시스템이야기2009. 2. 26. 09:30

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 사용기 일부 포함)



Posted by 좋은진호