zfs プール全体を別の zfs プールに一方向にミラーリングする方法

zfs プール全体を別の zfs プールに一方向にミラーリングする方法

いくつかのzvolとデータセットを含むzfsプールがあり、それらのいくつかは入れ子になっています。すべてのデータセットとzvolは、zfs-auto-snapshotによって定期的にスナップショットが作成されます。すべてのデータセットとzvolには、手動で作成されたスナップショットもあります。

リモートプールを設定しましたが、時間が不足しているため、ローカル高速ネットワークを介したzfs send -Rを介した初期コピーは完了しませんでした(一部のデータセットが欠落しているか、一部のデータセットが古くなっているか、スナップショットがありません)。

プールは遅い接続を介して物理的にリモートにあり、リモートプールをローカルプールと定期的に同期する必要があります。つまり、ローカルプールのデータをリモートプールにコピーし、ローカルプールのデータをコピーする必要があります。リモートプールから削除され、リモートプールには存在するがローカルプールにはないデータは、リモートプールから削除する必要があります。つまり、「zvols」、「datasets」、または「snapshots」を意味します。

rsyncを使用して2つの一般的なファイルシステム間でこれを行うには、「-axPHAX --delete」(一部のシステムをバックアップするために実際に実行する作業)になります。

リモートプールzvolとデータセット(スナップショットを含む)がローカルzvol、データセット、およびスナップショットと同期できるように同期操作を設定するにはどうすればよいですか?

スループット性能が低いので、sshを介した転送を避けたいと思います。 mbufferまたはiscsiを好む。

答え1

免責事項:私はzvolを使ったことがないので、通常のファイルシステムやスナップショットとは異なる方法でレプリケートすることはできません。私はそう思いますが、私の言葉を受け入れないでください。


ご質問は実際には複数の質問なので、個別に回答いたします。

プール全体をリモートの場所にコピー/ミラーリングする方法

作業を2つの部分に分ける必要があります。最初に最初のコピーを実行し、次に増分コピーを実行できます。コピースナップショットを台無しにしない限り。増分レプリケーションを有効にするには、最後のレプリケーションスナップショットを維持する必要があり、以前の内容はすべて削除できます。古いスナップショットが削除されるとzfs recvエラーが発生し、複製が中断されます。この場合は再起動する必要があるため、そうしないでください。

正しいオプションが必要な場合は、次のようになります。

  • zfs send:
    • -R:指定されたプールまたはデータセットの下のすべての項目を送信します(再帰コピー、常に必須、含む-p)。また、受信時に削除されたすべてのソーススナップショットがターゲットから削除されます。
    • -I:最後の複製スナップショットと現在の複製スナップショットの間のすべての中間スナップショットを含みます。 (増分転送する場合のみ必要)
  • zfs recv:
    • -F:ソースから削除された既存のデータセットの削除を含むようにターゲットプールを展開します。
    • -d: ソースプールの名前を破棄し、ターゲットプール名に変更します。 (残りのファイルシステムパスは維持され、必要に応じて作成できます。)
    • -u処置: ターゲットにファイルシステムをマウントしないでください。

完全な例が必要な場合は、次のような小さなスクリプトがあります。

#!/bin/sh

# Setup/variables:

# Each snapshot name must be unique, timestamp is a good choice.
# You can also use Solaris date, but I don't know the correct syntax.
snapshot_string=DO_NOT_DELETE_remote_replication_
timestamp=$(/usr/gnu/bin/date '+%Y%m%d%H%M%S')
source_pool=tank
destination_pool=tank
new_snap="$source_pool"@"$snapshot_string""$timestamp"
destination_host=remotehostname

# Initial send:

# Create first recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Initial replication via SSH.
zfs send -R "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"

# Incremental sends:

# Get old snapshot name.
old_snap=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$source_pool"@"$snapshot_string" | tail --lines=1)
# Create new recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Incremental replication via SSH.
zfs send -R -I "$old_snap" "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"
# Delete older snaps on the local source (grep -v inverts the selection)
delete_from=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$snapshot_string" | grep -v "$timestamp")
for snap in $delete_from; do
    zfs destroy "$snap"
done

SSHより速いものを使う

IPSecやOpenVPNトンネルなど、十分に安全な接続があり、発信者と受信者の間にのみ存在する別々のVLANがある場合は、SSHからmbufferなどの暗号化されていない代替手段に切り替えることができます。ここで述べたようにあるいは、弱い暗号化/無効化および圧縮が無効になっているSSHを使用することもできます。詳しくはこちら。 SSHをより速くするために再コンパイルする方法についてのウェブサイトもありますが、残念ながらURLは覚えていません。後で見つけたら編集します。

非常に大きなデータセットと遅い接続の場合は、ハードディスクを介した最初の転送も便利です(暗号化されたディスクを使用してzpoolを保存し、宅配便、郵便、または密封されたパッケージに直接転送します)。転送方法は送受信には重要ではないため、すべてをディスクにパイプし、プールをエクスポートし、ディスクを宛先に送信し、プールにインポートしてから、すべての増分転送をSSHに送信できます。

スナップショット混乱の問題

前述のように、レプリケーションスナップショットを削除/修正すると、エラーメッセージが表示されます。

cannot send 'pool/fs@name': not an earlier snapshot from the same fs

これは、コマンドが間違っているか一貫性のない状態なので、スナップショットを削除して再起動する必要があることを意味します。

これはいくつかの悪影響を及ぼします。

  1. 新しい複製スナップショットが正常に送信されるまで、複製スナップショットを削除することはできません。これらのレプリケーションスナップショットには他のすべての(以前の)スナップショットのステータスが含まれているため、削除されたファイルとスナップショットの空き領域はレプリケーションが完了するまで回収されません。これにより、プールに一時的または永続的なスペースの問題が発生する可能性があります。これは、再起動または完全なレプリケーションプロセスを完了するまで解決できません。
  2. 追加のスナップショットが増えると、listコマンドが遅くなります(この問題は解決されたOracle Solaris 11を除く)。
  3. スクリプト自体を除いて(偶発的な)削除からスナップショットを保護する必要があるかもしれません。

これらの問題に対する可能な解決策がありますが、直接試してはいません。zfs bookmarkこれには、特別に作成されたOpenSolaris / illumosの新機能を使用できます。これにより、スナップショット管理の制約から逸脱することができます。唯一の欠点は、現在単一のデータセットでのみ機能し、再帰的には機能しないことです。すべての古いデータセットと新しいデータセットのリストを維持し、それを繰り返し、ブックマークし、送受信し、リスト(または必要に応じて小規模データベース)を更新する必要があります。

ブックマークパスを試してみるとどうなるか知りたいです!

答え2

個人的には、リモートサーバーにzvol、データセットなどのリストを直接作成します。いいえzfs send時間がかかり、帯域幅が大量に消費されていても、最新のスナップショットがある場合は、そのスナップショットを更新してください。

zfs sendその後、独自の同期コードを作成して、ホイールを再構築する必要なしに引き続き使用できます。rsync古いファイルシステムには良いですが、zfs sendzfsには優れています。正確にスナップショットのどのブロックが変更されて送信されたかただ一方、rsyncはローカルサーバーとリモートサーバー間の個々のファイルとタイムスタンプを比較する必要があります。btrfs sendbtrfsプールにも同様に適用されます。

更新するスナップショットが数回しかない場合は、手動で更新できます。そうでない場合、それを自動化するには、最新のローカルスナップショットとリモートスナップショットのリスト、およびzfs sendrmeoteサーバーの期限切れのローカルスナップショットとバージョンを比較するスクリプトが必要です。

各データセットの最新のスナップショットにのみ興味があれば、これで十分です。以前のすべてのスナップショットに興味がある場合は、もちろんスクリプトもこれを処理する必要があります。これはさらに複雑になります。場合によっては、中間/失われたスナップショットを再送信できるように、リモートサーバーからロールバックする必要があります。

リモートサーバーへの安全な接続が必要な場合は、実際にsshトンネルを確立してopenvpn使用するために他のものを使用または使用する必要がありますnetcat

答え3

FreeBSDで「zrepl」をチェックしてください。あなたの人生と他人の人生をはるかに簡単にすることができます。数日前、オタワで開催されたBSDCan2018でリリースされました。有望に見え、問題を解決することもできます。

答え4

zrepは優れたオールインワンソリューションであり、通常のSSH転送よりも速い速度を得る方法に関するドキュメント+フックがあります。

https://github.com/bolthole/zrep

また、クロスプラットフォームです。 Linux、freebsd、および Solaris/illumos をサポートします。

関連情報