FreeBSD 7.0부터는 오픈솔라리스의 ZFS(Zettabyte File System)을 사용할 수 있다. ZFS는 파일시스템과 볼륨관리자가 통합되어 있는 장점을 최대한 살려 한두개의 과정만으로 파일시스템을 바로 사용할 수 있다. 또한 마치 찰흙을 붙였다 떼었다 하는 듯한 느낌으로 볼륨 관리의 유연성을 맛 볼 수 있다. 그러나 FreeBSD에서는 아직 실험적으로 동작중이며, IO 성능 또한 만족스럽지 못하다. 결국 FreeBSD에서 만큼은 미래를 위해 맛보기용 파일시스템로 즐기면 될 듯 싶다.
간단한 ZFS의 특징을 정리하면.
- 파일시스템 + 볼륨관리자가 통합되었다.
- 128비트 파일시스템이며, 디렉토리와 파일의 갯수에 제한이 없다.
- 미러링, 그리고 RAID기능에 해당하는 raidz를 지원한다.
- 물리적 disk를 쉽게 스토리지 풀에 추가할 수 있다.
- 상태 모니터링이 효과적이다. (iostat, status, history, get 등)
- 스냅샷 기능을 지원한다.
1. ZFS 풀과 파일시스템 생성 (zpool create, zfs create, zpool list, zfs list)
# zpool create data mfid0s1h
# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
data 31.8G 110K 31.7G 0% ONLINE -
# df -t zfs
Filesystem 1K-blocks Used Avail Capacity Mounted on
data 32771968 0 32771968 0% /data
zpool create 명령만으로 쉽게 '스토리지 풀'을 생성했다. 이 명령 하나만으로 바로 파일시스템을 이용할 수가 있다. 매우 간단하지 않는가?
리눅스의 LVM과 비교해보자. LVM은 PV 생성 -> VG 생성 -> LV 생성의 3과정을 거쳐야 한다. 1) 디스크나 파티션을 LVM으로 사용하겠다고 선언하는 PV(Physical Volume) 생성(pvcreate) 과정. 2) 이후 PV를 하나의 큰 덩어리로 묶는 VG(Volume Group) 생성(vgcreate) 과정. 3) 필요한 만큼만 떼어 내어 실제 사용가능한 파일시스템으로 만드는 LV(Logical Volume) 생성 과정. 이와 비교하면 zfs는 정말 간단하다.
이제 하나의 풀에 여러 파일시스템을 만들어보자.
# zfs create data/backup
# zfs create data/log
# zfs create data/photo
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
data 182K 31.3G 22K /data
data/backup 18K 31.3G 18K /data/backup
data/log 18K 31.3G 18K /data/log
data/photo 18K 31.3G 18K /data/photo
data 풀에 data/backup, data/log, data/photo 파일시스템을 생성했다. 그런데 마운트포인트가 모두 /data 아래로 생성되었는데, 다른 곳으로 할 수는 없을까? zfs set 명령 하나면 바로 변경 가능하다. 또는 생성할 때 -o mountmpoint=/backup 옵션으로 지정할 수 있다.
(※ zfs get all 또는 zfs get mountpoint로 속성 정보를 얻을 수 있다.)
# zfs set mountpoint=/backup data/backup
# zfs list /backup
NAME USED AVAIL REFER MOUNTPOINT
data/backup 18K 31.3G 18K /backup
# df -h -t zfs
Filesystem 1K-blocks Used Avail Capacity Mounted on
data 31G 0B 31G 0% /data
data/log 31G 0B 31G 0% /data/log
data/photo 31G 0B 31G 0% /data/photo
data/backup 31G 0B 31G 0% /backup
위의 파티션을 보면 용량이 모두 31GB로 표시되었다. zfs의 각 파티션이 '스토리지 풀'의 최대 용량까지 함께 사용하기 때문이다. data/photo 파티션은 5G만 사용하라고 쿼터를 할당해보자. 이 쿼터는 허용치만큼 늘릴 수도 줄일 수도 있다. 리눅스의 LVM이 확장하는 것만 가능(lvextend)한 것과 비교하면 상당히 유연한 자세를 취하고 있다.
# zfs set quota=5g data/photo
# zfs list data/photo
NAME USED AVAIL REFER MOUNTPOINT
data/photo 18K 5.00G 18K /data/photo
#
# zfs set quota=3g data/photo
# zfs list data/photo
NAME USED AVAIL REFER MOUNTPOINT
data/photo 18K 3.00G 18K /data/photo
#
# df -h data/photo
Filesystem Size Used Avail Capacity Mounted on
data/photo 3.0G 128K 3.0G 0% /data/photo
만약 다른 파티션에서 용량을 사용하게 되면 그 양만큼 다른 파티션은 사용할 공간이 줄게 된다. 아래를 보면 /data/log가 11G를 사용중이다. 그래서 다른 파티션은 31GB-11GB 뺀 용량이 전체 사이즈로 표현된다.
# df -h -t zfs
Filesystem Size Used Avail Capacity Mounted on
data 20G 0B 20G 0% /data
data/log 31G 11G 20G 35% /data/log
data/photo 3.0G 128K 3.0G 0% /data/photo
data/backup 20G 0B 20G 0% /backup
ZFS는 자체에 데이터 안정성을 높을 높이는 mirror와 RAID-Z 기능을 제공한다. mirror기능으로 풀을 만들어 보자.
# zpool create backup mirror mfid1 mfid3
# df -h -t zfs
Filesystem Size Used Avail Capacity Mounted on
backup 66G 0B 66G 0% /backup
디스크는 SAS 73GB짜리이다. ufs 또는 zfs로 1개의 파일시스템을 만들면 66GB가 나온다. 2개 디스크인데, 132GB가 아닌 66GB로 표시되는 것은 mirror로 생성되었음을 보여준다. mirror로 설정되어 있는지 확인하는 방법은 뒤에서 다시 얘기하겠다.
2. zfs는 당신이 한 일을 모두 알고 있다. (zfs history)
# zpool history
History for 'data':
2009-02-16.18:32:06 zpool create data mfid0s1h
2009-02-16.18:33:23 zfs create data/backup
2009-02-16.18:33:31 zfs create data/log
2009-02-16.18:33:50 zfs create data/photo
2009-02-16.18:35:19 zfs set mountpoint=/backup data/backup
2009-02-16.18:41:17 zfs create -o mountpoint=/work data/work
2009-02-16.18:51:07 zfs set quota=5g data/photo
2009-02-16.19:00:09 zfs set quota=3g data/photo
2009-02-16.19:16:41 zfs set quota=5g data/photo
2009-02-16.19:21:36 zfs set quota=3g data/photo
2009-02-16.19:28:49 zfs destroy data/work
'data' 풀에 적용된 작업이 모두 나왔다.
3. 상태 살펴보기 (zpool iostat, zpool status)
# zpool iostat 2
capacity operations bandwidth
pool used avail read write read write
---------- ----- ----- ----- ----- ----- -----
data 11.4G 20.4G 8 63 881K 1.58M
data 11.6G 20.1G 0 1.75K 32.0K 128M
data 11.9G 19.9G 0 1.88K 64.0K 133M
data 12.1G 19.7G 0 2.09K 32.0K 128M
data 12.3G 19.4G 0 2.17K 64.0K 131M
data 12.6G 19.2G 0 2.20K 32.0K 137M
data 12.8G 18.9G 0 2.33K 32.0K 139M
data 12.9G 18.9G 610 1.49K 75.8M 77.8M
data 12.9G 18.9G 521 1.61K 65.0M 89.7M
data 12.9G 18.9G 615 1.35K 76.5M 71.2M
IO 상태를 2초간격으로 살펴본 것이다. 리눅스나 FreeBSD에서 iostat를 해봤을 것이다. iostat는 디스크별로 IO를 보는 것이며, zpool iostat는 '스토리지 풀'별로 살펴보는 것이다. 'data' 풀의 ONLINE상태를 확인할 수 있다.
# zpool status
pool: data
state: ONLINE
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
data ONLINE 0 0 0
mfid0s1h ONLINE 0 0 0
다음은 'backup'풀이 mfid1, mfid3 2개 disk를 사용하여 mirror되어 있는 것을 볼 수 있다.
# zpool status
pool: backup
state: ONLINE
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
backup ONLINE 0 0 0
mirror ONLINE 0 0 0
mfid1 ONLINE 0 0 0
mfid3 ONLINE 0 0 0
errors: No known data errors
4. ZFS 풀과 파일시스템 unmount & 지우기 (zpool destroy, zfs umount, zfs destroy)
파일시스템를 umount하기 위해서는 'zfs umount 파일시스템' 형태로 하며, 완전 제거는 'zfs destroy'로 한다. 파일시스템이 사용중이지 않으면 바로 unmount와 제거가 가능하다.
# cd /data/log
# zfs umount data/log
cannot unmount '/data/log': Device busy
# cd /
# zfs umount data/log
# zfs mount data/log
# zfs destroy data/log
스토리지 풀 전체를 제거할 때도 마찬가지로 zpool destroy로 하면 된다.
# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
data 31.8G 10.9G 20.9G 34% ONLINE -
# zpool destroy data
cannot unmount '/backup': Device busy
could not destroy 'data': could not unmount datasets
# cd /
# zpool destroy data
# zpool list
no pools available
5. FreeBSD에서는 ZFS를 서비스에 적용할 수 있을까? (성능 및 기타 사항)
ZFS는 최소 1GB이상의 메모리를 권장한다. 그러나 ZFS는 실제 많은 메모리를 사용하는 경우가 있다. 파일시스템 성능 체크를 하는 동안 panic: kmem_malloc(16305): kmem_map too small: 332353536 total allocated 같은 메시지를 뿌리면서 몇 번 다운되었다. i386 환경에서는 kmem address space(vm.kmem_size_max)의 최대값이 320M으로 되어 있다. 그러나 이 수치는 ZFS을 사용하기에는 낮은 수치이므로 기본값을 그대로 사용할 경우에는 커널 패닉이 발생할 수 있다고 한다. 그래서 나도 다운이 된 것이었다. vm.kmem_size는 read only값이므로 /boot/loader.conf 에 다음 2줄을 추가한다. 그리고 부팅을 하고, 필요시 이 수치는 더 늘리면 된다.
vm.kmem_size="512M"
vm.kmem_size_max="512M"
[ 부팅 전 ]
# sysctl -a|grep kmem
vm.kmem_size_scale: 3
vm.kmem_size_max: 335544320
vm.kmem_size_min: 0
vm.kmem_size: 335544320
[ 부팅 후 ]
# sysctl -a|grep kmem
vm.kmem_size_scale: 3
vm.kmem_size_max: 536870912
vm.kmem_size_min: 0
vm.kmem_size: 536870912
bonnie++로 Sequential Output/Input/Create, Random, Random Create의 성능 비교를 했다. ufs 파일시스템과 비교했을 때 각 항목별로 대략 2~5배 이하의 만족스럽지 못한 성능이 나왔다. zfs 기본 생성외에 mirror로 이뤄진 풀, raidz 로 이뤄진 풀도 낮은 수치인 것은 마찬가지였다.
그리고, 부팅 후 ZFS를 처음 create할 때는 다음과 같은 메시지가 나온다.
This module (opensolaris) contains code covered by the
Common Development and Distribution License (CDDL)
see http://opensolaris.org/os/licensing/opensolaris_license/
WARNING: ZFS is considered to be an experimental feature in FreeBSD.
ZFS filesystem version 6
ZFS storage pool version 6
'WARNING' 부분이 보이는가? FreeBSD에서는 실험적인 상태이고, 성능 또한 상당히 낮으니, 편리함과 유연함을 높이 산다고 하더라고 서비스에 적용하기는 무리가 있다. 아직 FreeBSD에서는 재밌게 즐기면 된다. 즐기다 보면 미래에 적용해도 괜찮을 때가 오겠지...
6. 참고 자료
* ZFS 시작하기
* ZFS Tuning Guide
* FreeBSD 7.1 달라진 것 몇가지 (2009.1.20, 글 좋은진호)
* FreeBSD 7.0 사용기 (2008.3.7, 글 좋은진호, ZFS 사용기 일부 포함)