2012年11月24日土曜日

ZVOL を KVM ゲストに割り当てる

CentOS 6 + ZFS on Linux 0.6.0-rc12 において、ZVOL を KVM ゲストに割り当てる実験をしてみました。

目当ては、スパースボリューム (sparse volume) です。次は、man zfs(8) からの抜粋です。
           Though not recommended, a "sparse volume" (also known as "thin pro-
           visioning") can be created by specifying the -s option to  the  zfs
           create  -V command, or by changing the reservation after the volume
           has been created. A "sparse volume" is a volume where the  reserva-
           tion is less then the volume size. Consequently, writes to a sparse
           volume can fail with ENOSPC when the pool is low on  space.  For  a
           sparse volume, changes to volsize are not reflected in the reserva-
           tion.
スパースボリュームを作成するには、zfs create -V の際、同時に -s オプションを指定します。
# zfs create -s -V 30G tank1/zvol
# ls -l /dev/zvol/tank1/zvol 
lrwxrwxrwx 1 root root 9 Nov 24 10:46 /dev/zvol/tank1/zvol -> ../../zd0
# ls -l /dev/zd0 
brw-rw---- 1 qemu qemu 230, 0 Nov 24 11:03 /dev/zd0
# grep zd0 /proc/partitions 
 230        0   31457280 zd0
この zvol を KVM ゲストに割り当てて、CentOS 6.3 をインストールした直後のディスク消費量は次の通りです。なお、インストールオプションには、Software Development Workstation を選択しています。
# zfs list
NAME         USED  AVAIL  REFER  MOUNTPOINT
tank1       5.25G  53.3G   156K  /tank1
tank1/zvol  5.24G  53.3G  5.24G  -
# zfs get all tank1/zvol
NAME        PROPERTY              VALUE                  SOURCE
tank1/zvol  type                  volume                 -
tank1/zvol  creation              Sat Nov 24 10:01 2012  -
tank1/zvol  used                  5.24G                  -
tank1/zvol  available             53.3G                  -
tank1/zvol  referenced            5.24G                  -
tank1/zvol  compressratio         1.00x                  -
tank1/zvol  reservation           none                   default
tank1/zvol  volsize               30G                    local
tank1/zvol  volblocksize          8K                     -
tank1/zvol  checksum              on                     default
tank1/zvol  compression           off                    default
tank1/zvol  readonly              off                    default
tank1/zvol  copies                1                      default
tank1/zvol  refreservation        none                   default
tank1/zvol  primarycache          all                    default
tank1/zvol  secondarycache        all                    default
tank1/zvol  usedbysnapshots       0                      -
tank1/zvol  usedbydataset         5.24G                  -
tank1/zvol  usedbychildren        0                      -
tank1/zvol  usedbyrefreservation  0                      -
tank1/zvol  logbias               latency                default
tank1/zvol  dedup                 off                    default
tank1/zvol  mlslabel              none                   default
tank1/zvol  sync                  standard               default
tank1/zvol  refcompressratio      1.00x                  -
tank1/zvol  written               5.24G                  -
ZFS プールの空きや KVM ゲストのディスク使用量を気にかける必要はありますが、こんな具合にディスク消費量を節約できました。もっとも、節約だけであれば、スパースファイルでも同じことであり、実際、ext4 上にスパースファイルとして同様にインストールすると、ほぼ同じ消費量になります。
# df -Th /
Filesystem    Type    Size  Used Avail Use% Mounted on
/dev/sda6     ext4     20G   16G  2.5G  87% /
# ls -lsh /var/lib/libvirt/images/cent6vm64.img 
5.2G -rw-------. 1 root root 12G Aug 19 15:47 /var/lib/libvirt/images/cent6vm64.img
ZVOL を使う利点は、ZFS の豊富な機能 (compression, dedup, secondarycache, スナップショット) をゲスト毎に使い分けられる点ではないかと思います。また、運用上、スパースファイル方式よりも分かり易い (zfs list で各ゲストへの分配状況を俯瞰できる) かなとも思います。

ちなみに、LVM2 にも同様の機能を組み込もうとして、開発途上の模様です。CentOS 6 の man lvcreate(8) より抜粋です。
       -T, --thin, --thinpool ThinPoolLogicalVolume{Name|Path}
              Creates  thin  pool  or thin logical volume or both.  Specifying
              the optional argument --size will cause the creation of the thin
              pool  logical volume.  Specifying the optional argument --virtu-
              alsize will cause the creation of the thin logical  volume  from
              given  thin  pool  volume.  Specifying both arguments will cause
              the creation of both thin pool and thin volume using this  pool.
              Requires  device mapper kernel driver for thin provisioning from
              kernel 3.2 or newer.  Note: Thin types are currently  considered
              Tech  Preview.   For  more information on Tech Preview features,
              visit: https://access.redhat.com/support/offerings/techpreview/.
LVM2 (device-mapper) を使うと、運用が煩雑になる印象があるのですが、おそらくは、ZVOL より性能は上 (レイヤ増によるオーバーヘッドが少ない) だろうと思いますし、将来の選択肢として、頭の片隅に。

2012-11-25追記
さらに、compression による効果を試しました。zvol の compression プロパティを on にしてから、ゲストの CentOS 6.3 をインストールした結果です。
# zfs set compression=on tank1/zvol
... このあとで、ゲストをインストール ...
# zfs list
NAME         USED  AVAIL  REFER  MOUNTPOINT
tank1       3.60G  55.0G   156K  /tank1
tank1/zvol  3.60G  55.0G  3.60G  -
# zfs get all tank1/zvol
NAME        PROPERTY              VALUE                  SOURCE
tank1/zvol  type                  volume                 -
tank1/zvol  creation              Sat Nov 24 14:38 2012  -
tank1/zvol  used                  3.60G                  -
tank1/zvol  available             55.0G                  -
tank1/zvol  referenced            3.60G                  -
tank1/zvol  compressratio         1.76x                  -
tank1/zvol  reservation           none                   default
tank1/zvol  volsize               30G                    local
tank1/zvol  volblocksize          8K                     -
tank1/zvol  checksum              on                     default
tank1/zvol  compression           on                     local
tank1/zvol  readonly              off                    default
tank1/zvol  copies                1                      default
tank1/zvol  refreservation        none                   default
tank1/zvol  primarycache          all                    default
tank1/zvol  secondarycache        all                    default
tank1/zvol  usedbysnapshots       0                      -
tank1/zvol  usedbydataset         3.60G                  -
tank1/zvol  usedbychildren        0                      -
tank1/zvol  usedbyrefreservation  0                      -
tank1/zvol  logbias               latency                default
tank1/zvol  dedup                 off                    default
tank1/zvol  mlslabel              none                   default
tank1/zvol  sync                  standard               default
tank1/zvol  refcompressratio      1.76x                  -
tank1/zvol  written               3.60G                  -
圧縮により 1.64G ほどディスク消費を節約できています。
compression プロパティは、いつでも変更可能であり、ゲストのインストール時やアップデート時のみ、compression=on にして、ゲストの通常運用時には、compressoin=off にしておくといった使い方も可能です。

2012-12-06追記
重複排除 (dedup) についても、試してみました。zvol01 および zvol02 を用意して、dedup=verify を設定してから、各 zvol をそれぞれ KVM ゲストに割り当てて、CentOS 6.3 をインストールした場合の結果です。
# grep tank1/zvol01 /etc/libvirt/qemu/cent6zvol01.xml 
      <source dev='/dev/zvol/tank1/zvol01'/>
# grep tank1/zvol02 /etc/libvirt/qemu/cent6zvol02.xml 
      <source dev='/dev/zvol/tank1/zvol02'/>
# zfs get compression
NAME          PROPERTY     VALUE     SOURCE
tank1         compression  off       default
tank1/zvol01  compression  off       default
tank1/zvol02  compression  off       default
# zfs get dedup
NAME          PROPERTY  VALUE          SOURCE
tank1         dedup     off            default
tank1/zvol01  dedup     verify         local
tank1/zvol02  dedup     verify         local
# zfs list
NAME           USED  AVAIL  REFER  MOUNTPOINT
tank1         11.5G  51.4G   156K  /tank1
tank1/zvol01  5.60G  51.4G  5.60G  -
tank1/zvol02  5.52G  51.4G  5.52G  -
# zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
tank1  59.5G  7.10G  52.4G    11%  1.68x  ONLINE  -
重複排除により 4G ほど削減できています。重複排除は zpool の括りで行われるようで、効果確認は zpool コマンドで行います。
dedup プロパティについても、いつでも変更可能なので、インストール時だけ dedup=verify にして、通常運用時は dedup=off という使い方も可能です。ここでは試しませんでしたが、compression=on との同時利用も可能です。

2012年11月23日金曜日

ZVOL の性能

CentOS 6 + ZFS on Linux 0.6.0-rc12 において、ZVOL (ZFS プールの一部をブロックデバイスとして export する機能= LVM 的な機能) を使用したいと思い、利用方法調査と性能測定をやってみました。測定環境は、以前と同様に ThinkPad T510 です。

まず、設定方法は次の通りです。
# zfs list
NAME    USED  AVAIL  REFER  MOUNTPOINT
tank1  2.07M  58.6G   156K  /tank1
# zfs create -V 30G tank1/zvol
# zfs get all tank1/zvol
NAME        PROPERTY              VALUE                  SOURCE
tank1/zvol  type                  volume                 -
tank1/zvol  creation              Fri Nov 23 12:14 2012  -
tank1/zvol  used                  30.9G                  -
tank1/zvol  available             58.6G                  -
tank1/zvol  referenced            72K                    -
tank1/zvol  compressratio         1.00x                  -
tank1/zvol  reservation           none                   default
tank1/zvol  volsize               30G                    local
tank1/zvol  volblocksize          8K                     -
tank1/zvol  checksum              on                     default
tank1/zvol  compression           off                    default
tank1/zvol  readonly              off                    default
tank1/zvol  copies                1                      default
tank1/zvol  refreservation        30.9G                  local
tank1/zvol  primarycache          all                    default
tank1/zvol  secondarycache        all                    default
tank1/zvol  usedbysnapshots       0                      -
tank1/zvol  usedbydataset         72K                    -
tank1/zvol  usedbychildren        0                      -
tank1/zvol  usedbyrefreservation  30.9G                  -
tank1/zvol  logbias               latency                default
tank1/zvol  dedup                 off                    default
tank1/zvol  mlslabel              none                   default
tank1/zvol  sync                  standard               default
tank1/zvol  refcompressratio      1.00x                  -
tank1/zvol  written               72K                    -
# ls -l /dev/zvol/tank1/zvol 
lrwxrwxrwx 1 root root 9 Nov 23 12:15 /dev/zvol/tank1/zvol -> ../../zd0
# ls -l /dev/zd0
brw-rw---- 1 root disk 230, 0 Nov 23 12:15 /dev/zd0
このように、/dev/zd0 が生成されます。

今回は、作成されたブロックデバイスを ext4 にして、性能測定を行いました。
# mkfs -t ext4 /dev/zvol/tank1/zvol 
mke2fs 1.41.12 (17-May-2010)
Discarding device blocks: done                            
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=2 blocks, Stripe width=2 blocks
1966080 inodes, 7864320 blocks
393216 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
240 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
 4096000

Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 24 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
# mount /dev/zvol/tank1/zvol /mnt_tank1_zvol/
# df /mnt_tank1_zvol/
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/zd0              30963708    176064  29214780   1% /mnt_tank1_zvol
いちおう、io scheduler を3種類 (cfq, noop, deadline) 試しましたが、deadline が最も良好でしたので、その結果のみ掲載します。
# echo deadline > /sys/block/sdd/queue/scheduler 
# cat /sys/block/sdd/queue/scheduler 
noop anticipatory [deadline] cfq 
# bonnie++ -u root -d /mnt_tank1_zvol/
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx         15464M   940  96 40404   4 19568   3  2630  60 68826   5  4712  63
Latency             14844us    4526ms    4292ms     400ms     417ms    6134us
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 20098  18 +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++
Latency               108us     927us     473us     169us      25us      54us
1.96,1.96,xxxx,1,1353630877,15464M,,940,96,40404,4,19568,3,2630,60,68826,5,4712,63,16,,,,,20098,18,+++++,+++,+++++,+++,+++++,+++,+++++,+++,+++++,+++,14844us,4526ms,4292ms,400ms,417ms,6134us,108us,927us,473us,169us,25us,54us
ベースの ZFS プール(tank1)の性能に対して、シーケンシャル WRITE で、約25% ほどの性能低下です。

2012年11月11日日曜日

ZFS と io scheduler

CentOS 6 で ZFS on Linux を利用する場合に、io scheduler が性能にどのように影響するのか、少しだけ実験してみました。ZFS は自身で I/O スケジューリングを行うはずなので、Linux の io scheduler は邪魔ではないかと思ったもので。。

順番に cfq(デフォルト), noop, deadline の場合の bonnie++ のデータです。
# cat /sys/block/sdd/queue/scheduler 
noop anticipatory deadline [cfq]
# bonnie++ -u root -d /tank1
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx         15464M   144  99 60984  12 35507   9   345  90 95825  10 800.4  26
Latency               103ms     212ms    1351ms     751ms     547ms     556ms
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  9603  93 +++++ +++ 25418  97  7615  94 +++++ +++ 20001  97
Latency             37143us     734us     584us   86610us     101us    1078us
1.96,1.96,xxxx,1,1352637907,15464M,,144,99,60984,12,35507,9,345,90,95825,10,800.4,26,16,,,,,9603,93,+++++,+++,25418,97,7615,94,+++++,+++,20001,97,103ms,212ms,1351ms,751ms,547ms,556ms,37143us,734us,584us,86610us,101us,1078us
# echo noop > /sys/block/sdd/queue/scheduler 
# cat /sys/block/sdd/queue/scheduler 
[noop] anticipatory deadline cfq
# bonnie++ -u root -d /tank1
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx         15464M   149  99 53196  11 34046   9   360  92 105384  12 853.4  26
Latency             95853us     418ms    1455ms     596ms     374ms     561ms
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  9562  92 +++++ +++ 25809  96 10773  96 +++++ +++ 10272  98
Latency             35613us     299us     819us   49027us      97us     387us
1.96,1.96,xxxx,1,1352612707,15464M,,149,99,53196,11,34046,9,360,92,105384,12,853.4,26,16,,,,,9562,92,+++++,+++,25809,96,10773,96,+++++,+++,10272,98,95853us,418ms,1455ms,596ms,374ms,561ms,35613us,299us,819us,49027us,97us,387us
# echo deadline > /sys/block/sdd/queue/scheduler 
# cat /sys/block/sdd/queue/scheduler 
noop anticipatory [deadline] cfq 
# bonnie++ -u root -d /tank1
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx         15464M   148  99 54315  11 34406   9   355  91 105448  12 831.9  24
Latency               107ms     289ms    1232ms     689ms     318ms     621ms
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  9649  93 +++++ +++ 23925  85 16976  95 +++++ +++ 27138  97
Latency             35409us     735us     339us   54244us      25us     128us
1.96,1.96,xxxx,1,1352612140,15464M,,148,99,54315,11,34406,9,355,91,105448,12,831.9,24,16,,,,,9649,93,+++++,+++,23925,85,16976,95,+++++,+++,27138,97,107ms,289ms,1232ms,689ms,318ms,621ms,35409us,735us,339us,54244us,25us,128us
あちらを立てればこちらが立たず という感じです。

また、io scheduler をいじっても、FreeBSD 9.0 の ZFS 性能にはかなわないようです。
としても、CentOS 6 で ZFS を普通に使える (わたしの利用レベルでは安定しています) ことは、ありがたいことです。

最後に、この記事の掲載データは、FreeBSD 9.0 のデータを測ったのと同じマシン (ThinkPad T510)、同じボリューム (eSATA 接続の古い SAMSUNG製 SSD) のものです。
人気ブログランキングへ にほんブログ村 IT技術ブログへ