rsyncとlsyncdでリアルタイムにディレクトリを同期する

· 2 min read
rsyncとlsyncdでリアルタイムにディレクトリを同期する

差分を算出してファイルやディレクトリを同期してくれる rsync と
ローカルファイルへの変更を監視してくれる lsyncd を組み合わせることで
リアルタイムにディレクトリを同期することができます。

lsyncd と rsync を連動する方法は二つあります。

  • SSH を通して rsync 同士が通信する方法
  • バックアップ先で rsync デーモンを動かす方法

rsync をデーモンモードで動作させることで、
rsync プロトコル(rsync://)による同期が可能になり、
SSH を利用する場合より暗号化によるオーバーヘッドがなく高速で同期することができます。


前提環境

ホストOS IPアドレス 同期対象ディレクトリ
マスター CentOS 6.8 10.0.0.6 /var/www/html/
スレーブ CentOS 6.8 10.0.0.7 /var/www/html/

同期対象のディレクトリは Apache のデフォルトのドキュメントルートを指定するので、
あらかじめ Apache のインストールも必要になります。


lsyncd + rsync のインストール

マスター側には lsyncd / rsync、スレーブ側には rsync をインストールします。

\マスター側
# yum -y install lsyncd
# yum -y install rsync

\スレーブ側
# yum -y install xinetd
# yum -y install rsync

これでインストールは完了です。


lsyncd の設定 [マスター側]

lsyncd.conf を設定します。
/etc/lsyncd.conf に下記を追記します。

# vi /etc/lsyncd.conf

settings{
    logfile = "/var/log/lsyncd.log",
    statusFile = "/tmp/lsyncd.stat",
    statusInterval = 1,
}
sync{
    default.rsync,
    source="/var/www/html/",
    target="10.0.0.7::sync",
    rsync = {
        _extra = { "-a" },
    }
}

ざっくり解説すると、settings でログやステータスの出力先を設定し、
sync セクションで同期元ディレクトリ(source)と同期先(target)を指定します。

同期先の target にある ::syncsyncモジュール名 で、
このあと設定する スレーブ側 rsyncd.conf のモジュール名 と一致していれば OK です。


lsyncd の起動 [マスター側]

自動起動の設定をして…

# chkconfig lsyncd on

lsyncd を起動します。(この時点ではスレーブ側の設定がまだなら、起動に失敗する場合があります)

# /etc/rc.d/init.d/lsyncd start

rsync の設定 [スレーブ側]

スレーブ側の設定は xinetdrsyncd の 2 つです。
まず xinetd の設定ファイルを編集します。

# vi /etc/xinetd.d/rsync

service rsync
{
    disable     = no    # yes から no に変更
    flags       = IPv6
    socket_type = stream
    wait        = no
    user        = root
    server      = /usr/bin/rsync
    server_args = --daemon
    log_on_failure += USERID
}

user は root 以外にしても構いませんが、ここでは簡単のため root のままにしています。

xinetd を自動起動にして起動します。

# chkconfig xinetd on
# service xinetd start

rsyncd.conf の設定 [スレーブ側]

スレーブ側の rsyncd.conf を設定します。
(xinetd に叩かれたときの rsync デーモンの挙動になります)

# vi /etc/rsyncd.conf

# マスター側 lsyncd.conf 内の target と同じモジュール名にする
[sync]
    # コピー先対象ディレクトリ
    path        = /var/www/html/
    hosts allow = localhost 10.0.0.6
    list        = true
    uid         = root
    gid         = root
    read only   = false
    port        = 873

ポイントは [sync] の部分で、これがリアルタイム同期の モジュール になります。
マスター側 target="10.0.0.7::sync"sync がここです。

ここで同期先ディレクトリ・許可するホスト・ポート番号などを設定します。


マスター側の lsyncd を起動する

順番が前後している場合は、もう一度 lsyncd を起動しておきます。
(本来はスレーブ側設定 → マスター側設定の順番が望ましいです)

# /etc/rc.d/init.d/lsyncd start

ここまでできたら大筋完成です。

  • スレーブ側で xinetd が待機して rsync --daemon を起動できる状態にする
  • マスター側 lsyncd が差分検知 → rsync で送信
  • スレーブ側の xinetd がそれを受けて rsyncd に渡す

という流れになります。

ログも確認してみましょう。

# less /var/log/lsyncd.log

Mon May  1 00:31:17 2017 Normal: recursive startup rsync: /var/www/html/ -> 10.0.0.7::sync/
Mon May  1 00:31:22 2017 Normal: Startup of "/var/www/html/" finished.
Mon May  1 00:32:12 2017 Normal: Calling rsync with filter-list of new/modified files/dirs

ログにきちんと出ていれば OK です。
試しにマスター側で test ファイルを生成すると、スレーブ側にも自動で同期されるはずです。


※余談
スレーブ側のファイルを手動でいじるとどうなるか? という疑問もあると思いますが、
かなりおかしな状態になる可能性が高いので、基本は「スレーブは触らない」 運用がおすすめです。
(いろいろ工夫したい場合は、競合時のポリシーなどを含めて別途調査したほうがよいです)