2 つのサーバー間でコンテンツを同期しようとしています。サーバーは同一のビルド (Ubuntu 12.04LTS) であり、コンテンツを同期するために次の cron ジョブを実行しています。
rsync -arzc --update --delete /htdocs/testing/www/cms_uploads/* [email protected]:/htdocs/testing/www/cms_uploads/
しかし、以下に詳述するプロセスをテストすると、奇妙な結果が得られます。
最初のテスト
- aaaa.jpg を Node2 にアップロードしました
- Node1に同期する
- ノード1から削除
- ノード1に再出現
- ノード2から削除
- Node1から削除
2回目のテスト
- bbbb.png を Node1 にアップロードしました
- Node2に同期
- ノード2から削除
- ノード2に再出現
- ノード1から削除
- ノード1に再出現
私がやろうとしているのは、両方のサーバーで常に同じコンテンツが正確に同じであることを確認することだけです。何が間違っているのでしょうか?
答え1
rsync
双方向同期を行うように設定されていません。特別な支援 (変更されたマシンからの同期など) と多くの幸運がなければ、これは実行できません。
変更がまれにしか発生せず、間隔が離れているようにするには、幸運が必要です。次の同期が開始される前に (いずれかのマシンから) Node1 と Node2 の両方が変更されると、同期時に一部の変更が失われます。
参照これ
答え2
問題の説明には根本的な問題があります。サーバーが同期していて、aaaa.jpg
ノード 2 にファイルを作成したとします。次の同期では、その偽のファイルをノード 2 から削除する必要がありますか (ノード 1 には存在しないため、削除されている必要があります)、それともファイルをノード 1 にコピーする必要がありますか (ノード 1 には存在しないため、新しく作成する必要があります)。
同期を実行する順序によって、それぞれの場合に何が起こるかが決まります。多くの場合、これによって望ましい結果が得られないことがほぼ確実です。さらに悪いことに、同期が並行して実行される場合 (つまり、ホストの 1 つが独自の同期ジョブによって更新され、同時に他のホストで実行されている同期ジョブによってトラバースされる場合)、結果はかなりランダムになります。
rsync は基本的に一方向の同期用に設計されています。2 つの rsync ジョブを実行するだけでは双方向の同期は期待できません。
ユニゾンは双方向同期用に設計されたファイル同期ツールです。これは、タスクに最適なツールに最も近いものです。これをセットアップして、unison -auto remote.example.com://path/to/directory /path/to/directory
ホストの 1 つで実行します。
どのようなツールを使用する場合でも、たとえば同じファイルが 2 台の異なるマシンで 2 つの異なるバージョンに置き換えられる場合など、競合が発生する可能性があります。このような競合を解決するための適切な自動化方法はないため、手動による介入が必要になります。
ほとんどの設定では、アップロードする場所として 1 つのサーバーを指定し、そのマスター サーバーから他のすべてのサーバーを同期するのが正しい方法です。誰かがスレーブにファイルをアップロードした場合は、アップロードをマスターに中継し、ローカルでは何も変更しないでください。マスターでファイルが変更されるたびに、それをスレーブにプッシュします。
答え3
rsync には -u オプションがあり、次の処理を実行します。
「これにより、rsync は、宛先に存在し、ソース ファイルよりも新しい変更時刻を持つすべてのファイルをスキップします。(既存の宛先ファイルの変更時刻がソース ファイルと同じ場合、サイズが異なると更新されます。)」
したがって、
1) 指定したコマンドに -u オプションを追加し、-c オプションを削除したものと、
2) 同じコマンドだが方向が逆のものを含むシェル スクリプト
は、双方向の同期をある程度実現できますが、2 つの問題があります。1
) リモート サーバーで削除 (または名前変更) されたファイルは、rsync がローカルに新しいファイルを見つけたと判断するため、ローカルからコピーされます。2
) 同期の間に両方の場所で 1 つのファイルが変更された場合、より新しい変更のみが保持されます。