VPS에서 ZFS 사용 시 RAM 점유율 최적화 가이드
ZFS는 데이터 무결성과 스냅샷 등 강력한 기능을 제공하지만 ARC 캐시로 인해 많은 RAM을 점유합니다. 2GB 또는 4GB 용량의 VPS 환경에서 ZFS를 안정적으로 운영하기 위한 메모리 설정 전략과 리소스 관리 방법을 상세히 설명합니다.
ZFS가 제공하는 것과 요구하는 것
FreeBSD와 Linux의 ZFS는 이제 OpenZFS라는 하나의 코드베이스로 통합되었으므로, 두 시스템 모두 동일한 기능을 제공합니다. ZFS를 실행하는 서버는 데이터 체크섬, 데이터가 변경되기 전까지 비용이 발생하지 않는 스냅샷, zfs send을 이용한 복제, 그리고 속성 설정 하나로 활성화되는 압축 기능을 얻게 됩니다. ZFS가 요구하는 것은 메모리입니다. ARC(Adaptive Replacement Cache)는 기본적으로 RAM의 상당 부분을 점유하는데, 2 GB 또는 4 GB 용량의 VPS(Virtual Private Server) 환경에서는 바로 그 메모리가 애플리케이션에 필요한 자원인 경우가 많습니다.
이 가이드는 40개의 드라이브 베이를 갖춘 스토리지 서버가 아닌, 1~2개의 가상 디스크를 사용하는 임대형 VPS 환경을 기준으로 ZFS를 평가합니다. 이러한 환경에서도 유용한 기능은 시간을 투자할 가치가 있습니다. 반면, VPS 환경에 적합하지 않은 부분은 풀(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데이터셋은 정책의 단위입니다
데이터셋은 풀 내부의 파일시스템이며, 생성 비용이 저렴하므로 작업 단위별로 하나씩 생성하십시오. 속성은 풀에서 하위로 상속되므로, 기본값을 한 번 설정한 뒤 필요한 곳에서만 재정의하면 됩니다.
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는 특정 데이터셋이 풀 전체를 채우지 못하도록 제한하는 방법입니다. 용량이 100%에 가까워진 ZFS 풀은 속도가 느려지고 정리하기 어려워지므로, 의도적으로 여유 공간을 남겨두어야 합니다.
스냅샷은 데이터가 변경되기 전까지 비용이 발생하지 않습니다
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는 차분(difference)을 적용할 기반이 없으므로 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.
이는 한 가지 조건을 제외하면 완벽한 오프사이트 백업 방식입니다. 객체 스토리지(object storage)는 스트림을 수신할 수 없으므로, 원격지는 반드시 ZFS 풀(pool)이어야 합니다. 대상이 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)에 빠질 수 있습니다. 스왑은 일반 파티션이나 풀 외부의 스왑 파일에 두어야 합니다.
ext4 또는 XFS와 restic이 더 나은 선택인 경우
ZFS는 여유 메모리와 두 번째 볼륨이 있는 서버에서 제값을 합니다. 그 외의 환경에서는 일반 파일 시스템과 실제 백업 도구를 사용하는 것이 유리합니다. 다음과 같은 상황에서는 ext4나 XFS를 선택하십시오.
- 인스턴스의 RAM이 2 GB 또는 4 GB이며, 워크로드가 이를 모두 필요로 하는 경우.
- 가상 디스크가 하나뿐이고 복제본이 없어, ZFS를 사용해도 복구 없이 탐지만 가능한 경우.
- 백업 대상이 오브젝트 스토리지나 일반 Linux 호스트여서
zfs send스트림을 수신할 수 없는 경우. - DKMS를 사용하는 Debian을 운영 중이며, 커널 업그레이드 시 모듈이 빌드되지 않는 상황을 감당할 수 없는 경우.
- 루트 파일 시스템에 ZFS가 필요하지만, 제공업체의 이미지에서 ext4만 지원하는 경우.
별도의 데이터 볼륨이 있고, 여유 RAM(8 GB 이상 권장)이 있으며, 단순히 스냅샷과 zfs send를 활성화하는 수준을 넘어 이를 활용할 계획이 있다면 ZFS를 유지하십시오. 그 외의 모든 경우에는 서버가 직접 제어하지 않는 스토리지에 암호화 및 중복 제거된 백업을 수행하는 ext4와 restic 조합이 메모리 부담 없이 동일한 효과를 제공합니다.
실패 유형 및 확인되는 메시지
재부팅 후 풀이 사라진 경우. 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 명령으로 설정을 고정합니다. 다른 시스템에서 정상적으로 내보내지 않은 풀은 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 스냅샷은 백업인가?
아닙니다. 스냅샷은 데이터와 동일한 풀(pool) 안에 존재합니다. 잘못된 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를 확인하십시오.