2012年10月28日日曜日

CentOS 6 と CentOS 5 で ZFS を共用する

CentOS 5 では、ZFS on Linux が使えない (ビルドできない) ので、zfs-fuse を使うよりないのですが、マルチブート環境で、CentOS 6 と共用したいため、そのための設定方法メモです。

zfs-fuse のほうが zpool および zfs のバージョンが低いので、CentOS 6 に ZFS on Linux を導入した環境で、次のようにバージョンを指定してストレージプールを作成すれば、マルチブートで共用できるようになります。
# zpool create -o ashift=12 -o version=23 -O version=4 tank1 /dev/disk/by-id/scsi-SATA_External_Disk_0AL25744_6000092__0_S-part1
# fdisk -u -l /dev/sdd | grep sdd1
/dev/sdd1            2048   125045423    62521688   83  Linux
ここで、ashift=12 は AFT 対応 HDD (物理セクタサイズが 4K の HDD) の場合に指定すると効果があるパラメータですが、zfs-fuse 付属の zpool コマンドでは指定できません。また、上記のようにパーティションを切っている場合は、先頭セクタ番号が 8 の倍数になるように調整しておく必要があります。

ベンチマーク結果を参考に載せておきます。
まず、CentOS 6 + ZFS on Linux 0.6.0-rc11 の場合です。
# uname -a
Linux xxxx 2.6.32-279.11.1.el6.x86_64 #1 SMP Tue Oct 16 15:57:10 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
# zpool get guid tank1
NAME   PROPERTY  VALUE  SOURCE
tank1  guid      4585092805656841166  local
# zpool status
  pool: tank1
 state: ONLINE
status: The pool is formatted using an older on-disk format.  The pool can
 still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'.  Once this is done, the
 pool will no longer be accessible on older software versions.
 scan: none requested
config:

 NAME                                                   STATE     READ WRITE CKSUM
 tank1                                                  ONLINE       0     0     0
   scsi-SATA_External_Disk_0AL25744_6000092__0_S-part1  ONLINE       0     0     0

errors: No known data errors
# 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   161  99 60368  12 35164   9   371  94 96024  10 807.8  26
Latency             99022us     443ms    1407ms     332ms     546ms    1067ms
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  9314  91 +++++ +++ 24604  97  9976  95 +++++ +++  9474  98
Latency             48790us     741us     505us   53719us     128us    1094us
1.96,1.96,xxxx,1,1350830603,15464M,,161,99,60368,12,35164,9,371,94,96024,10,807.8,26,16,,,,,9314,91,+++++,+++,24604,97,9976,95,+++++,+++,9474,98,99022us,443ms,1407ms,332ms,546ms,1067ms,48790us,741us,505us,53719us,128us,1094us

次に、CentOS 5 + zfs-fuse-0.6.9_p1-6.20100709git.el5.1 のデータです。
# uname -a
Linux xxxx 2.6.18-308.11.1.el5 #1 SMP Tue Jul 10 08:48:43 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux
# zpool get guid tank1
NAME   PROPERTY  VALUE  SOURCE
tank1  guid      4585092805656841166  default
# zpool status
  pool: tank1
 state: ONLINE
 scrub: none requested
config:

        NAME                                                              STATE     READ WRITE CKSUM
        tank1                                                             ONLINE       0     0     0
          disk/by-id/scsi-SATA_External_Disk_0AL25744_6000092__0_S-part1  ONLINE       0     0     0

errors: No known data errors
# 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         15424M    24  11 32019   5 24308   6  2379  98 103178   7 496.0   9
Latency               506ms    1381ms    1627ms   10573us     609ms     999ms
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  5648  12 11300  10  5469   7  5038  12 12881  14  7092  12
Latency             28879us    1700us    3875us   54328us    1760us    2040us
1.96,1.96,xxxx,1,1351439162,15424M,,24,11,32019,5,24308,6,2379,98,103178,7,496.0,9,16,,,,,5648,12,11300,10,5469,7,5038,12,12881,14,7092,12,506ms,1381ms,1627ms,10573us,609ms,999ms,28879us,1700us,3875us,54328us,1760us,2040us
使用機材は、ThinkPad T510 Core i7 M620 2.67G + SAMSUNGの2008年製造の古い SSD 64G (eSATA 接続) です。

2012-11-10追記
わたしの利用範囲では、ZFS on Linux の性能は十分であると感じますが、FreeBSD のほうが上だと聞きますので、試しに同じマシン(ThinkPad T510)にマルチブート環境を作って、同じボリュームを import して、bonnie++ で計測してみました。
# uname -a
FreeBSD xxxx 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan  3 07:46:30 UTC 2012     root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
# 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            16G   173  99 53620   9 33313   5   425  90 138720   7 876.5   8
Latency             46882us    4175ms    3542ms     513ms     590ms     782ms
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 29261  88 +++++ +++ 32398  97 23195  97 +++++ +++ 12962  98
Latency             13252us     132us     126us   26767us     102us    7513us
1.96,1.96,xxxx,1,1352526856,16G,,173,99,53620,9,33313,5,425,90,138720,7,876.5,8,16,,,,,29261,88,+++++,+++,32398,97,23195,97,+++++,+++,12962,98,46882us,4175ms,3542ms,513ms,590ms,782ms,13252us,132us,126us,26767us,102us,7513us
# zpool get all tank1
NAME   PROPERTY       VALUE       SOURCE
...
tank1  guid           4585092805656841166  local
...
# zpool status
  pool: tank1
 state: ONLINE
status: The pool is formatted using an older on-disk format.  The pool can
 still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'.  Once this is done, the
 pool will no longer be accessible on older software versions.
 scan: none requested
config:

 NAME        STATE     READ WRITE CKSUM
 tank1       ONLINE       0     0     0
   ada2s1    ONLINE       0     0     0

errors: No known data errors
確かに各数字を見比べてみると、全般的に FreeBSD 9.0 のほうが、少し性能が上に見えました。
もしも、NAS 専用サーバを作るのであれば、FreeBSD や FreeNAS というものは、良い選択肢なのかもなと思いました。

余談:FreeBSD は、過去何回かインストールした経験があったのですが、拡張パーティションにはインストールできないということを、すっかり忘れており(たぶん、以前同じようにハマったと思いました)、結構な手間・時間がかかってしまいました。たぶん、ほとんど起動しないだろうというのに。。
なお、FreeBSD 10 に向けて、ZFS の性能向上の取り組みがあるらしいので、リリースされたら、また測ってみたいなと思っています。

ZFS の L2ARC に zram を利用する

ZFS の L2ARC に zram を利用し始めたのですが、汎用的な zram の初期化スクリプトというのは無いため、自分のサーバ (CentOS 6.3) 向けに初期化スクリプトを書きました。
一から書くのも骨ですので、どなたかの参考になれば幸いです。
#!/bin/bash
#
# my_zram       This shell script takes care of starting and stopping
#               zram for swap and zfs's cache(L2ARC).
#
# chkconfig: 12345 90 99
# description:  initializing zram for my server
#
# config:

### BEGIN INIT INFO
# Provides: my_zram
# Required-Start: 
# Required-Stop: 
# Default-Stop: 0 1 2 3 6
# Short-Description: initializing zram
# Description:  initializing zram
#
### END INIT INFO

#
# Authors: luna2 <blue3waters at gmail dot com>
#
# This file is subject to the GNU General Public License.
# It comes with NO WARRANTY.
#

LOCKFILE=/var/lock/subsys/my_zram

case "$1" in
  start)
    [ ! -e /tank2/src ] && service zfs start
    modprobe zram num_devices=2
    if [ $? -eq 0 ] ; then
        echo $((2048*1024*1024)) > /sys/block/zram0/disksize
        echo  $((896*1024*1024)) > /sys/block/zram1/disksize
        #
        /sbin/zpool add tank2 cache /dev/zram0
        #
        mkswap /dev/zram1
        swapon -p 1 /dev/zram1
        #
        touch $LOCKFILE
    fi
    ;;
  stop)
    /sbin/zpool remove tank2 /dev/zram0
    /sbin/zfs umount -a
    service zfs stop
    rm -f $LOCKFILE
    ;;
  *)
    echo "Usage $0 start | stop "
    ;;
esac

ストレージプール tank2 に、2G の cache (L2ARC) を追加し、ついでに、スワップを 896M 用意しています。また、起動順は 90番 に設定しています。これは、samba と NFS の初期化順序を考慮した結果です。
# ls -1 /etc/rc5.d/S??{nfs,smb,zfs}
/etc/rc5.d/S01zfs
/etc/rc5.d/S30nfs
/etc/rc5.d/S91smb
デフォルトでは、上のように zfs の初期化が nfs よりも早いのですが、sharenfs を使うには、zfs の初期化を nfs より後ろにする必要があるため、chkconfig zfs off に設定して、zfs の起動は、my_zram の中から行うようにしています。

2012-10-29追記
zram の効用について、追記です。
わたしが ZFS サーバに使用しているマシンは、メモリを 4G 積んでいるのですが、古いチップセット (945G Express) であるため、3.3G までしか見えないという貧弱なものです。zram 等のチューニングを施す前の状態だと、2~3日使用すると、free コマンドで次のような値を示していました。
             total       used       free     shared    buffers     cached
Mem:       3410036    2876652     533384          0      65448     586916
-/+ buffers/cache:    2224288    1185748
Swap:      2046968     213948    1833020
200M ほどスワップ使用されていますが、この状態でも、わたしの用途では、そんなに困るわけでもなかったのですが、zram を適量使うことで (※この適量のバランスが難しかったのですが) 、ディスクスワップしないで済むようになりました。次が、チューニング後の値です。
             total       used       free     shared    buffers     cached
Mem:       3410036    3185076     224960          0      67944     616652
-/+ buffers/cache:    2500480     909556
Swap:      2964464     781364    2183100
ここで、Swap: used の値が 780M ほどを示していますが、これが zram 上に載っています。
# cat /proc/swaps
Filename                                Type            Size    Used    Priority
/dev/md2                                partition       2046968 0       -1
/dev/zram1                              partition       917496  781352  1
これ、この通り。zram 利用前は md2 が使われていましたが、ディスクスワップせずに済んでいます。初期化スクリプト中で、swapon コマンドに -p 1 というオプションを与えていますが、これにより、md2 よりも zram1 が優先して使われます。
zram の圧縮状況は、/sys から読み取れます。
# cat /sys/block/zram1/mem_used_total
205156352
単純計算で 580M ほど、稼いだ結果になっています。
一方、ストレージプール tank2 に cache (L2ARC) として追加した zram0 のほうは次のような状況です。
# cat /sys/block/zram0/mem_used_total
784912384
zpool iostat -v から cache の使用状況がわかるのですが、上記のキャプチャの際には既に飽和していましたので、約1.3G ほど稼いだことになります。なお、tank2 には、各種 OSS のソースコードと CentOS などの iso イメージを格納しており、secondarycache プロパティを次のように設定しています。
# zfs get secondarycache tank2/src
NAME       PROPERTY        VALUE           SOURCE
tank2/src  secondarycache  all             local
# zfs get secondarycache tank2/isos
NAME        PROPERTY        VALUE           SOURCE
tank2/isos  secondarycache  metadata        local
ソースコードは中身もろとも、iso はメタデータのみ L2ARC 許可ということです。

説明が最後になりましたが、デフォルトの状態だと ARC への割り当て量が多すぎるようなので、次の設定により、1G に絞っています。
# cat /etc/modprobe.d/zfs.conf
options zfs zfs_arc_max=1073741824
デフォルトだと 約1.8G でした。/proc/spl/kstat/zfs/arcstats から確認可能です。

まとめますと、わたしのマシンのケースでは、
3.3G 物理メモリ
1G  ARC
2G  zram L2ARC
896M zram swap
という配分で、zram により 約1.9G ほどお得しています。計測が難しいですが、体感上は引っかかりが少なくなったような気がしています。

なお、上記の配分に至るまでは、何回か試行錯誤が必要でした。zram を使いすぎると、スラッシングになり逆効果になる場合もあるようでした。

2012-12-08追記
その後、利用していて、swap が合計 2G 近くに達する状況 (disk swap にはみ出た) があったため、zram swap を 2G に変更して使っています。変更後、2G 弱まで swap が成長しましたが、disk swap には達せずに、よい感じ。どなたかのご参考まで。

2013-06-02追記
illumos プロジェクトで、L2ARC の圧縮機能 (secondarycachecompress) を開発中のようです。メモまで。
http://wiki.illumos.org/display/illumos/L2ARC+Compression

2013-08-31追記
ZFS on Linux 0.6.2 がリリースされました。secondarycachecompress が導入されたようです。着実な進化に感謝です。
https://groups.google.com/a/zfsonlinux.org/forum/#!topic/zfs-announce/DOAuSF7kjsU
New Features:
...
* Added L2ARC compression from Illumos
ですけれど、プールバージョン 5000 にする必要がありますし、自分としては、まだしばらく zram を使おうかと思ってます。

2013-09-02追記
1台を 0.6.2 にアップデートしてみたのですが、secondarycachecompress というプロパティは見当たらず、経緯を確認したところ、illumos のほうで、プロパティにする必要が無いという判断になり、ZOL も追従したようです。ただし、モジュールオプション l2arc_nocompress で off にすることも可能にしたようです。
https://github.com/zfsonlinux/zfs/issues/1379
# rpm -q zfs
zfs-0.6.2-1.el6.x86_64
# modinfo -p zfs | grep l2arc_nocompress
l2arc_nocompress:Skip compressing L2ARC buffers
# cat /sys/module/zfs/parameters/l2arc_nocompress 
0
# uname -a
Linux xxxx 2.6.32-358.18.1.el6.x86_64 #1 SMP Wed Aug 28 17:19:38 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/redhat-release 
CentOS release 6.4 (Final)

2013-10-12追記
Fedora 19 のカーネルは、zram がオフになっているのですが、rpmfusion が提供している kmod-staging に zram が入っているので、こちらを利用すれば良いようです。ただし、カーネルバージョン依存なので、注意が必要です。Fedora から新しいカーネルがリリースされてから1~2週間くらい経たないと、対応する kmod-staging が出てこないので、/etc/yum.conf に exclude=kernel-* を指定しておいたほうがいいかも。
カーネルを再構築してもいいわけですが、面倒なので、メモでした。
なおカーネル 3.11 で、zswap が入ったので、zram + zswap を試したのですが、わたしの利用形態では効果を実感することはありませんでした。

2012年10月27日土曜日

dkms 対応の ZFS on Linux を CentOS 6.3 に導入する

ZFS on Linux 0.6.0-rc10 (Aug 14 2012 リリース) から dkms (dynamic kernel module support) 対応が行われたようで、少々乗り遅れていますが、CentOS 6.3 に dkms 対応版を導入しました。その手順メモです。

これまでは、非dkms対応の 0.6.0-rc8 をビルドして使っていましたので、まずは、こちらを一旦削除してリブートします。
# zfs umount -a
# yum remove zfs
# rpm -e zfs-modules
# yum remove spl
# yum remove spl-modules
# shutdown -r now

次に、基盤となる dkms をインストールします。こちらは、EPEL に収録されているものを利用しました。
# yum install dkms --enablerepo=epel
...
# rpm -qi dkms
Name        : dkms                         Relocations: (not relocatable)
Version     : 2.2.0.3                           Vendor: Fedora Project
Release     : 2.el6                         Build Date: Mon 11 Jun 2012 11:39:12 PM JST
Install Date: Sun 21 Oct 2012 04:56:02 PM JST      Build Host: x86-02.phx2.fedoraproject.org
Group       : System Environment/Base       Source RPM: dkms-2.2.0.3-2.el6.src.rpm
Size        : 215347                           License: GPLv2+
Signature   : RSA/8, Fri 15 Jun 2012 08:47:09 AM JST, Key ID 3b49df2a0608b895
Packager    : Fedora Project
URL         : http://linux.dell.com/dkms
Summary     : Dynamic Kernel Module Support Framework
Description :
This package contains the framework for the Dynamic
Kernel Module Support (DKMS) method for installing
module RPMS as originally developed by Dell.

そして、ZFS 本体をインストールします。途中、zfs をリビルドする際に、e2fsprogs-devel と libblkid-devel が依存エラーになったので、追加インストールしました。
# rpm -ivh spl-modules-dkms-0.6.0-rc11.noarch.rpm
# rpmbuild --rebuild spl-0.6.0-rc11.src.rpm
# rpm -Uvh /root/rpmbuild/RPMS/x86_64/spl-0.6.0-rc11.el6.x86_64.rpm
# rpm -Uvh zfs-modules-dkms-0.6.0-rc11.noarch.rpm
# yum install e2fsprogs-devel
# yum install libblkid-devel
# rpmbuild --rebuild zfs-0.6.0-rc11.src.rpm
# rpm -Uvh /root/rpmbuild/RPMS/x86_64/zfs-0.6.0-rc11.el6.x86_64.rpm
# rpm -Uvh /root/rpmbuild/RPMS/x86_64/zfs-devel-0.6.0-rc11.el6.x86_64.rpm
# rpm -Uvh /root/rpmbuild/RPMS/x86_64/zfs-dracut-0.6.0-rc11.el6.x86_64.rpm
# rpm -Uvh /root/rpmbuild/RPMS/x86_64/zfs-test-0.6.0-rc11.el6.x86_64.rpm
# shutdown -r now

各種モジュールがロードされていること、zfs 領域が見えることを確認して完了です。
# lsmod | grep zfs
zfs                  1104868  0 
zcommon                43286  1 zfs
znvpair                47487  2 zfs,zcommon
zavl                    6925  1 zfs
zunicode              323120  1 zfs
spl                   253420  5 zfs,zcommon,znvpair,zavl,zunicode
# zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
tank1  59.5G  1.02M  59.5G     0%  1.00x  ONLINE  -
# zfs list
NAME    USED  AVAIL  REFER  MOUNTPOINT
tank1   920K  58.6G   104K  /tank1

これで、新しいカーネルにアップデートする際、今までよりも手間が減ることになります。現在の dkms の状態を見ると、次のようになっています。
# dkms status
spl, 0.6.0, 2.6.32-279.11.1.el6.x86_64, x86_64: installed
zfs, 0.6.0, 2.6.32-279.11.1.el6.x86_64, x86_64: installed
spl, 0.6.0, 2.6.32-279.5.1.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
zfs, 0.6.0, 2.6.32-279.5.1.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
spl, 0.6.0, 2.6.32-279.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
zfs, 0.6.0, 2.6.32-279.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
現時点で最新の 2.6.32-279.11.1.el6 を使っていますが、残してある古いカーネルでも zfs が動く状態になっていることが確認できます。
そのうち、新しいカーネルが出てきたらアップデートして、追加レポートしたいと思います。

2012-11-07追記
本日、新しいカーネル 2.6.32-279.14.1.el6 が出てきましたので、早速インストールしました。
# uname -a
Linux xxxx 2.6.32-279.14.1.el6.x86_64 #1 SMP Tue Nov 6 23:43:09 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
# dkms status
spl, 0.6.0, 2.6.32-279.11.1.el6.x86_64, x86_64: installed
zfs, 0.6.0, 2.6.32-279.11.1.el6.x86_64, x86_64: installed
spl, 0.6.0, 2.6.32-279.14.1.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
zfs, 0.6.0, 2.6.32-279.14.1.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
spl, 0.6.0, 2.6.32-279.5.1.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
zfs, 0.6.0, 2.6.32-279.5.1.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
spl, 0.6.0, 2.6.32-279.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
zfs, 0.6.0, 2.6.32-279.el6.x86_64, x86_64: installed-weak from 2.6.32-279.11.1.el6.x86_64
# lsmod | grep zfs
zfs                  1104868  1 
zcommon                43286  1 zfs
znvpair                47487  2 zfs,zcommon
zavl                    6925  1 zfs
zunicode              323120  1 zfs
spl                   253420  5 zfs,zcommon,znvpair,zavl,zunicode
# zfs list
NAME    USED  AVAIL  REFER  MOUNTPOINT
tank1   932K  58.6G   104K  /tank1
このとおり、以前のように再ビルドすることなく、ZFS 領域が使えました。大変便利になったと思います。

2013-04-02追記
0.6.1 がリリースされ、CentOS 6 向けのバイナリの yum リポジトリが提供されたので、こちらを参照してください。

2013-06-29追記
モジュールをコンパイルした際の古いカーネル(上記の例なら 2.6.32-279.11.1.el6)を削除してしまうと、モジュールも削除されてしまい、新カーネル(2.6.32-279.14.1.el6)で ZFS が使えなくなってしまいます。
その場合、次のコマンドで再コンパイルすれば良いです。
# dkms install -m spl -v 0.6.1
# dkms install -m zfs -v 0.6.1
人気ブログランキングへ にほんブログ村 IT技術ブログへ