VPS에서 ZFS 사용 시 RAM 메모리 점유 문제 해결
ZFS의 ARC 캐시가 VPS의 제한된 RAM을 과도하게 점유하는 문제를 분석합니다. 2GB 또는 4GB 환경에서 ZFS를 안정적으로 운영하기 위한 메모리 제한 설정 방법과 데이터 무결성 및 성능 사이의 현실적인 타협점을 제시합니다.
ZFS가 제공하는 것과 감수해야 할 것
FreeBSD와 Linux의 ZFS는 이제 OpenZFS라는 하나의 코드베이스로 통합되어 두 시스템 모두 동일한 기능을 제공합니다. ZFS를 사용하는 서버는 데이터 체크섬, 데이터 변경 전까지 비용이 발생하지 않는 스냅샷, zfs send을 이용한 복제, 그리고 속성 설정 하나로 활성화되는 압축 기능을 얻게 됩니다. 반면 감수해야 할 것은 메모리 사용량입니다. ARC(Adaptive Replacement Cache)는 기본적으로 RAM의 상당 부분을 점유하는데, 2 GB 또는 4 GB 용량의 VPS(가상 사설 서버) 환경에서는 바로 그 메모리가 애플리케이션에 필요한 자원인 경우가 많습니다.
이 가이드는 40개의 드라이브 베이를 갖춘 스토리지 서버가 아닌, 1~2개의 가상 디스크를 사용하는 임대형 VPS 환경을 기준으로 ZFS를 평가합니다. 이 환경에서도 유용한 기능은 시간을 투자할 가치가 있습니다. 반대로 이 환경에 적합하지 않은 부분은 풀(pool)을 구성하기 전에 미리 알아두어야 합니다.
FreeBSD와 Linux에서의 OpenZFS: 하나의 코드베이스, 서로 다른 패키징 방식
FreeBSD는 2008년 FreeBSD 7.0부터 ZFS를 기본 시스템에 포함해 왔으며, 초기에는 실험적인 기능으로 제공되었습니다. 2020년 12월 OpenZFS 2.0 이후부터는 FreeBSD와 Linux 모두 동일한 소스 트리에서 빌드되므로, zfs와 zpool는 양쪽 환경에서 동일하게 동작하며 한쪽에서 생성한 풀(pool)을 다른 쪽에서 그대로 임포트할 수 있습니다.
ZFS가 Linux에서는 패키지 형태로, FreeBSD에서는 기본 시스템의 일부로 제공되는 이유는 라이선스 때문입니다. OpenZFS는 CDDL(Common Development and Distribution License)을 따릅니다. 반면 Linux 커널은 GPL(General Public License) 버전 2를 따릅니다. Linux 커널 프로젝트는 이 두 라이선스를 호환되지 않는 것으로 간주하므로, ZFS 코드는 Linux 메인라인에 병합되지 않으며 각 배포판이 이를 어떻게 제공할지 결정합니다. FreeBSD는 이러한 갈등이 없으므로 ZFS가 기본적으로 포함되어 있습니다. 이것이 실질적인 차이의 전부이며, 사용자가 어느 한쪽을 선택해야 할 문제는 아닙니다.
SSD Nodes는 FreeBSD 이미지를 제공하지 않으므로, 이곳에서 대여한 서버에서는 이 가이드의 Linux 관련 내용이 적용됩니다. 다른 곳에서 FreeBSD를 운영한다면, FreeBSD 서버는 별도의 모듈 빌드나 커널 업그레이드 과정 없이 바로 ZFS를 사용할 수 있습니다.
ZFS 설치 및 풀 생성
Ubuntu에서는 모듈이 커널 패키지에 포함되어 제공되므로 명령어 도구만 설치하면 됩니다.
sudo apt update
sudo apt install -y zfsutils-linux
zfs versionzfs version은 사용자 영역 버전과 커널 모듈 버전, 두 줄을 출력합니다. 한 줄만 출력된다면 모듈이 로드되지 않은 것입니다. 해당 패키지는 universe 구성 요소에 포함되어 있으며, Ubuntu 서버 이미지에는 기본적으로 활성화되어 있습니다. 만약 apt에서 패키지를 찾을 수 없다면 먼저 sudo add-apt-repository universe을 실행하십시오.
Debian의 경우 패키지는 contrib 구성 요소에 있으며, 모듈은 DKMS(dynamic kernel module support)를 통해 시스템에서 직접 빌드됩니다. /etc/apt/sources.list.d/debian.sources 파일의 Components: 줄에 contrib를 추가하고 sudo apt update을 실행한 뒤 다음을 수행하십시오.
sudo apt install -y linux-headers-$(dpkg --print-architecture) zfs-dkms zfsutils-linux설치 과정에서 모듈이 컴파일되며 Building initial module for 6.12.0-...가 출력되는데, 이 작업은 몇 분 정도 소요됩니다. 커널이 업그레이드될 때마다 모듈을 다시 빌드해야 한다는 점을 기억하십시오. 빌드에 실패하면 문제를 해결하기 전까지 풀을 임포트할 수 없습니다.
FreeBSD에서는 별도의 설치 과정이 없습니다. 서비스를 활성화하고 시작하십시오.
sysrc zfs_enable=YES
service zfs start이제 풀을 생성합니다. /dev/vdb은 감지 순서에 따라 할당되며 다른 볼륨을 연결할 때 변경될 수 있으므로, 먼저 안정적인 장치 경로를 확인하십시오.
ls -l /dev/disk/by-id/
sudo zpool create -o ashift=12 tank /dev/disk/by-id/virtio-abc123def456
zpool status tankzpool status을 실행하면 tank 아래에 장치 목록이 포함된 state: ONLINE가 출력되어야 합니다. ashift=12는 풀의 최소 블록 크기를 4 KiB로 고정하며, 이는 최신 SSD와 일치합니다. 이 설정은 생성 후 변경할 수 없습니다.
대부분의 임대 서버 이미지는 ext4 루트로 부팅되므로, 여기서 다루는 ZFS는 루트 파일시스템이 아닌 두 번째 볼륨의 데이터 풀입니다. 빌드를 시작하기 전에 장치가 의도한 것이 맞는지 확인하십시오. 구매한 NVMe 디스크를 확인하는 작업은 1분이면 끝나지만, 잘못 빌드하여 다시 구성하는 데는 반나절이 걸릴 수 있습니다.
체크섬은 풀에 중복성이 있을 때만 복구할 수 있습니다
ZFS가 기록하는 모든 블록에는 체크섬이 포함되며, 읽을 때마다 이를 검증합니다. 오류 탐지는 항상 작동하지만, 복구에는 두 번째 복사본이 필요합니다.
단일 디스크 풀에서 ZFS는 오류를 감지하여 사실을 알리고 작업을 중단합니다. zpool status -v는 다음과 같이 보고합니다.
status: One or more devices has experienced an error resulting in data
corruption.
action: Restore the file in question if possible. Otherwise restore the
entire pool from backup.
errors: Permanent errors have been detected in the following files:
/tank/data/archive.tar손상된 파일의 이름이 표시됩니다. ext4라면 오류를 알리지 않고 손상된 바이트를 그대로 반환했을 것이므로, 이 기능만으로도 가치가 있습니다. 하지만 ZFS는 풀 내에 복구할 두 번째 복사본이 없으므로 이를 직접 수정할 수는 없습니다.
미러 구성에서는 동일한 읽기 요청이 정상적인 측에서 처리되고, 손상된 블록은 다시 기록되며, 해당 이벤트가 zpool status의 CKSUM 열에 나타납니다. 이것이 자가 치유(self-healing)이며, 이를 위해서는 두 개의 장치가 필요합니다.
sudo zpool create -o ashift=12 tank mirror /dev/disk/by-id/DISK1 /dev/disk/by-id/DISK2VPS 환경에서 호스트 스토리지는 보통 이미 중복 구성되어 있으며, 흔히 하이퍼바이저 하단의 RAID 10을 사용합니다. 이는 드라이브 장애로부터 데이터를 보호합니다. 하지만 배열은 어떤 복사본이 올바른지 알 수 없으므로, 블록이 잘못된 상태로 반환되어도 이를 알려주지 못합니다. ZFS는 직접 기록한 체크섬과 데이터를 비교하므로 오류를 정확히 파악합니다.
가상 디스크가 하나뿐이지만 복구 능력을 원한다면, sudo zfs set copies=2 tank/important을 사용하여 해당 데이터셋의 모든 블록을 동일한 디스크에 두 번 저장할 수 있습니다. 이 설정은 데이터셋이 사용하는 공간을 두 배로 늘리며, 블록 손상 시에는 데이터를 보호하지만, 볼륨 전체가 사라지는 장애에는 대응할 수 없습니다.
스크럽(scrub)은 풀의 모든 데이터를 읽고 검증합니다.
sudo zpool scrub tank
zpool status tank정상적인 풀은 scan: scrub repaired 0B in 00:04:11 with 0 errors과 같은 줄로 끝납니다. 스크럽을 일정에 따라 실행하십시오. 소규모 풀이라면 월 1회 실행으로 충분합니다.
systemctl list-unit-files 'zfs-scrub*'
sudo systemctl enable --now zfs-scrub-monthly@tank.timer데이터셋은 정책의 단위입니다
데이터셋은 풀 내부의 파일 시스템이며, 생성 비용이 저렴하므로 작업 단위별로 하나씩 생성하십시오. 속성은 풀에서 하위로 상속되므로 기본값을 한 번 설정한 뒤 필요한 곳에서 재정의하면 됩니다. FreeBSD에서는 보통 이런 방식으로 jail을 운영합니다. jail마다 데이터셋을 하나씩 할당하면 개별 jail 단위로 스냅샷을 생성하고 롤백할 수 있는데, 이것이 바로 jail과 Docker 컨테이너를 구분 짓는 요소 중 하나입니다.
sudo zfs create tank/data
sudo zfs create tank/pg
sudo zfs set compression=lz4 tank
sudo zfs set atime=off tank
sudo zfs set quota=20G tank/data
sudo zfs set recordsize=16K tank/pg
zfs get -r compression,compressratio,quota tank압축은 사용자가 주의를 기울이다가 설정하지 않는 속성이지만, 이는 잘못된 방식입니다. lz4는 적은 양의 CPU를 사용하면서 디스크에 도달해야 하는 데이터 양을 줄여주므로, 압축 가능한 데이터라면 일반적으로 읽기와 쓰기 속도가 더 빨라집니다. zstd은 더 많은 CPU를 사용하여 더 강력하게 압축하므로, 자주 읽지 않는 로그나 아카이브에 적합합니다. zfs get compressratio tank을 사용하여 실제 압축률을 확인하십시오. 단, 압축률은 해당 속성을 설정한 이후에 기록된 데이터에 대해서만 계산된다는 점을 기억해야 합니다.
recordsize는 데이터셋이 기록하는 가장 큰 블록 크기이며, 기본값은 128K입니다. 8 KiB 페이지를 128 KiB 레코드에 기록하는 데이터베이스의 경우, 작은 쓰기 작업 한 번이 전체 레코드를 읽고, 내용을 변경한 뒤, 다시 기록하는 과정으로 변질됩니다. 데이터 로드 전에 데이터베이스 데이터셋의 recordsize=16K을 설정하십시오. 이 속성은 새로 기록되는 블록에만 적용되기 때문입니다.
quota는 특정 데이터셋이 풀을 가득 채우지 못하도록 제한하는 방법입니다. ZFS 풀이 100%에 가까워지면 속도가 느려지고 정리하기 어려워지므로, 의도적으로 여유 공간을 남겨두어야 합니다.
데이터가 변경되기 전까지 스냅샷은 비용이 발생하지 않습니다
ZFS는 라이브 블록을 덮어쓰지 않습니다. 새로운 블록을 기록하고 포인터를 업데이트하는 방식을 사용하며, 이것이 바로 copy-on-write의 의미입니다. 스냅샷은 "현재 이 데이터셋이 가리키고 있는 블록들을 유지하라"는 기록이므로, 생성 즉시 완료되며 추가 공간을 차지하지 않습니다.
sudo zfs snapshot tank/data@2026-08-11
zfs list -t snapshot -o name,used,refer -r tank/data스냅샷의 USED 열은 해당 스냅샷만이 독점적으로 점유하고 있는 공간을 의미합니다. 데이터가 변경되거나 삭제되면 이전 블록을 해제할 수 없게 되므로, 처음에는 0에 가깝던 이 수치가 점차 증가합니다.
파일을 복구하기 위해 별도의 복원 절차를 거칠 필요는 없습니다.
ls /tank/data/.zfs/snapshot/
cp /tank/data/.zfs/snapshot/2026-08-11/notes.txt /tank/data/notes.txt.zfs 디렉터리는 sudo zfs set snapdir=visible tank/data을 실행하기 전까지는 ls -a에서도 보이지 않습니다. 스냅샷이 없으면 실수로 rm -rf을 실행했을 때 ext4 복구 경로로 빠지게 되며, 이는 디스크 언마운트부터 시작하여 상황이 훨씬 복잡해지므로 필요한 시점이 오기 전에 미리 스냅샷을 생성하십시오.
롤백을 수행하면 스냅샷 이후에 기록된 모든 데이터가 삭제됩니다.
sudo zfs rollback tank/data@2026-08-11더 최신 스냅샷이 존재하면 롤백이 거부되며, -r를 사용하면 해당 최신 스냅샷들을 삭제하고 진행할 수 있습니다. 엔터 키를 누르기 전에 데이터셋 이름을 두 번 확인하십시오.
스냅샷은 백업이 아닙니다. 스냅샷은 동일한 풀, 동일한 볼륨, 동일한 서버 내에 존재합니다. 볼륨에 장애가 발생하거나 zpool destroy이 발생하면 데이터와 함께 스냅샷도 사라집니다. 스냅샷은 사용자의 rm이나 잘못된 업그레이드로부터 보호해주며, 이는 실제 발생하는 많은 사고를 방어할 수 있게 해주지만, 풀 자체에 발생하는 문제로부터는 아무것도 보호하지 못합니다. 전체적인 근거는 여기에서 확인할 수 있습니다: VPS 스냅샷이 백업이 아닌 이유.
전송 및 수신: 단일 명령어로 수행하는 복제
zfs send는 스냅샷을 표준 출력으로 바이트 스트림 변환하며, zfs receive은 해당 스트림을 다시 데이터셋으로 복원합니다. 첫 번째 복제는 전체 전송(full send) 방식으로 수행됩니다.
sudo zfs snapshot tank/data@daily-2026-08-11
sudo zfs send tank/data@daily-2026-08-11 | ssh backup.example.com "sudo zfs recv -F backup/data"그 이후에는 두 스냅샷 사이의 변경 사항만 전송합니다.
sudo zfs snapshot tank/data@daily-2026-08-12
sudo zfs send -i tank/data@daily-2026-08-11 tank/data@daily-2026-08-12 | ssh backup.example.com "sudo zfs recv backup/data"수신 측은 반드시 전송의 기준이 되는 스냅샷을 보유하고 있어야 합니다. 해당 스냅샷이 없으면 ZFS는 차분 데이터를 적용할 기반이 없으므로 cannot receive incremental stream: most recent snapshot of backup/data does not match incremental source 오류와 함께 수신이 중단됩니다. 양측 모두가 보유한 스냅샷을 기준으로 전송하거나, 전체 전송을 다시 시작하십시오.
원격 root 계정을 사용하는 대신 대상 서버에 권한을 부여하십시오: sudo zfs allow -u backupuser create,mount,receive backup/data.
이는 한 가지 조건을 충족할 경우 실질적인 오프사이트 백업이 됩니다. 객체 스토리지는 스트림을 수신할 수 없으므로, 원격지는 반드시 ZFS 풀이어야 합니다. 대상이 S3 호환 스토리지이거나 일반 Linux 호스트인 경우에는 해당 환경을 지원하는 도구를 사용해야 하며, VPS에서 restic 백업하기 문서에서 관련 경로를 다룹니다.
ZFS는 왜 그렇게 많은 RAM을 사용합니까? ARC에 대하여
ARC(adaptive replacement cache)는 ZFS의 읽기 캐시입니다. 이 캐시는 일반적인 Linux 페이지 캐시가 아닌 커널 메모리에 상주하므로, free -h은 이를 buff/cache 항목으로 보고하지 않습니다. 대신 사용 중인 메모리로 표시됩니다. ZFS 서버의 메모리가 거의 가득 찬 것처럼 보인다면, 이는 보통 캐시가 활성화된 상태이며 이것이 "ZFS가 내 RAM을 다 먹었다"는 보고의 대부분을 차지합니다.
기본 제한값은 의도적으로 넉넉하게 설정되어 있습니다. OpenZFS 2.3은 최대 ARC 크기를 RAM에서 1 GiB를 뺀 값과 RAM의 5/8 중 더 큰 값으로 설정합니다. OpenZFS 2.2 이하 버전은 Linux에서 RAM의 절반을 사용했으나, FreeBSD는 이미 새로운 규칙을 적용하고 있었습니다. 본인의 시스템에 어떤 규칙이 적용되는지 확인하려면 zfs version을 실행하십시오.
The data behind this chart
[
{
"label": "2 GB VPS",
"openzfs_2_2_linux_gib": 1,
"openzfs_2_3_gib": 1.25
},
{
"label": "4 GB VPS",
"openzfs_2_2_linux_gib": 2,
"openzfs_2_3_gib": 3
},
{
"label": "8 GB VPS",
"openzfs_2_2_linux_gib": 4,
"openzfs_2_3_gib": 7
},
{
"label": "16 GB VPS",
"openzfs_2_2_linux_gib": 8,
"openzfs_2_3_gib": 15
}
]위 수치는 일반적인 인스턴스 크기에 적용되는 문서화된 기본 규칙이며, 실행 중인 서버에서 측정한 값이 아닙니다. 4 GB 인스턴스에서 2.3 규칙은 3 GiB의 ARC를 허용합니다. 동일한 서버를 2.2 버전에서 실행하면 2 GiB에서 제한됩니다. 2 GB 인스턴스라도 2.3 규칙 하에서는 1.25 GiB를 허용합니다. 애플리케이션은 남은 메모리를 사용하게 됩니다.
표를 신뢰하기보다 서버에서 실제 수치를 확인하십시오:
grep -E '^(size|c_max) ' /proc/spl/kstat/zfs/arcstats
arc_summary | head -n 20세 번째 열은 바이트 단위입니다. c_max은 현재 적용 중인 상한선이며, size는 현재 ARC가 점유하고 있는 크기입니다.
ARC는 메모리를 반환합니다. 커널이 메모리 압박을 알리면 ARC는 크기를 줄입니다. 문제는 타이밍입니다. 축소 작업은 메모리 압박에 의해 유발되므로, 한 번에 수백 MiB를 요청하는 프로세스는 ARC가 메모리를 해제하기도 전에 OOM(out of memory) 킬러를 만날 수 있습니다. 데이터베이스와 웹 서버를 실행하는 2 GB 서버에서는 드문 일이 아닙니다. OpenZFS 매뉴얼에서도 수동 설정 변경에 대해 동일하게 언급합니다. 제한값을 낮추더라도 "메모리 압박이 유발되지 않으면 ARC는 즉시 줄어들지 않습니다".
소규모 VPS에서 ARC 제한 설정하기
먼저 워크로드의 메모리 사용량을 결정하십시오. 데이터베이스와 애플리케이션이 필요로 하는 메모리를 합산하고 운영체제를 위한 여유 공간을 확보한 뒤, 나머지를 ARC에 할당합니다. Postgres와 웹 애플리케이션 하나를 실행하는 4 GB 인스턴스라면 512 MiB에서 1 GiB 정도의 ARC를 시작점으로 잡는 것이 합리적입니다.
실시간으로 값을 설정합니다. 아래는 1 GiB로 설정하는 예시입니다.
echo 1073741824 | sudo tee /sys/module/zfs/parameters/zfs_arc_max재부팅 후에도 설정이 유지되도록 합니다.
echo 'options zfs zfs_arc_max=1073741824' | sudo tee /etc/modprobe.d/zfs.conf
sudo update-initramfs -uinitramfs 단계가 중요한 이유는 루트 파일시스템이 마운트되기 전에 모듈이 initramfs에서 먼저 로드될 수 있기 때문입니다. 이 경우 방금 작성한 파일을 읽지 못하게 됩니다. 재부팅 후 c_max 라인을 통해 arcstats에서 확인하십시오.
매뉴얼에서 언급하는 두 가지 주의 사항이 있습니다. 시스템이 실행 중일 때는 값을 다시 0으로 되돌릴 수 없으므로, 설정을 취소하려면 파일을 수정하고 재부팅해야 합니다. 또한 숫자를 낮춘다고 해서 이미 커진 ARC가 즉시 줄어들지는 않습니다.
FreeBSD에서는 동일한 제한을 vfs.zfs.arc 아래의 sysctl로 설정합니다. sysctl vfs.zfs.arc를 실행하여 현재 값과 사용 중인 버전의 정확한 이름을 확인한 다음, 최댓값을 /boot/loader.conf에 기록하십시오.
소규모 서버를 위한 두 가지 메모리 규칙이 더 있습니다. 중복 제거(deduplication) 기능은 끄십시오. 중복 제거 테이블은 메모리에 상주하며, 일반적으로 고유 데이터 1 TB당 1~3 GB의 RAM이 필요하다는 것이 정설입니다. 또한 zvol(풀에서 분할한 블록 장치)에 스왑을 두지 마십시오. 메모리를 확보하려는 파일시스템을 통해 스왑을 수행하면 시스템이 교착 상태(deadlock)에 빠질 수 있습니다. 스왑은 풀 외부의 일반 파티션이나 스왑 파일에 두십시오.
When ext4 or XFS plus restic is the better answer
ZFS earns its keep on a server with spare memory and a second volume. Outside that, a plain filesystem plus a real backup tool wins. Choose ext4 or XFS when:
- The instance has 2 GB or 4 GB of RAM and the workload wants all of it.
- There is one virtual disk and no second copy, so ZFS gives you detection without repair.
- Your backup target is object storage or a plain Linux host, so nothing there can receive a
zfs sendstream. - You run Debian with DKMS and cannot afford a kernel upgrade that leaves the module unbuilt.
- You need ZFS on the root filesystem and the provider's images only offer ext4.
Keep ZFS when you have a separate data volume, RAM to spare (8 GB and up is comfortable), and a plan that uses snapshots and zfs send rather than just enabling them. For everything else, ext4 with restic writing encrypted, deduplicated backups to storage the server does not control covers most of the same ground for none of the memory.
실패 유형 및 확인되는 메시지
재부팅 후 풀이 사라진 경우. zpool status 명령은 no pools available 메시지를 출력합니다. 임포트 서비스는 /etc/zfs/zpool.cache 파일을 읽으므로, 해당 파일에 없는 풀은 부팅 시 자동으로 임포트되지 않습니다. sudo zpool import 명령으로 임포트 가능한 풀을 확인하고, sudo zpool import tank 명령으로 다시 불러온 뒤, sudo zpool set cachefile=/etc/zfs/zpool.cache tank 명령으로 설정을 고정합니다. 다른 시스템에서 정상적으로 export되지 않은 풀은 cannot import 'tank': pool may be in use from other system 오류를 보고하며, 다른 호스트에서 사용 중이 아님이 확실할 때 sudo zpool import -f tank 명령으로 이를 강제할 수 있습니다.
Debian에서 커널 업그레이드 후 modprobe: FATAL: Module zfs not found in directory /lib/modules/6.12.0-... 오류. DKMS가 새 커널용으로 빌드되지 않은 경우이며, 보통 일치하는 헤더가 설치되지 않았을 때 발생합니다. dkms status 명령으로 커널별 빌드 상태를 확인합니다. 이후 sudo apt install -y linux-headers-$(uname -r) 및 sudo dkms autoinstall 명령으로 재빌드하고, sudo zpool import tank 명령으로 풀을 다시 불러옵니다.
풀이 가득 찼으나 파일을 삭제한 경우. 스냅샷이 데이터를 참조하고 있으면 삭제된 데이터도 디스크에 남아 있으므로, du와 df의 결과가 일치하지 않게 됩니다. zfs list -o space -r tank 명령은 사용량을 USEDDS와 USEDSNAP으로 나누어 보여주며, USEDSNAP 값이 크다면 이것이 원인입니다. sudo zfs destroy tank/data@2026-06-01 명령으로 오래된 스냅샷을 삭제하면 공간이 확보됩니다.
zpool status에서 CKSUM 수치가 증가하는 경우. ZFS 하위 계층에서 잘못된 데이터가 반환된 것입니다. 미러 구성에서는 해당 수치가 경고를 의미하며 블록은 이미 복구된 상태입니다. 단일 디스크 풀에서는 파일이 손실된 것이며, zpool status -v 명령으로 해당 파일명을 확인한 뒤 이 풀에 저장되지 않은 백업본에서 파일을 복구해야 합니다.
서버가 느려지고 스와핑이 발생하는 경우. 앞서 설명한 대로 ARC 크기를 제한한 뒤, arc_summary 명령을 실행하여 적중률(hit ratio)을 확인합니다. 작업 세트를 유지하기에 ARC가 너무 작으면 모든 읽기 요청이 디스크로 전달됩니다. 이 시점부터는 페이지 캐시를 사용하는 일반 파일 시스템이 더 나은 성능을 제공할 수 있습니다.
FAQ
VPS에서 ZFS를 운영하려면 RAM이 얼마나 필요한가?
ZFS는 2 GB 인스턴스에서도 동작합니다. 중요한 것은 애플리케이션이 사용할 수 있는 가용 메모리입니다. 별도의 튜닝을 하지 않으면 OpenZFS 2.3은 ARC 크기를 RAM에서 1 GiB를 뺀 값과 RAM의 5/8 중 큰 값으로 설정합니다. 따라서 4 GB 서버라면 3 GiB를 캐시로 할당할 수 있습니다. zfs_arc_max을 워크로드에 지장을 주지 않는 수치로 설정한 뒤, /proc/spl/kstat/zfs/arcstats에서 c_max 라인을 읽어 설정을 확인하십시오.
ZFS 스냅샷은 백업인가?
아닙니다. 스냅샷은 데이터와 동일한 풀에 존재합니다. 잘못된 rm나 업그레이드 실패로부터는 데이터를 보호할 수 있지만, 풀이나 인스턴스 자체가 손실되면 스냅샷도 함께 사라집니다. zfs send을 사용하여 다른 장비로 스냅샷을 전송하거나, 이 서버가 제어하지 않는 외부 저장소에 기록하는 백업 도구를 사용해야 진정한 백업이 됩니다.
ZFS는 FreeBSD와 Linux에서 동일하게 동작하는가?
2020년 12월 OpenZFS 2.0 이후 동일한 코드베이스를 공유하며, 명령어와 디스크 포맷이 같아 풀을 양쪽 운영체제 간에 이동할 수 있습니다. 차이점은 패키징 방식입니다. FreeBSD는 ZFS를 기본 시스템에 포함하여 제공합니다. 반면 Linux 배포판은 각기 다른 방식을 취합니다. Ubuntu는 커널 패키지에 모듈을 포함하여 빌드하지만, Debian은 DKMS를 사용하여 사용자 시스템에서 직접 빌드하므로 커널 업그레이드 시 재빌드가 성공할 때까지 모듈을 사용할 수 없는 상황이 발생할 수 있습니다.
단일 디스크 VPS에서 ZFS가 손상을 복구할 수 있는가?
ZFS는 손상을 감지하고 해당 파일명을 알려주지만, 복구에는 블록의 두 번째 복사본이 필요하므로 스스로 복구할 수는 없습니다. 데이터셋에 zfs set copies=2을 설정하면 공간을 두 배로 사용하여 두 번째 복사본을 생성할 수 있으며, 이는 배드 블록 문제를 해결할 수 있으나 볼륨 손실에는 대응하지 못합니다. 두 개의 볼륨으로 미러링을 구성하는 것이 실질적인 복구 방법입니다.
압축을 사용하면 서버 속도가 느려지는가?
lz4를 사용하면 일반적으로 속도가 더 빨라집니다. 블록을 압축하면 읽고 쓰는 바이트 수가 줄어들며, 블록당 CPU 연산 비용은 디스크 I/O를 절약하는 이점에 비해 매우 작습니다. 풀 루트에 compression=lz4을 설정하여 모든 데이터셋이 이를 상속받게 하고, 실제 데이터가 기록된 후 zfs get compressratio tank를 확인하십시오.