2012年10月28日日曜日

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 を試したのですが、わたしの利用形態では効果を実感することはありませんでした。

0 件のコメント:

コメントを投稿

人気ブログランキングへ にほんブログ村 IT技術ブログへ