rsyncほどファイルシステム同期で話に上がらない
Unison。
*nixのみならず、Windowsでも走ったりと優秀なんだけどなぁ..
ちなみに2台以上で構成する場合は、スター型( 更新系1 × 参照系1~N )が推奨されている。
けれど、スター型が保証できるコンテンツ/インフラであれば、別にスター型でなくてもいい気がする。
さっそくインストールするが、Debianなら、
apt-get install unison
と簡単。
ローカルでの利用では、
unison origin sync_dest
などとする。
リモート2拠点間では、
unison origin ssh://192.168.1.1/sync_dest
などとSSH経由が推奨されているが、
#@remote host(192.168.1.1)
unison -socket 5963
#sync from another
unison origin socket://192.168.1.1:5963/sync_dest
などとしてSOCKETモードなるデーモンモードもある。
ただし、こちらの場合はセキュリティなどの都合で非推奨。
上記手順は、あくまでも任意で同期する場合の手順で、PULL型同期となる。
このままでは実運用には耐えないので、inotifyイベント発生時に同期するよう
incron(inotifyイベントのcron的な代物)を仕組む。
Debianなら、
apt-get install incron
echo 'root' > /etc/incron.allow
incrontab -e
# origin IN_MODIFY,IN_ATTRIB,IN_CREATE,IN_DELETE,IN_CLOSE_WRITE,IN_MOVE unison -batch origin sync_dest
となどとする。
但し、inotifyイベントの指定はザックリなので、稼働状況に応じて調整する必要有り。
ちなみに、
cat /proc/sys/fs/inotify/max_user_watches
とし、出力される数値が監視対象ディレクトリ数となる。
必ず、対象ディレクトリ数を上回らないように調整すること。
これを怠ると、超過時にincronが正常動作せず同期処理が不完全に行われることがある。
これを踏まえるとリモート2拠点間構成の場合は、
incrontab -e
# origin IN_MODIFY,IN_ATTRIB,IN_CREATE,IN_DELETE,IN_CLOSE_WRITE,IN_MOVE unison -batch origin socket://192.168.1.1:5963/sync_dest
とするといい。
incron経由では環境変数などが設定されずに実行されるので、
正常動作しない場合は、
vi sync.sh
#!/bin/sh
. /etc/profile
. /etc/bash.bashrc
unison -batch origin socket://192.168.1.1:5963/sync_dest
といったスクリプトを経由すると回避できる。
但し、この手法はいわゆるPUSH型同期となるので、3拠点以上になると更新サーバーへの負担が線形的に増加する。
この場合は、参照サーバー間でPULL型とPUSH型を併用するなどして回避できるけれど、
この簡易的な同期手法ではそもそもお門違いなので別真っ当なクラスタリング手法を検討したほうがいい。
最後に、split-brainが生じた場合は以下の手順で復旧する
- 衝突と変更内容を確認する
- 更新サーバーのincronを停止する
- 手動で同期する
- 更新サーバーのincronを復旧する
尚、Windows環境ではincron実装がないので、.Netの
FileSystemWatcherクラスをPowerShellなどで利用して代替実装をする必要がある。
[パフォーマンス測定結果]
ディレクトリ数 |
2878 |
ファイル数 |
31281 |
ファイルサイズ合計 |
4591789950 byte (4.4GB) |
同期開始遅延 |
28秒 |
同期速度 |
8.2780MB (8分49秒) |
[テスト環境bonnie++実行結果]
bonnie -d /root/ -n 0 -u root -b
Version 1.96 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
testhost 512M 892 94 35214 4 28256 4 4735 92 +++++ +++ 128.0 2
Latency 15100us 4294ms 530ms 4539us 3900us 696ms
[所感]
仮想環境間で試験した為、思うようなIOパフォーマンスが通常転送でもでなかった。
その最中とはいえ、通常運用では生じないような大量ファイル同期をシナリオとして扱った。
やはり大量同期は不得手のようだったものの、マスタIO書き込み完了はGlusteFSより速い。
ちなみに、初回同期はunison側で同期カタログを作成するため、
通常同期以上にCPU負荷と同期開始遅延が生じる。
他に気になった点としては、
- vimなどの書き込み一時ファイルが同期対象に含まれると同期エラーが生じる
- ファイル新規作成時は、同期遅延が生じやすい
導入環境は、
- 静的画像などで低頻度の更新が生じるコンテンツの簡易クラスタリング
- バックアップなどのアーカイブサーバー間の簡易クラスタリング
- *nix<->Windows間の簡易クラスタリング
- 多少の同期遅延が許容されるDR環境
が適していそう。