Top > Linux > lsyncd ローカルファイルによるミラーリング
lsyncd を使ったファイルのミラーリング・バックアップ
lsyncd とは Live SYNCing (Mirror) Daemon の略である。≒ そこそこリアルタイムにファイルをミラーすることができるデーモンである。
設定とソフトウェアの構成次第でリモートマシンへのミラーも可能。
lsyncd を使用するには Linux の kernel 2.6.13(2005 年公開) で組み込まれた inotify が必要。
inotify とはディレクトリまたはファイルの粒度でファイルがオープン(読み取り専用/書き込み可能のオープンの判別可能)されたことやファイルの追加、変更、削除をイベントとして監視することができる API である。
lsyncd のインストール
カーネルのリリース番号の確認 CentOS 7 64bit における実行例
# uname -r
3.10.0-514.16.1.el7.x86_64
例えば EPEL のリポジトリ を登録していれば
# yum -y install lsyncd
にて完了
バグなどの理由で最新版を使いたいのであれば GitHub の https://github.com/axkibe/lsyncd
から取得できる。2017-06-01 時点で ver. 2.2.2 ( CentOS 7 の yum (epel) で入手できるバージョンも同じ )
注意
lsync 2.2.1 から rsync を使用する場合に送信、受信双方で 3.1 以上(含む) のバージョンが必要と記載されている。
CentOS 7 のお手軽インストールだと rsync は 3.0.9 がインストールされているので別途準備する必要がある。(2017-06-01 時点)
CentOS 7.3 + rsync 3.0.9 でも以下の簡単なサンプルでお試しした程度では動いてるっぽいが不具合時の影響を考えると素直にインストールしておくべきですね。
conf ファイルの編集 (Layer4 / Layer3)
以下のファイルの同期を行なう場合の設定ファイルを作成する
- ディレクトリ /tmp/src 以下のファイルの変更を /tmp/dest に伝播させる
- ディレクトリ /tmp/my_html 以下のファイルの変更を /tmp/my_cache の関連ファイル削除に置換して伝播させる
記述する方式には Layer 1 から Layer 4 まであり Layer1 が一番低レベルのハンドリングが可能。
Layer4 は一番お手軽ということになる。
/usr/share/doc/lsyncd-2.2.2/examples/lrsync.lua を参考に設定ファイルを作成する。
(lsyncd-2.2.2 の場合)
# cp -p /usr/share/doc/lsyncd-2.2.2/examples/lrsync.lua /etc/lsyncd.conf
# vi /etc/lsyncd.conf
----
-- User configuration file for lsyncd.
--
-- Simple example for default rsync.
--
-- 2.1 より前?の設定を持ち込むと起動しない場合があるので注意
-- settings = {
-- ... Warn: settings = { ... } is deprecated.
-- rsyncOps={"-rptgo", "--links", "--delete"},
-- ... Parameter "rsyncOps" unknown. (if this is not a typo add it to checkgauge)
--
--
settings {
logfile = "/var/log/lsyncd.log",
statusFile = "/tmp/lsyncd.stat",
statusInterval = 3,
}
-- sync セクション #1 / rsync 連携 (layer4)
-- rsync を /usr/local/bin に別途用意した場合を想定
-- binary="/usr/local/bin/rsync"
--
-- 以前の書式 rsyncOpt={"-rlptgo", "--delete"} を想定
-- -r サブディレクトリを含める / -p パーミッションの複製
-- -t タイムスタンプの複製 / -g グループの複製
-- -o 所有者の複製
-- --l シンボリックをシンボリックリンクとして複製
-- --delete 同期先だけにファイルがある場合は同期先ファイルを削除
sync{
default.rsync,
source="/tmp/src/",
target="/tmp/dest/",
rsync={
binary="/usr/local/bin/rsync",
links=false,
times=false,
_extra = {"-lptgo"}
},
}
-- sync セクション #2 / bash -c 連携 (layer3)
--
-- /tmp/my_html の file.html が変更されたら /tmp/my_cache の file.cache を削除する
my_bash = {
delay = 0,
maxProcesses = 1,
onModify = 'f="^targetPathname"; /bin/rm -f "${f%.html}.cache"',
onDelete = 'f="^targetPathname"; /bin/rm -f "${f%.html}.cache"',
}
sync {
my_bash,
source="/tmp/my_html",
target="/tmp/my_cache",
}
rsync へのオプションで引数を直接記述する rsyncOps は廃止されているが _extra パラメータで設定可能
このサンプル内のオプションはすべて _extra に寄せている。
sync{} #1 内の links=false; と times=false; は lsyncd がデフォルトで true に設定しているものを無効化して _extra= のオプションとの競合(併記)を排除している。
また、 -r と --delete は設定ファイルからは変更できないオプションとして予め組み込まれている。
Layer4 の詳細については Config Layer 4: Default Config
で調べてください。
複数の同期したいものがある場合 sync {...} を並べて記述すればよい。
rsync へのオプションは 1 つずつに分けてダブルクォートで囲んで指定する。スペースを入れて複数個同時に指定したときは動作しなかった。
default.rsync のデフォルト設定値
lsyncd.conf の default.rsync (※1) で使用される rsync の設定は
rsync -ltsd --delete --include-from=- --exclude=* SOURCE TARGET
相当と書かれているが、-log all で出力されるログの内容からみると
rsync -slt -r --delete --ignore-errors --force --from0 --include-from=- --exclude=* SOURCE TARGET
が現在の設定と思われる。(v.2.2.2 / 2017-06-01 時点)
man rsync から抜粋
- [-slt] no space-splitting / copy symlinks as symlinks / preserve modification times
- [-r] recurse into directories
- [--delete] delete extraneous files from destination dirs
- [--ignore-errors] delete even if there are I/O errors
- [--force] force deletion of directories even if not empty
- [--from0] all *-from/filter files are delimited by 0s (補足 0s = \0 , NULLのこと)
- [--include-from=-] read include patterns from FILE (補足 '-' なので lsyncd から入力される)
- [--exclude=*] exclude files matching PATTERN (補足 '*' なので lsyncd から入力されたパターン以外は除外)
(※1) lsyncd.conf ファイル中の記述で sync { default.rsync, source ="/tmp ... } の default.rsync の部分のこと
default.rsync に該当する部分は LUA という言語で記述し conf ファイルに組み込むことが可能
⇒ 参考 lsyncd に細かいプログラムを組み込む例
Cent OS 6
lsyncd 起動スクリプト
起動スクリプトは多重起動防止やロックファイルを作成しておかないと異常動作の原因になることがあるので要注意。
コメント内の # chkconfig: - 80 20 によって起動と停止順番を定義する。80 は httpd(85) より少し前に START され、リブートやシャットダウン時には httpd(15) より少し後に STOP させたい場合の例である。番号は自分の目的に合わせて適当に設定する。
# vi /etc/init.d/lsyncd
#!/bin/bash
# chkconfig: - 80 20
# description: lsyncd
RETVAL=0
prog="/usr/bin/lsyncd"
pidfile="/var/run/lsyncd.pid"
lockfile="/var/lock/subsys/lsyncd"
option="-pidfile $pidfile"
# option="-log all -pidfile $pidfile"
conffile="/etc/lsyncd.conf"
. /etc/rc.d/init.d/functions
start() {
echo -n "Starting $prog:"
daemon --pidfile=$pidfile $prog $option $conffile
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch $lockfile
return $RETVAL
}
stop() {
echo -n "Stopping $prog:"
killproc -p $pidfile $prog
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f $lockfile $pidfile
return $RETVAL
}
case $1 in
start) start ;;
stop) stop ;;
restart) stop && start ;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
# option="-log all" は設定が上手くいかないときにコメントアウトする。大量のログが出るので通常時は使用しない方が良い。
lsyncd を自動起動 / 停止させる
起動スクリプトを登録 rc3.d , rc6.d や rc0.d などにエントリされる 参考: ランレベル
# chmod +x /etc/init.d/lsyncd
# chkconfig --add lsyncd
# chkconfig lsyncd on
# chkconfig --del lsyncd
lsyncd の起動
マシンを再起動して設定できているか確認、または、service コマンドで直接起動する。
# service lsyncd start
Starting /usr/bin/lsyncd: [ OK ]
2回目は [OK] がでないことを確認 = 多重起動されていない。
同じ監視をする設定で lsyncd が多重起動されてしまうと更新ファイルを同期できない原因になる。
設定に誤りがあったりするとログファイルが延々と大量に出力され続けることがあるので念のため確認する。
# tail -f /var/log/lsyncd.log
CentOS 7
lsyncd を自動起動 / 停止させる
# systemctl enable lsyncd
Created symlink from /etc/systemd/system/multi-user …………
# systemctl disable lsyncd
Removed symlink /etc/systemd/system/multi-user.tar …………
lsyncd の起動
起動と確認例
# systemctl start lsyncd
... 出力はなにもない
# systemctl status lsyncd
● lsyncd.service - Live Syncing (Mirror) Daemon
Loaded: loaded (/usr/lib/systemd/system/lsyncd.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2017-06-01 00:00:00 JST; 10s ago
Main PID: 73070 (lsyncd)
CGroup: /system.slice/lsyncd.service
└─73070 /usr/bin/lsyncd -nodaemon /etc/lsyncd.conf
ミラーするファイルを指定する方法
lsyncd の除外設定は rsync のinclude / exclude の設定に似ているが + や - による設定は行えない。つまり、除外のみしか行なうことができない。
そのため lsyncd の除外リストと rsync の許可リストと除外リストを併用して記述することでファイルの選別を実現する。
lsyncd の除外リストは必須ではないが、ミラーしないファイルが変更されても lsyncd でイベントが発生し rsync で何もしないという不毛な処理が発生するのはもったいない。
指定したディレクトリを除外し、特定のファイルだけミラーをしたい場合の設定
ミラーの条件例
- /tmp/src3/subdir , /tmp/src3/subdireX をミラーから除外
- hoge.txt のみをミラーする。それ以外はすべて除外する
以上の条件でミラーするときの conf ファイル記述例
sync{
default.rsync,
source="/tmp/src3/",
target="/tmp/dest3/",
exclude={"/subdir/", "/subdirX/"},
-- exclude="/subdir**", ワイルドカードによる指定も可能
-- exclude="/*/", サブディレクトリすべて
-- exclude={"*.log", "/*/"}, ファイル名にも指定可能
rsync={
binary="/usr/local/bin/rsync",
links=false,
times=false,
_extra = {"-lptgo"}
},
}
使用できるワイルドカードは
- ? - スラッシュ(/) を除く任意の 1 文字にマッチ
- * - スラッシュ(/) を除く任意の 0 文字以上にマッチ
- ** - スラッシュ(/) を含む任意の 0 文字以上にマッチ
lsyncd の exclude を外部ファイルで指定する場合には "excludeFrom=ファイル名" を使用して宣言する。
外部ファイルで指定する場合には + による include 設定は機能しない。'/' で終了している場合には除外ディレクトリと判定される。
(注意) 除外するパターンマッチについて
exclude="log"
の除外指定を行なうと log(ファイル) , /log/ (ディレクトリ)が除外対象となる。
つまり /abc/log/ はマッチするので除外対象となるが /login/ は除外対象にはならない。
関連カーネルパラメータ
inotify で監視できるファイル数の上限に関するパラメータ
監視対象を一気に増やしたときなどには上限を超えていないか確認する。
- /proc/sys/fs/inotify/max_queued_events
- /proc/sys/fs/inotify/max_user_instances
- /proc/sys/fs/inotify/max_user_watches ← 特にコレ
lsyncd による同期の体感スピード
同一ファイルに対して絶え間なく連続して変更を加えると伝播は遅延するし、単純な追加、変更、削除であってもリアルタイムに同期されるのではなく一呼吸おいて同期されるという感じなので過剰な期待はしてはいけない。