web-dev-qa-db-ja.com

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

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

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

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

Rsyncを使用して2つの通常のファイルシステム間でこれを行っていた場合、「-axPHAX --delete」になります(これは、一部のシステムをバックアップするために実際に行うことです)。

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

Sshのスループットパフォーマンスが低いため、sshを介した転送は避けたいです。代わりにmbufferまたはiscsiを使用します。

16
Costin Gușă

免責事項:zvolsを使用したことがないので、レプリケーションが通常のファイルシステムやスナップショットと異なるかどうかはわかりません。私は彼らがそうであると思いますが、私の言葉をそれに取ってはいけません。


あなたの質問は実際には複数の質問です、私はそれらに別々に答えようとします:

完全なプールをリモートの場所に複製/ミラーリングする方法

タスクを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のような暗号化されていない代替手段に切り替えることができます asここに説明されています 、または弱い/暗号化なしで圧縮を無効にしてSSHを使用できます 詳細はこちら 。SSHを再コンパイルしてはるかに高速にすることについてのWebサイトもありましたが、残念ながら私はしませんt URLを覚えておいてください。見つかった場合は後で編集します。

非常に大規模なデータセットと低速な接続の場合、ハードディスクを介した最初の送信に役立つ場合があります(暗号化されたディスクを使用してzpoolを保存し、宅配便、郵便、または直接、密封されたパッケージで送信します)。送信方法はsend/recvには関係ないため、すべてをディスクにパイプし、プールをエクスポートし、宛先にディスクを送信し、プールをインポートしてから、SSH経由ですべての増分送信を送信できます。

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

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

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

これは、コマンドが間違っていたか、スナップショットを削除して最初からやり直す必要がある不整合な状態にあることを意味します。

これには、いくつかの否定的な影響があります。

  1. 新しい複製スナップショットが正常に転送されるまで、複製スナップショットを削除することはできません。これらのレプリケーションスナップショットには他のすべての(古い)スナップショットの状態が含まれているため、削除されたファイルとスナップショットの空きスペースは、レプリケーションが終了した場合にのみ再利用されます。これにより、プールで一時的または永続的なスペースの問題が発生する可能性があります。これは、完全なレプリケーション手順を再起動または終了することによってのみ修正できます。
  2. 多くの追加のスナップショットがあり、listコマンドの速度が低下します(これが修正されたOracle Solaris 11を除く)。
  3. スクリプト自体を除いて、(偶発的な)削除からスナップショットを保護する必要がある場合があります。

これらの問題に対する可能な解決策は存在しますが、私は自分で試したことがありません。このタスク専用に作成されたOpenSolaris/illumosの新機能であるzfs bookmarkを使用できます。これにより、スナップショット管理から解放されます。唯一の欠点は、現時点では単一のデータセットに対してのみ機能し、再帰的に機能しないことです。すべての古いデータセットと新しいデータセットのリストを保存してから、それらをループ処理し、ブックマークを付けて送受信し、リスト(または必要に応じて小さなデータベース)を更新する必要があります。

ブックマークルートを試してみた場合、どのように機能したか聞いてみたいと思います。

12
user121391

個人的には、リモートサーバー上のzvols、データセットなどのリストを作成しますしないでください最新のスナップショットを作成し、それらのスナップショットをzfs sendで更新します、これは時間がかかり、多くの帯域幅を使用する場合でも。

その後、zfs sendをそれ以降も使用し続けることができ、独自の同期コードを記述してホイールを再発明する必要はありません。 rsyncは古いファイルシステムではいいですが、zfs sendはzfsではるかに優れています-スナップショットで変更されたブロックをexactly知っており、それらを送信しますonly rsyncはローカルサーバーとリモートサーバー間で個々のファイルやタイムスタンプを比較します。同じことがbtrfsプールのbtrfs sendにも当てはまります。

最新にする必要があるスナップショットの数が少ない場合、これは手動で行うことができます。それ以外の場合、自動的に行うには、最新のローカルスナップショットとリモートスナップショットのリスト、およびバージョンを比較するスクリプトと、rmeoteサーバー上の古いzfs sendのローカルスナップショットが必要です。

各データセットの最新のスナップショットのみに関心がある場合は、これで十分です。以前のすべてのスナップショットに関心がある場合は、スクリプトでそれらも処理する必要があることは明らかです。場合によっては、リモートサーバーでロールバックして、中間/不足しているスナップショットを再送信できるようにする必要があります。

リモートサーバーへの安全な接続が必要な場合は、sshを使用する以外に選択肢はほとんどありません。あるいは、openvpnまたは何かでトンネルを設定し、netcatを使用することもできます。

5
cas

FreeBSDの `zrepl 'を見てください。これにより、あなたの人生を、そして誰にとってもずっと簡単にできるようになります。数日前にオタワでBSDCan2018中に発表されました。それは有望に見え、あなたの問題の解決策になるかもしれません

1
fd0

zrepは素晴らしいオールインワンソリューションであり、単なるSSH転送よりも高速な転送を実現する方法に関するドキュメントとフックがあります

https://github.com/bolthole/zrep

それはクロスプラットフォームでもあります:linux、freebsd、solaris/illumosでサポートされています

0
Philip Brown