lsyncd(Live Syncing Daemon)はリアルタイムのファイル同期を提供する仕組みのひとつです。inotifyというファイルの変更を検知すると、rsyncd経由で同期先のサーバへファイルを転送します。このページでは、lsyncd, rsyncdの使い方についてまとめます。
lsyncd 概要
lsyncdの動向
lsyncdは、2009年7月のソフトウェアデザインに掲載されてから徐々に有名になった技術ですが、現在(2014年10月)ではわりと下火になってきました。GitHubを見ると最近のコミットの数が少ないし、新しいバージョンの開発が行われていません。私自身もlsyncdはかなり痛い目にあったオープンソースなので、正直お勧めできません。とは言っても、lsyncdを運用せざるを得ない残念な方もいらっしゃると思いますので、そんな残念なOpsのためにまとめ記事を書きます。
lsyncdのバージョン
lsyncdにはバージョン1とバージョン2があります。ソフトウェアデザインに掲載されたのがバージョン1であった影響もあり、バージョン1を前提としてたブログが多数みられます。他のブログ記事を読む時は、その記事がバージョン1なのかバージョン2なのかを慎重に読み取った方が良いでしょう。
なお、このサイトはバージョン2のみを取り扱います。バージョン1は、もはや公式サイトからダウンロードする事すらできなくなっています。
lsyncd vs DRBD
lsyncdと比較される概念として、DRBDのようなクラスタリングソフトウェアが挙げられます。両者の違いは以下の通りです。
lsyncd | DRBD | |
---|---|---|
転送単位 | ファイル単位 | ブロック単位 |
同期対象数 | 多数 20台以上の運用実績あり | 多くの場合は2台体制, 最大4台まで可能 |
手間 | すぐに構築可能 | ファイルシステムの再構成やマウントポイントの定義が必要 |
主な用途 | 少量のファイル同期 | データベースのクラスタリング |
lsyncdはファイル単位の転送であるのに対し、DRBDはブロック単位の転送です。DRBDはブロック単位の転送を行うため、ファイルシステムの再構築やマウントポイントの定義など構築の手間が非常に大きいです。それに対し、lsyncdは比較的容易に導入する事ができます。
lsyncdは多数のホストに対して同期を効かせる事ができるのに対し、DRBDは2台のホストを同期させる用途で使用する事が多いです。多数のホストに対して同期を行いたい場合は、lsyncdを採用しましょう。
結論としては、「データベースの同期にはDRBD, GlusterFS, BindFSのようなクラスタリングソフトを使用し、少量のファイル転送にはlsyncdを使用する」と覚えておけば、原則間違えはないと思います。
rsyncコマンド
rsyncコマンドの使い方
lsyncdはリアルタイムでrsyncを行う常駐プログラムです。lsyncdを設定する前に、まずはrsyncコマンドの復習をしておきましょう。
rsyncはディレクトリ単位の同期を行うコマンドです。同一ホスト内のファイルコピーを行う事もできますが、多くの場合はリモートホストへのファイル転送で使用する事が多いでしょう。さて、rsyncの構文は以下のようになります。
# rsync <option> <source_dir> <user>@<host>:<directory> # rsync <option> <user>@<host>:<directory> <target_dir>
使用頻度が高いオプションをまとめると以下の通りです。
オプション | 説明 |
---|---|
-a | -rlptgoDと同じ意味です。詳細な説明はマニュアルに任せますが、-aをつけた方が何かと便利な事が多いです。 |
-v | 転送するファイル一覧を表示します。 |
-e | リモートシェルのコマンドを指定します(デフォルトはssh)。例えば、"ssh -p 1022"とすればポート番号を変更できますし、"ssh -i secret.pem"とすれば秘密鍵を指定できます。 |
--progress | ファイル転送の進捗を表示します。大きなファイルを転送する進捗が見えないと何かと不安になります。私の精神安定剤。 |
--exclude | 転送対象から除外したいファイルを指定します。 |
--exclude-from | 転送対象から除外したいファイル一覧を定義した設定ファイルを指定します。 |
--dry-run | -vと併用する事で、実際には転送せずに転送するファイル一覧を表示します。オプション指定やディレクトリ指定に誤りがないか、事前に動作確認したい時に使用します。 |
使用例は以下の通りです。
[rsync@localhost ~]$ rsync -av -e "ssh -p 12272" --dry-run /usr/local/manage/ rsync@www41375u.sakura.ne.jp:/usr/local/manage/ building file list ... done ./ env/ mrtg/ mrtg/alert_ssh.sh mrtg/tmp.txt rsync/ rsync/www_exclude.lst snmpd/ sent 261 bytes received 68 bytes 219.33 bytes/sec total size is 267 speedup is 0.81 [rsync@localhost ~]$
rsyncコマンド –exclude
–excludeオプションで転送対象から除外したいファイルを定義する事ができます。ディレクトリ単位で除外したい場合は、コピー元ディレクトからの相対パスで指定します。特定のファイルを除外したい場合は、ワイルドカードと範囲指定でファイル名を指定します(例えば、”*.log.[0-9]”のように指定します。正規表現は使用できません)。
使用例は以下の通りです。”not_sync”ディレクトリとログファイルを除外して転送する例です。
[rsync@localhost ~]$ rsync -av --exclude="not_sync" --exclude="*.log" --exclude="*.[0-9]" --dry-run /usr/local/Workdir rsync@www41375u.sakura. ne.jp:/usr/local/Workdir/ building file list ... done Workdir/ Workdir/test.txt sent 114 bytes received 32 bytes 292.00 bytes/sec total size is 5 speedup is 0.03 [rsync@localhost ~]$
rsyncコマンド –exclude-from
rsyncの除外対象が多くなると、除外対象をコマンドラインで指定するのはメンテナンス上無理があります。そのような場合は、除外対象をファイルで定義する事もできます。
実行例は以下の通りです。
[rsync@localhost ~]$ cat workdir_exclude.lst - not_sync - *.log - *.[0-9] [rsync@localhost ~]$ [rsync@localhost ~]$ [rsync@localhost ~]$ [rsync@localhost ~]$ [rsync@localhost ~]$ rsync -av -e "ssh -p 12272" --exclude-from=/home/rsync/workdir_exclude.lst --dry-run /usr/local/Workdir rsync@www41375u.sakura.ne.jp:/usr/local/Workdir/ building file list ... done Workdir/ Workdir/test.txt sent 114 bytes received 32 bytes 292.00 bytes/sec total size is 5 speedup is 0.03 [rsync@localhost ~]$
設定例は示しませんが、”+”で除外リストから除く(転送対象に含める)事もできます。”+”でincludeの意味、”-“でexcludeの意味と考えて差し支えございません。
なお、机上で–exclude指定を考えるのは設定ミスをしやすいので、実行前に–dry-runオプションで動作確認する事をお勧めします。
rsyncd (ファイル受信側の設定)
rsyncd, lsyncdによるリアルタイムの同期を実現するためには、ファイルを受信する側のサーバでrsyncdを起動させる必要があります。
このrsyncdという言葉は聞きなれないと思いますが、rsyncとは別物です。多くのエンジニアはrsyncと言えばsshでディレクトリ単位のコピーを行うコマンドを思い浮かべますが、rsyncdはtcp873で待ち受けるファイル同期のための常駐プログラムです。
rsyncdの起動 [必須]
rsyncdはxinetd経由で呼び出されるます。もしxintedがインストールされていない場合は、xinetdをインストールして下さい。
# yum install xinetd # chkconfig xinetd on # /etc/init.d/xinetd start
rsyncdはデフォルトで無効化されていますので、/etc/xinetd.d/rsyncの”disable”をyesからnoに変更しrsyncdを有効化します。 また、CentOS6からはデフォルトでIPv6でのみ受信する設定になっていますので、”flags”をIPv6からIPv4に変更します。
# default: off # description: The rsync server is a good addition to an ftp server, as it \ # allows crc checksumming etc. service rsync { disable = no flags = IPv4 socket_type = stream wait = no user = root server = /usr/bin/rsync server_args = --daemon log_on_failure += USERID }
xinet.dを再起動し設定を反映させます。設定反映後、IPv4 tcp873でListenしている事を確認します。”0 0.0.0.0:873″との記述がある事を確認してください。もし、”:::873″となっていればIPv6で受信している事を意味しますので、設定の見直しが必要です。
# /etc/init.d/xinetd restart # netstat -ano | grep 873 tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN off (0.00/0/0) #
環境によっては、iptablesやhosts.allowのような受信許可設定も必要になる事にもご注意ください。/etc/sysconfig/iptablesの設定変更が必要ならば、以下のような設定例になります。
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 873 -j ACCEPT
rsyncd.conf ディレクトリの設定 [必須]
rsyncdの設定を行います。設定は、/etc/rsyncd.confに記述して下さい。以下は、/usr/local/Workdirに対して”Workdir”というラベルを付与する例です。
[Workdir] path = /usr/local/Workdir comment = work directory hosts allow = XX.XX.XX.XX/YY hosts deny = * read only = no uid = root gid = root
hosts allow, hosts denyはrsyncdによって接続したいホストを限定したい場合に指定して下さい。特に要件がないならば、設定の必要はございません。
read onlyは書き込みを許すかどうかです。rsyndは公開サーバとしての用途もありますので、デフォルト設定は読取専用です。しかし、lsyncdで使用する場合は書き込み操作が必要になるので、”read only = no”としましょう。
uid, gidは同期ディレクトリに対して読み書きを行うユーザです。恐らく全てのファイルを同期したい場合が大半と思われますので、”uid = root”, “gid = root”とするのが良いでしょう。ちなみに、この設定を省略してしまうとnobodyで読み書きが行われます。
rsyncd.conf 複数ディレクトリの指定 [任意]
複数のディレクトリに対してrsyncdによる同期を行う事もできます。以下は、/usr/local/Workdir, /usr/local/Workdir2の2つのディレクトリに対してrsyncdによる同期を許可した設定です。
ディレクトリを複数指定する場合は、以下のようにグローバルな設定を利用し設定ファイルの簡素化を図りましょう。ディレクトリ設定より前に設定を記述すると、全てのディレクトリに対する共有設定になります。以下は、read only=no, uid=root, gid=rootを共通設定として記載した例です。
## Global Settings read only = no uid = root gid = root [Workdir] path = /usr/local/Workdir [Workdir2] path = /usr/local/Workdir2
rsyncd.conf ログ設定 [任意]
rsyncdはデフォルトで/var/log/messagesに同期を行ったディレクトリをログ出力します。ログ出力例は以下の通りです。
[root@localhost ~]# tail -f /var/log/messages Oct 18 16:38:01 localhost rsyncd[32547]: dbus-1/system.d/ Oct 18 16:38:01 localhost rsyncd[32547]: default/ Oct 18 16:38:01 localhost rsyncd[32547]: depmod.d/ Oct 18 16:38:01 localhost rsyncd[32547]: dhcp/ Oct 18 16:38:01 localhost rsyncd[32547]: dhcp/dhclient.d/ Oct 18 16:38:01 localhost rsyncd[32547]: dnsmasq.d/ Oct 18 16:38:01 localhost rsyncd[32547]: dracut.conf.d/ Oct 18 16:38:01 localhost rsyncd[32547]: elasticsearch/ Oct 18 16:38:01 localhost rsyslogd-2177: imuxsock begins to drop messages from pid 32547 due to rate-limiting Oct 18 16:38:05 localhost xinetd[32543]: EXIT: rsync status=0 pid=32547 duration=5(sec)
もし、大量のログ出力を嫌うならば、ログ出力を抑制する事ができます。/etc/rsyncd.confに”transfer logging = no”を加筆する事でログ出力を抑制する事ができます。
ただし、私がかつて運用を行っていた現場は非常にrsyncd, lsyncdのトラブルが多かったです。ログを抑制するという事は、後からの追跡ができなくなるデメリットがある事は理解した上で設定を投入して下さい。
read only = no uid = root gid = root transfer logging = no [Workdir] path = /usr/local/Workdir
rsyncdを大量に使用する現場では、rsyncdのログが膨大になってしまいます。これを/var/log/messagesに出力すると、OSに対するエラーが埋もれてしまう可能性があります。
そのような場合は、rsyncdのログ出力を別ファイル化する事を検討しましょう。rsyncdはデフォルトで、syslog facilityのdaemonに対してログ出力します。これを何か適当なfacilityに変更する事で、ログ出力の別ファイル化ができます。
/etc/rsyncd.confに”syslog facility”を加筆し、ログ出力先を指定して下さい。以下はlocal0にrsyncdのログを出力する例です。
read only = no uid = root gid = root transfer logging = yes syslog facility = local0 [Workdir] path = /usr/local/Workdir
あとは、rsyslogdとログローテーションの設定をすれば、ログ関連の設定が完了です。
rsyslogdの詳細説明はrsyslogd (syslogd) 設定に任せ、ここでは設定例のみ紹介します。/etc/rsyslog.confに以下ハイライトされた部分の設定を加筆します。
# Everybody gets emergency messages *.emerg * # Save news errors of level crit and higher in a special file. uucp,news.crit /var/log/spooler # Save boot messages also to boot.log local7.* /var/log/boot.log # Save boot rsyncd also to rsyncd.log local0.* /var/log/rsync # ### begin forwarding rule ###
rsyslogdを再起動し設定を反映させます。
# /etc/init.d/rsyslog restart
みんな忘れがち、そして後任の運用担当者がよく泣くログローテーションの設定例は以下の通りです。ログローテーションの詳細説明はlogrotate 設定方法に任せ、ここでは設定例のみ紹介します。rsyncdのログはrsyslogdによって出力されるログですので、ログローテーションの際はrsyslogdに対してHUPシグナルを送って下さい(HUPシグナルを送る対象は、xinetd, rsyncdではありません)。
/etc/logrotate.d/syslogに、ログローテーション対象として/var/log/rsyncを加筆します。以下ハイライトされた部分を加筆して下さい。
/var/log/cron /var/log/maillog /var/log/messages /var/log/secure /var/log/spooler /var/log/rsync { sharedscripts postrotate /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true endscript }
lsyncd ( ファイル送信側の設定 )
lsyncdのインストール [必須]
lsyncdをインストールします。現在(2012/02/26)はrpmforgeから提供されていますので、yumコマンドで簡単にインストールできます。rpmforgeの設定については、yumリポジトリの使い方/設定/作成方法を参照下さい。
# yum install --enablerepo=rpmforge lsyncd
lsyncdの設定 [必須]
lsyncdは/etc/lsyncd.confに設定を記述します。デフォルト設定やサンプル設定のファイルは存在しないので、設定ファイルを新規作成して下さい。
設定例は以下の通りです。もし、複数のホストに対してファイル転送を行ないたい場合は、rsync { … } のエントリを増やしてください。
---- -- User configuration file. -- -- Simple example for default rsync. -- settings { logfile = "/var/log/lsyncd.log", statusFile = "/var/log/lsyncd.stat", } sync{ default.rsync, source="/usr/local/Workdir/", target="192.168.XX.XX::Workdir", }
lsyncd 起動 [必須]
lsyncdは起動スクリプトを用いて、起動させることができます。操作例は以下の通りです。
# chkconfig lsyncd on # /etc/init.d/lsyncd start
lsyncdの起動に成功してもファイル転送に成功しているとは限りません。例えば、公開鍵の設定が間違っていたとしても、psコマンド等によるプロセス確認では正常に見えます。そのため、以下のようにログを確認し正常にファイル転送できているかを確認する必要があります。
エラーがある場合はログファイルに”Retrying startup”のようなメッセージが出力され続けます。以下はエラーが存在する場合のログ出力例です。
[root@localhost ~]# tail -f /var/log/lsyncd.log Sun Feb 26 23:00:22 2012 Normal: Finished a list = 0 Sun Feb 26 23:00:35 2012 Normal: Calling rsync with filter-list of new/modified files/dirs /hoge / Sun Feb 26 23:00:35 2012 Normal: Finished a list = 0 Sun Feb 26 23:01:06 2012 Normal: --- TERM signal, fading --- Sun Feb 26 23:01:06 2012 Normal: recursive startup rsync: /var/www/ -> rsync@www41375u.sakura.ne.jp::var/www/ rsync: failed to connect to www41375u.sakura.ne.jp: Connection refused (111) rsync error: error in socket IO (code 10) at clientserver.c(107) [sender=2.6.8] Sun Feb 26 23:01:06 2012 Normal: Retrying startup of '/var/www/'. Sun Feb 26 23:01:21 2012 Normal: Calling rsync with filter-list of new/modified files/dirs rsync: failed to connect to www41375u.sakura.ne.jp: Connection refused (111) rsync error: error in socket IO (code 10) at clientserver.c(107) [sender=2.6.8] Sun Feb 26 23:01:21 2012 Normal: Retrying a list on exitcode = 10 Sun Feb 26 23:01:21 2012 Normal: Calling rsync with filter-list of new/modified files/dirs
一方、ファイル転送が正常に行なわれ射る場合は、以下のように出力されます。
[root@skr096 ~]# tail -f /var/log/lsyncd.log /4913 /hoge /hoge~ Sat Oct 18 23:07:36 2014 Normal: Finished a list after exitcode: 0 Sat Oct 18 23:07:54 2014 Normal: Calling rsync with filter-list of new/modified files/dirs /test/ / /test/hoge /test/foo Sat Oct 18 23:07:54 2014 Normal: Finished a list after exitcode: 0
lsyncd ログローテーション [必須]
ログファイルを明示的に定義した場合は、ログローテーションの設定も忘れずに行いましょう。以下はログローテーションの設定例です。/etc/logrotate.d/lsyncdというファイルを以下のような内容で作成します。
/var/log/lsyncd/*log { missingok notifempty sharedscripts postrotate /sbin/service lsyncd reload > /dev/null 2>/dev/null || true endscript }
なお、ログファイル設定を省略した場合は、facilityがuserでログ出力されます。rsyslog.conf, syslog.confの設定次第ですが、多くの場合は/var/log/messagesにログ出力されると思います。
lsyncd カーネルパラメタの変更 [必須]
lsyncdはionotifyというファイルシステムのイベントを取得するAPIを使用しています。ionotifyは監視できるファイル数の上限が定められており、max_user_watchesで定義されています。
デフォルトでは8192個までしか監視できません。もし大量のファイルを同期したい場合は、カーネルパラメータfs.inotify.max_user_watchesを変更する必要があります。/etc/sysctl.confにfs.inotify.max_user_watchesを追加します。設定例は以下の通りです。
diff --git a/sysctl.conf b/sysctl.conf index e256b03..84de03e 100644 --- a/sysctl.conf +++ b/sysctl.conf @@ -43,3 +43,6 @@ kernel.shmall = 4294967296 net.ipv6.conf.default.accept_ra=0 net.ipv6.conf.all.accept_ra=0 net.ipv6.conf.eth0.accept_ra=0 + +# lsyncd +fs.inotify.max_user_watches = 65536
”sysctl -p”により設定を反映させます。
[root@localhost ~]# /sbin/sysctl -p /etc/sysctl.conf <omitted> fs.inotify.max_user_watches = 65536 [root@localhost ~]#
Tips
rsyncd CentOS 5.X系とCentOS 6.X系の違い
この記事は2012年2月に初めて書き、2014年10月に再度見直しを行いました。2012年の時点ではCentOS 5.Xで動作確認を行い、2014年10月ではCentOS 6.5で動作確認を行っております。
その際、rsyncdの仕様変更をいくつか見つけました。注意すべき仕様変更は以下の通りです。
CentOS 5.X | CentOS 6.X | |
---|---|---|
IPv4/IPv6 | IPv4で待ち受け | デフォルト設定はIPv6で待ち受け |
設定ファイル | /etc/sysconfig/rsyncd.conf | /etc/rsyncd.conf |
lsyncd 1.X系, 2.0系, 2.1系の違い
lsyncdはバージョンによって書式や指定可能オプションが異なります。
1.X系と2.0系では設定ファイルの書式が大きく異なります。1.X系の頃はXML形式の読みづらい記述になっていましたが、2.0系では読みやすい記述方法になっています。
2.0系から2.1系からのバージョンアップでは、指定可能なオプションが異なります。2.0系の頃は以下のようにrsyncOpsというパラメタを用いて転送対象外となるファイルを定義しましたが、2.1系ではrsyncOpsというパラメタが廃止されています。
ちなみに、2.0系の頃はrsyncOpsを省略するとファイル転送が行われなくなる不具合がありました。
---- -- User configuration file. -- -- Simple example for default rsync. -- settings = { logfile = "/var/log/lsyncd.log", statusFile = "/var/log/lsyncd.stat", } sync{ default.rsync, source="/usr/local/Workdir/", target="rsync@www41375u.sakura.ne.jp::Workdir", rsyncOps={ "-a", "--exclude-from=/usr/local/manage/rsync/exclude.lst", }, }
動作確認環境
- 最終動作確認日 2014/10/19
- CentOS 6.5 64 bit
- rsync-3.0.6-9.el6_4.1.x86_64
- lsyncd-2.1.4-1.el6.rf.x86_64