2010年8月31日火曜日

kdump に lzop を使う方法

kdump にはダンプファイルを圧縮する設定があり、普通は core_collector ディレクティブに makedumpfile -c を指定するという方法をとる。ただ、圧縮処理には結構な時間がかかり、これを短縮する方法はないかと考えてみた。

makedumpfile -c を指定した場合の initrd内のinit には、次のような記述が埋め込まれる。
mount -t ext3 $DUMPDEV /mnt
if [ $? == 0 ]
then
  mkdir -p /mnt///127.0.0.1-$DATE
  VMCORE=/mnt///127.0.0.1-$DATE/vmcore
  export VMCORE
  makedumpfile -c /proc/vmcore $VMCORE-incomplete >/dev/null
つまるところ core_collector に指定するフィルタプログラムは cp のシンタックスを満たせば良いようだ。 数ある圧縮プログラムの中で、高速であることを特徴とするものに lzop というプログラムがあり、これを使いたい。ただ、コマンドラインオプションを細工しても、cp のシンタックスを満たすようにはできないので、一皮かぶせる。
#! /sbin/busybox msh
/usr/bin/lzop -o $2 $1
こいつを、/etc/kdump.conf に次のような形で指定する。
ext3 LABEL=/1
path /var/crash
extra_bins /usr/bin/lzop /usr/bin/lzop.copy
core_collector lzop.copy
そうすると、initrd 内に lzop 関連のファイルが全部入る。
# zcat /boot/initrd-2.6.18-194.el5kdump.img | cpio -tv | grep lzo
-rwxr-xr-x   1 root     root       125672 Aug 31 23:19 usr/lib64/liblzo2.so.2
-rwxr-xr-x   1 root     root           44 Aug 31 23:19 usr/bin/lzop.copy
-rwxr-xr-x   1 root     root        67288 Aug 31 23:19 usr/bin/lzop
17070 blocks
initrd内のinitは次のように展開される。
mount -t ext3 $DUMPDEV /mnt
if [ $? == 0 ]
then
  mkdir -p /mnt//var/crash/127.0.0.1-$DATE
  VMCORE=/mnt//var/crash/127.0.0.1-$DATE/vmcore
  export VMCORE
  lzop.copy /proc/vmcore $VMCORE-incomplete >/dev/null
これでうまいこと、lzop 圧縮でダンプファイルが生成できました。
# pwd
/var/crash/127.0.0.1-2010-08-31-23:27:08
# file vmcore 
vmcore: lzop compressed data - version 1.020, LZO1X-1, os: Unix
gzip や bzip2 でも、同様にできるものと思いますが、速度の面から考えて、有用なのは lzop だけなのではと思います。
なお、lzop は RHEL6 Beta2 には含まれてましたが、RHEL5 には含まれていませんので、rpmfind などから拾ってくる必要があります。

2010-12-05追記
lzop で採取されたダンプの参照方法と、lzop を用いた場合の効果を書いていなかったので、まとめたいと思います。
まず、lzop で採取されたダンプの解凍方法とダンプ参照方法。
# ls -l vmcore
-r-------- 1 root root 922628641 Dec  5 11:50 vmcore.lzo

# file vmcore 
vmcore: lzop compressed data - version 1.020, LZO1X-1, os: Unix

# mv vmcore vmcore.lzo

# lzop -d vmcore.lzo 

# ls -l vmcore
-r-------- 1 root root 4122392804 Dec  5 11:50 vmcore

# crash /boot/System.map-2.6.18-194.el5 /usr/lib/debug/lib/modules/2.6.18-194.el5/vmlinux vmcore

  SYSTEM MAP: /boot/System.map-2.6.18-194.el5                          
DEBUG KERNEL: /usr/lib/debug/lib/modules/2.6.18-194.el5/vmlinux (2.6.18-194.el5)
    DUMPFILE: vmcore
        CPUS: 2
        DATE: Sun Dec  5 11:49:50 2010
      UPTIME: 00:43:27
LOAD AVERAGE: 2.03, 1.71, 1.33
       TASKS: 144
    NODENAME: my39
     RELEASE: 2.6.18-194.el5
     VERSION: #1 SMP Fri Apr 2 14:58:14 EDT 2010
     MACHINE: x86_64  (1196 Mhz)
      MEMORY: 3.9 GB
       PANIC: "SysRq : Trigger a crashdump"
         PID: 7544
     COMMAND: "bash"
        TASK: ffff81011dbf7040  [THREAD_INFO: ffff81010fdf2000]
         CPU: 1
       STATE: TASK_RUNNING (SYSRQ)

crash> 
次に同じマシンで makedumpfile -c -d 1 で採取したダンプの情報です。こちらの場合は、圧縮したまま crash に渡すことができます。
# ls -l vmcore 
-rw------- 1 root root 848124021 Dec  5 12:03 vmcore

# file vmcore 
vmcore: data

# crash /boot/System.map-2.6.18-194.el5 /usr/lib/debug/lib/modules/2.6.18-194.el5/vmlinux vmcore

  SYSTEM MAP: /boot/System.map-2.6.18-194.el5                          
DEBUG KERNEL: /usr/lib/debug/lib/modules/2.6.18-194.el5/vmlinux (2.6.18-194.el5)
    DUMPFILE: vmcore  [PARTIAL DUMP]
        CPUS: 2
        DATE: Sun Dec  5 11:56:53 2010
      UPTIME: 00:04:52
LOAD AVERAGE: 0.23, 0.29, 0.13
       TASKS: 144
    NODENAME: my39
     RELEASE: 2.6.18-194.el5
     VERSION: #1 SMP Fri Apr 2 14:58:14 EDT 2010
     MACHINE: x86_64  (1197 Mhz)
      MEMORY: 3.9 GB
       PANIC: "SysRq : Trigger a crashdump"
         PID: 6310
     COMMAND: "bash"
        TASK: ffff8101371d07e0  [THREAD_INFO: ffff81013ad80000]
         CPU: 1
       STATE: TASK_RUNNING (SYSRQ)

crash> help -n | grep dump_level
          dump_level: 1 (0x1) (DUMP_EXCLUDE_ZERO)
lzop で採取した場合と、makedumpfile -c -d 1 で採取した場合のデータを整理すると、次のようになります。

■ lzop で採取した場合
ダンプ採取所要時間:1分22秒(kdump_post を使ってタイムスタンプを記録して測定)
ダンプファイルサイズ:922628641

■ makedumpfile -c -d 1 で採取した場合
ダンプ採取所要時間:6分34秒(kdump_post を使ってタイムスタンプを記録して測定)
ダンプファイルサイズ:848124021

このように、ダンプファイルサイズが少し大きくなる程度で、ダンプ採取時間が大幅に短縮(=ダウンタイムが大幅に短縮)でき、LZO の威力(高速圧縮性能)が発揮された結果となりました。 最後になりましたが、実験は、ThinkPad X300 メモリ4GB + CentOS 5.5 x86_64 で行いました。環境情報を示します。
# uversion 
CentOS release 5.5                      647818J

BIOS version  : 7TET36WW (1.10 )  05/11/2009
System serial : xxxxxxx

CPU model  : Intel(R) Core(TM)2 Duo CPU     L7100  @ 1.20GHz
Processors : 2  (1 sockets, 2 cores per CPU, HT: not supported or disabled)

Memory : 3780 MB

Linux : 2.6.18-194.el5  x86_64  (my39)

この環境で、システム起動直後にテストデータ(Webサーバを想定してテキストデータ)でキャッシュを満タンにした状態でダンプ採取して、比較しました。

2011-06-19追記
dumpコマンドのLZO圧縮オプション
よければ、こちらも、参照ください。

2011-06-26追記
EPEL というのがあることを知り、確かめてみたら、lzop も入ってました。
http://download.fedora.redhat.com/pub/epel/5/

2012-11-25追記
64bit版の CentOS 6 または RHEL6 であれば、lzop が収録されています。

2013-12-07追記
CentOS 6.5 で、makedumpfile (kexec-tools パッケージに収録) に -l オプション (LZO 圧縮サポート) が追加されましたので、上のような小細工は必要なくなりました。同時に Snappy のサポート (-p オプション) も追加されています。どちらが効果的かは、サーバの使い方によるかと思います。
人気ブログランキングへ にほんブログ村 IT技術ブログへ