web-dev-qa-db-ja.com

競合管理を使用したリアルタイムのマルチクライアント同期

ローカルネットワークでNASを使用して、コンピューター間の同期をセットアップする必要があります。ただし、セットアップはやや複雑なので、これを行う既製の製品はないと想定しています。私が必要なもの。

詳細:

私が使用するデバイス:

  • デスクトップPC、デュアルブートWindows 10/Arch Linux
  • ラップトップ(Arch Linux)
  • NAS(セルフビルド、FreeNASが実行されている)

これまでrsyncを使用してNASにバックアップしました(一方向、デュアルブートセットアップは両方のOSに同じストレージを使用します)。

問題は、ラップトップを同期させたいということです。したがって、ある種の双方向同期を行う必要があります。

ここで発生する問題:

  1. シャットダウンの数秒前にファイルを保存することが多いので、同期ツールを定期的に実行するのではなく、ファイルの変更を監視する必要があります

    • ローカルネットワークの外部でラップトップを同期できません(ローカルネットワークでは、ほとんどの場合デスクトップPCを使用しています)。ローカル(更新された)バージョンはかなり古く、いくつかの競合が発生する可能性があります。
  2. 私が住んでいる帯域幅は非常に限られており、同期を維持するためにかなり大きなファイルがあるため、ownCloudなどではなく、ローカルネットワーク(おそらくNASの既存のネットワーク共有)のみを使用したいと思います。

私の考え

私はこの質問を見つけました: DropBoxの最小限の実行可能なレプリカを模倣するようにrsyncと他のスクリプトをセットアップするにはどうすればよいですか? そして lsyncd (Live Syncing Daemon)を使用してソリューションを調べました、ローカルディレクトリをリモートターゲットと同期します。これで問題1を解決できる可能性がありますが、それでも競合に備える必要があります。さらに、Windowsでlsyncdに関するドキュメントが見つからなかったため、そこでは機能しないと思います。

また、 nison をソリューションに組み込む可能性についても検討しました。双方向の同期を行うようです。たぶん私はそれをlsyncdと一緒に使うことができます。ただし、競合の処理についてはよくわかりません。 -batchを使用すると、競合がスキップされるというヒントを見つけました。しかし、競合するファイルを長期的に処理するにはどうすればよいですか(結局、それらを同期したいのですが)?

だから私の質問は、どうすればこれを達成できますか?

3
Qw3ry

あなたのNAS-私は BitTorrent sync がとても好きです。これはほとんどのシステム(ラズベリーパイやミップシステムを含む)で動作し、少数の消費者NASシステム(私のシーゲイトのような)。共有するフォルダーを選択し、キーを生成し、そのキーを使用して、必要な各システムで共有を設定するだけです。そのスマートあなたがLAN上にいることを検出するのに十分で、LANの外で動作します。無料バージョンは私のニーズに十分に対応します-私は主に、私が常に保持しているシステムからのダウンロードと、追加した多くの小さなファイルのバックアップを同期するために使用しますまれに。

それはあなたが必要とすることをします-必要に応じてLANを使用して、一方向または双方向の同期。削除されたファイルのコピーを保持することで競合に対処し(ユースケースではオフにします)、通常は十分に動作するため、ほとんど気づきません。

2
Journeyman Geek

したがって、私の自己開発ソリューションには、 Journeyman Geekの1つ よりも少し多くのスクリプトが必要です。 sync-partには unison を使用し、競合を警告するために zenity を使用しました。

スクリプト

Bashスクリプト(これをスタートアップアプリケーションに入れます):

#!/bin/bash
if [ -z "$(arp | grep MAC_ADDRESS_OF_NAS)" ]; then
    zenity --warning --text="NAS not found. Aborting."
fi;
unison sync -batch=true -repeat=watch |& while read -r line; do
    if test -n "$(echo $line | grep skipped:)"; then
        zenity --warning --text="$line"; 
    fi;
done

ユニゾン構成(これをsync.prfとして~/.unison/に入れます):

root=/home/my-username/the-data-i-want-to-backup/
root=/mnt/NAS/some/sub/path/

# follow all symlinks
follow = Path *

# automatically do everything (if there are no conflicts)
auto = true

# for some reason unison fails if I sync the permissions
perms = 0
dontchmod = true

詳細な説明(および派生物のトラブルシューティング)

  1. まず、ローカルネットワークでNASが見つかったかどうかを確認します。そのMACアドレスがarp出力に表示されない場合は、同期する必要はないと思います。ラップトップを完全にオフにすることはめったにないので、これにはおそらくさらに調整が必要です。そのため、ネットワークに接続してもスクリプトは開始されません。cronジョブまたは何らかの「on-network-connect」を追加する可能性があります。
  2. zenity を使用して、bashスクリプトからグラフィカルダイアログを作成できます。おそらくそれをインストールする必要があります。基本的な使用法は非常に簡単です。
  3. unison syncは同期を開始します。 ~/.unison/sync.prfという構成プロファイルを探します。 syncを他の何か(ファイル名とコマンドの両方)で置き換えることができます。
  4. 競合するファイルをスキップするには、-batch=trueを指定します。競合が発生した場合にunison syncを手動で実行したいので、構成ファイルではこれを行いません。
  5. 変更を監視するためにサードパーティのツールは必要ありません。-repeat=watchは私が望むことを正確に実行します。 補足:実際には、変更があれば完全な再同期を開始するので、もっとうまくいく可能性がありますが、それは私にとっては問題ありません。
  6. unison-コマンドの出力は少し奇妙で、これが機能するまでに少し時間がかかりました:
    • 競合がある場合、出力にはskipped: FILENAMEが含まれます
    • これはSTDOUTではなくSTDERRで発生するように思われるため、|&でパイプする必要があります。
    • なんらかの理由で、単純なgrepでは機能しないことがわかりませんでした。 unison sync ... |& grep "skipped:" | xargs zenity --text="{}"のようなものを試しましたが、ユニゾンが最終的に終了するまで実行されませんでした(-repeat=がなくても正常に動作し、grepがなくても正常に動作しました)
  7. 上記の理由から、whileループを使用して入力を読み取り、各行自体でのみgrepを使用しました。
  8. ユニゾンプロファイルで、絶対パスを使用したことに注意してください。何らかの理由で、~/my/folderでは機能しませんでした

その他の注意事項

  • 私はオーバーエンジニアリングする傾向がある人です。 unison-profileを生成するスクリプトを設定します。興味のある方:

    #!/bin/bash
    
    HOME_DIR=$(cd ~; pwd)
    
    REPO_DIR="$(dirname "$(readlink -f $0)")"
    
    UNISON_PRF=$HOME_DIR/.unison/sync.prf
    
    # write sync script
    read -e -p "Local sync dir: [like ~/Data] " LOCAL_SYNC_DIR
    # make path absolute:
    LOCAL_SYNC_DIR="${LOCAL_SYNC_DIR/#\~/$HOME_DIR}"
    read -e -p "Remote sync dir: [like /mnt/NAS/Data/] " REMOTE_SYNC_DIR
    REMOTE_SYNC_DIR="${REMOTE_SYNC_DIR/#\~/$HOME_DIR}"
    
    rm "$UNISON_PRF"
    echo "root=$LOCAL_SYNC_DIR" > "$UNISON_PRF"
    echo "root=$REMOTE_SYNC_DIR" >> "$UNISON_PRF"
    cat "$REPO_DIR/sync.prf" >> "$UNISON_PRF"
    
    # user info
    echo "IMPORTANT: You need to put $REPO_DIR/unison/sync.sh to your startup applications for this to work properly!"
    
2
Qw3ry