2016年9月17日土曜日

CentOS6 + ZFS on Linux 環境での updatedb による余分なI/O負荷

ZFS on Linux を CentOS6 で動作させている環境で、cron.daily の際に updatedb がやけに動いていることを発見。
mlocate.cron を見てみたら、次のような記述になっていました。
[root@hoge ~]# cat /etc/cron.daily/mlocate.cron 
#!/bin/sh
nodevs=$(< /proc/filesystems awk '$1 == "nodev" && $2 != "zfs" { print $2 }')
renice +19 -p $$ >/dev/null 2>&1
ionice -c2 -n7 -p $$ >/dev/null 2>&1
/usr/bin/updatedb -f "$nodevs"
まさかとは思いましたが、レッドハットが ZFS に配慮しているケースもあるみたいです。mlocate の changelog から抜粋。
[root@hoge ~]# rpm -q --changelog mlocate | head -8
* Mon Jan 26 2015 Michal Sekletar <msekleta@redhat.com> - 0.22.2-6
- mlocate.db is ghost file created with non-default attrs, list them explicitly so rpm --verify doesn't report errors (#1182304)

* Wed Jan 07 2015 Michal Sekletar <msekleta@redhat.com> - 0.22.2-5
- index zfs filesystems despite the fact they are marked as nodev (#1023779)
- use more strict permissions for cron script and mark it as config (#1012534)
- add gpfs to PRUNEFS (#1168301)

[root@hoge ~]# 
対応するバグジラ(#1023779)によると、
https://bugzilla.redhat.com/show_bug.cgi?id=1023779
ZFS 領域が updatedb の対象にならないという問題があり、まず Fedora で修正され、RHEL6 にも修正が取り込まれたようです。
さらには、RHEL7 向けのバグジラ(#1304416)もオープンされています。
https://bugzilla.redhat.com/show_bug.cgi?id=1304416
こちらは、RHEL7.3 向けに Status:VERIFIED の状態、つまり、ベータに取り込まれた模様です。

レッドハットが ZFS を無視しないでくれる(つまりは、ある程度は RHEL+ZFS を利用する顧客が居るらしい?)のは、個人的にはありがたいことと思いました。
が、しかし、ZFS の倉庫領域(大量のファイルを格納している)は、updatedb 対象じゃないほうが良いです。わたしの使い方に於いては。
というわけで、
[root@hoge ~]# vi /etc/updatedb.conf 
PRUNE_BIND_MOUNTS = "yes"
PRUNEFS = "zfs 9p afs anon_inodefs auto autofs bdev binfmt_misc cgroup cifs coda configfs cpuset debugfs devpts ecryptfs exofs fuse fusectl gfs gfs2 gpfs hugetlbfs inotifyfs iso9660 jffs2 lustre mqueue ncpfs nfs nfs4 nfsd pipefs proc ramfs rootfs rpc_pipefs securityfs selinuxfs sfs sockfs sysfs tmpfs ubifs udf usbfs"
PRUNENAMES = ".git .hg .svn"
PRUNEPATHS = "/afs /media /net /sfs /tmp /udev /var/cache/ccache /var/spool/cups /var/spool/squid /var/tmp"
[root@hoge ~]#
という具合に設定しました。
[root@hoge ~]# grep mlocate /var/log/cron
...
Sep 10 03:41:09 hoge run-parts(/etc/cron.daily)[6431]: starting mlocate.cron
Sep 10 04:19:02 hoge run-parts(/etc/cron.daily)[13231]: finished mlocate.cron
Sep 11 03:48:11 hoge run-parts(/etc/cron.daily)[12147]: starting mlocate.cron
Sep 11 04:22:57 hoge run-parts(/etc/cron.daily)[18782]: finished mlocate.cron
Sep 12 03:17:06 hoge run-parts(/etc/cron.daily)[11282]: starting mlocate.cron
Sep 12 03:43:40 hoge run-parts(/etc/cron.daily)[16158]: finished mlocate.cron
Sep 13 03:22:05 hoge run-parts(/etc/cron.daily)[16992]: starting mlocate.cron
Sep 13 03:50:24 hoge run-parts(/etc/cron.daily)[22578]: finished mlocate.cron
Sep 14 03:08:05 hoge run-parts(/etc/cron.daily)[20083]: starting mlocate.cron★ここから変更後
Sep 14 03:08:22 hoge run-parts(/etc/cron.daily)[20318]: finished mlocate.cron
Sep 15 03:13:08 hoge run-parts(/etc/cron.daily)[25880]: starting mlocate.cron
Sep 15 03:13:14 hoge run-parts(/etc/cron.daily)[26074]: finished mlocate.cron
Sep 16 03:07:06 hoge run-parts(/etc/cron.daily)[29745]: starting mlocate.cron
Sep 16 03:07:09 hoge run-parts(/etc/cron.daily)[29947]: finished mlocate.cron
このように、30~40分程度動いていた updatedb が、10秒程度になり、無駄な I/O 負荷をカットできました。
人気ブログランキングへ にほんブログ村 IT技術ブログへ