lsyncdを使ったディレクトリ同期の制限について

こんばんは、牧野です。
最近、急に涼しくなりましたね。おかげで、自転車通勤がかなり快適になりうれしいです。

さて、今日はサーバ間でディレクトリを同期させるのに便利な、lsyncdについてです。
アシアルではいくつかのシステムでlsyncdを使っています。
大量のファイルの同期が必要そうなシステムが出てきたため、lsyncdの制限について検証してみました。
lsyncdで問題となりそうなパラメータが、inotifyのmax_user_watchesです。
参考にしたのは、こちらのブログです。
lsyncdの設定については、以前熊谷がブログを書いていますので、こちらもご覧下さい。

今回の検証環境は、vmwareのdebianサーバ2台です。
サーバ1ではlsyncdを、サーバ2でrsyncをデーモンで動かします。

/etc/lsyncd.xml.conf


<lsyncd version="1">
  <settings>
    <logfile filename="/var/log/lsyncd.log"/>
    <binary filename="/usr/bin/rsync"/>
    <pidfile filename="/var/run/lsyncd.pid"/>
    <callopts>
      <option text="-%rlptgoD"/>
      <option text="--delete" />
      <exclude-file/>
      <source/>
      <destination/>
    </callopts>
  </settings>
  <directory>
    <source path="/data/backup1/"/>
    <target path="192.168.137.13::backup1"/>
  </directory>
</lsyncd>

/etc/rsyncd.conf


uid = root
gid = root
log file = /var/log/rsyncd.log
pid file = /var/log/rsyncd.pid
[backup1]
        comment = rsync backup1
        path = /data/backup1
        hosts allow = 192.168.137.12/32
        read only = false

上のように同期設定をし、サーバ1で大量のファイル、ディレクトリを作成するプログラムを実行、正常に同期されるか確認します。
デフォルトではmax_user_watchesの値は、8192になっていますので、実験用に小さくします。今回は100にしました。

/etc/sysctl.confに


fs.inotify.max_user_watches = 100

を追加して、rootで


/sbin/sysctl -p

を実行します。

lsyncd_test.php


<?php
$base_dir = '/data/backup1';
if (!is_dir($base_dir)) {
  exec('mkdir -p '. $base_dir);
  exec('chmod 777 '. $base_dir);
}
//合計1000個のファイルを作成する。
$file_num = 1000;
//ファイル5個ごとにディレクトリを作成する。
$num_per_dir = 5;
for ($i = 0; $i < $file_num; $i++) {
  if ($i % $num_per_dir == 0) {
    $sub_dir = $base_dir .'/'. sprintf('%05d', intval($i / $num_per_dir));
    if (!is_dir($sub_dir)) {
      exec('mkdir -p '. $sub_dir);
      exec('chmod 777 '. $sub_dir);
    }
  }
  exec("touch {$sub_dir}/". sprintf('%05d', $i));
}

lsyncd_test.phpを実行すると、/data/backup1内に、200個のディレクトリ、各ディレクトリに5個のファイル、合計1000個のファイルが作成されます。

lsyncd_test.phpを実行して、サーバ2で/data/backup1を確認すると、

ディレクトリは/data/backup1を含め、201個ありますが、ファイルは485個で止まっています。

ファイルを確認すると、

00000~00096のディレクトリのファイルまでは同期されていることがわかります。
/var/log/lsyncd.logを見ると、

00097から以後で、ディレクトリを監視対象に追加しようとしてエラーが発生していました。
このように、max_user_watchesの値は自動同期できるディレクトリ数に関係していることが確認できました。
lsyncdを使う場合でディレクトリ数が多くなりそうな時は、パラメータの値に気をつけて下さい。