はじめに
Amazon FSx for OpenZFSには、リージョンをまたいでデータを複製する手段としてオンデマンドレプリケーションが用意されています。ただ、これはスナップショットを取得してDR側のファイルサーバに適用する方法で、スケジュールに沿って継続的に同期し続けるマネージドの仕組みまでは用意されていなかったりします。そのため、マルチリージョンであったりDR用途で使うのであればスナップショットの作成、複製の起動、進捗の監視、定期実行までをユーザ側で組み立てる必要があります。
また、実際にレプリケーションの設定を組んでみると、複製はスナップショット単位で実行されるため、送信元と送信先に共通のスナップショットがない初回は全量転送になるなど、さまざまな注意事項が存在しています。
そこで今回は非同期レプリケーションの検証として、東京リージョンのFSx for OpenZFSに10 GiBのランダムなデータを書き込みました。そのスナップショットを手動で取得し、大阪リージョンのボリュームへ全量コピーを実行しました。この記事では、その手順とCLI・CloudWatch・NFSクライアントで確認できた結果をまとめます。
今回実施している内容は初回の全量コピーのみであるため、増分コピー(INCREMENTAL_COPY)については追加での検証が必要になります。
想定読者
- FSx for OpenZFSでリージョン間のデータ複製を検討している方
- DR側のスループットキャパシティや所要時間を見積もっている方
この記事でわかること
- スナップショットから大阪側ボリュームを更新するまでのCLI操作
- デプロイタイプごとに異なるレプリケーションのスループット要件
- 10 GiBの全量コピーに要した時間と、その内訳
検証構成と先に押さえたい仕様
構成は以下のとおりです。
東京・大阪のそれぞれにFSx for OpenZFSと確認用のAmazon EC2を用意しました。複製対象はルートボリュームです。
なお、オンデマンドレプリケーションが転送するのは指定したスナップショットのデータだけで、子ボリュームのデータは含まれません。ボリュームを分けている構成では、ボリュームごとにレプリケーションを起こす必要があります。
| 項目 | 東京(送信元) | 大阪(送信先) |
|---|---|---|
| デプロイタイプ | Single-AZ 2(非HA) | Single-AZ 1(非HA) |
| ストレージ | SSD 64 GiB | SSD 64 GiB |
| スループットキャパシティ | 160 MBps | 256 MBps |
| プロビジョンドSSD IOPS | 192 | 192 |
| AZ | ap-northeast-1a | ap-northeast-3b |
もう一つ、作成時に確認しておきたいのがスループットキャパシティです。オンデマンドレプリケーションの前提条件では、ファイルシステムのデプロイタイプごとに次の下限が示されています。
| デプロイタイプ | 必要なスループットキャパシティ |
|---|---|
| Single-AZ 1(HA・非HA) | 256 MBps以上 |
| Single-AZ 2(HA・非HA)、Multi-AZ(HA) | 160 MBps以上 |
この下限は、送信元・送信先のどちらのファイルシステムにも適用されます。今回の東京側はSingle-AZ 2の160 MBpsなので、ちょうど下限を満たしている状態でした。
一方で、大阪側はSingle-AZ 1なので、必要な設定値は256 MBps以上です。ちなみに、FSx for OpenZFSのスループットは任意の数値を入力する方式ではなく、デプロイタイプごとに決まった値から選択する方式になっています。
AWSのドキュメントではSSD IOPSを6,000以上にすることも推奨していますが、今回は検証用途なのでこの部分は考慮していません。
AWS側がこの値を推奨する背景としては、FSx for OpenZFSのレプリケーションではプロビジョニング済みのスループットを通常のワークロードと共有します。そのため、通常のワークロードを圧迫してしまわないようにこういった数値を推奨しているみたいですね。
またパフォーマンスを考慮するのであれば、通常のワークロードに必要なスループットの2倍を用意することを推奨していたりもするので、実際のワークロードにあてがうには注意が必要です。
詳しくはオンデマンドレプリケーションの性能上の考慮事項に書かれています。
東京側に10 GiBのテストデータを用意する
東京側のEC2からルートボリュームをNFSでマウントしました。マウントにはAWSコンソールが提示するデフォルトのコマンドをそのまま使い、オプションを独自に調整していません。
sudo mkdir -p /mnt/fsx
sudo mount -t nfs \
-o noatime,nfsvers=4.2,sync,nconnect=16,rsize=1048576,wsize=1048576 \
fs-xxxxxxxx.fsx.ap-northeast-1.amazonaws.com:/fsx/ /mnt/fsx/
東京側では、マウント後にdfで/mnt/fsxへ接続できていることを確認しました。
大阪側も同様に、大阪のFSxのDNS名を使って事前にマウントしています。
テストデータは/dev/urandomから書き込みました。圧縮されにくいデータを使い、10 GiBという論理サイズと実際の転送量を比較しやすくしています。
dd if=/dev/urandom of=/mnt/fsx/test.txt bs=1M count=10240
書き込みには73.98秒かかり、平均で約145 MB/sでした。東京側のスループットキャパシティは160 MBpsなので、リージョン内のNFS書き込みでは設定値に近い値が出ています。
これは完全に検証用で使っているので、他ワークロードからの圧迫は一切受けていない状況です。
dfでは使用量が10492928(1 KiBブロック)となり、表示上は16%でした。その後、今回の検証用に東京側のルートボリュームのスナップショットを手動で作成しました。次のCLI操作へ進む前に、スナップショットのLifecycleがAVAILABLEになっていることを確認しています。

スナップショットの取得が終わるまでaws cliでひたすら進捗確認をしていきます。

スナップショットの取得が完了するとステータスがAVAILABLEになるので、これで先に進めそうです。

スナップショットのARNを取得する
CopySnapshotAndUpdateVolumeに渡すのはスナップショットIDではなくARNです。東京リージョンに対してdescribe-snapshotsを実行し、対象ボリュームで絞り込みます。
# 実環境のソースボリュームIDに置き換える
SOURCE_VOLUME_ID=fsvol-0123456789abcdef0
aws fsx describe-snapshots \
--region ap-northeast-1 \
--filters Name=volume-id,Values="$SOURCE_VOLUME_ID" \
--query 'Snapshots[].{Name:Name,ARN:ResourceARN,Lifecycle:Lifecycle,Time:CreationTime}' \
--output table
ここで見るのは、対象ボリュームのスナップショットであることとAVAILABLEであることの2点です。
先ほど確認済みなので、先ほどのスクショを元に穴埋めしていきます。
大阪側ボリュームへ初回のFULL_COPYを実行する
初回は東京・大阪の間に共通のスナップショットがないため、FULL_COPYを指定します。--regionには送信先である大阪リージョンを指定します。送信元のリージョンはスナップショットARNに含まれています。
ただ、実際には一度では通らず、2つのエラーに弾かれました。どちらもドキュメントに書いてある前提条件なのですが、読み飛ばしていた部分でした。
1つ目: FULL_COPYにはオプションの明示が必要
最初は--copy-strategy FULL_COPYだけを指定して実行しました。
An error occurred (BadRequest) when calling the CopySnapshotAndUpdateVolume operation:
Unable to update the volume with snapshot using the FULL_COPY CopyStrategy
because DELETE_INTERMEDIATE_DATA option is not set
--optionsに指定できる値はDELETE_INTERMEDIATE_SNAPSHOTS、DELETE_CLONED_VOLUMES、DELETE_INTERMEDIATE_DATAの3つです。FULL_COPYは送信先のデータを丸ごと置き換える破壊的な操作なので、中間データを消してよいという同意を明示しない限り実行させない作りになっているようです。(結構安全設計だなって思いました。)送信先にクローンや依存するスナップショットがある場合は、それぞれに対応する値もあわせて指定する必要があります。
2つ目: 送信先のスループットキャパシティ不足
オプションを足して再実行すると、今度は別のエラーが返ってきました。
An error occurred (BadRequest) when calling the CopySnapshotAndUpdateVolume operation:
The on-demand replication request failed because file system fs-xxxxxxxx does not have
the minimum required throughput of 160 MB/s. File system fs-xxxxxxxx is currently
configured with 64 MB/s. Increase the file system's throughput capacity to at least
160 MB/s and retry the request.
実は最初の方で大阪側を64 MBpsで作っていたため、このエラーが発生しました。
スループットキャパシティの変更を済ませたうえで、最終的に通ったコマンドは次のとおりです。
# 2つとも実環境の値に置き換える
DEST_VOLUME_ID=fsvol-0123456789abcdef1
SOURCE_SNAPSHOT_ARN=arn:aws:fsx:ap-northeast-1:123456789012:snapshot/fsvol-0123456789abcdef0/fsvolsnap-0123456789abcdef0
aws fsx copy-snapshot-and-update-volume \
--region ap-northeast-3 \
--volume-id "$DEST_VOLUME_ID" \
--source-snapshot-arn "$SOURCE_SNAPSHOT_ARN" \
--copy-strategy FULL_COPY \
--options DELETE_INTERMEDIATE_DATA
DELETE_INTERMEDIATE_DATAは、送信先にある中間データの削除を許可するオプションです。FULL_COPYでは送信先ボリュームのデータだけでなく、クローンやスナップショットも削除されます。既存データがあるボリュームに実行する際は、送信先を取り違えていないか確認が必要です。
もう一つ、コピー戦略によって送信先ボリュームの状態が変わる点も押さえておきたいところです。INCREMENTAL_COPYの実行中は送信先ボリュームが読み取り専用になり、FULL_COPYの実行中は送信先ボリュームがいったんアンマウントされ、転送完了後に自動で再マウントされます。今回は大阪側のEC2からマウントしたままFULL_COPYを実行しているので、その裏でアンマウントと再マウントが走っていたことになります。DR側を普段から参照用に使っている構成では、複製中はアクセスが切れる前提で考えておく必要があります。
AdministrativeActionsで進捗確認をする
CLIがエラーなく返っても、その時点でデータ転送は終わっていません。大阪側ボリュームのAdministrativeActionsを確認します。
aws fsx describe-volumes \
--region ap-northeast-3 \
--volume-ids "$DEST_VOLUME_ID" \
--query 'Volumes[].AdministrativeActions' \
--output json
処理中は、次の状態でした(一部の項目を抜粋)。
{
"AdministrativeActionType": "VOLUME_UPDATE_WITH_SNAPSHOT",
"ProgressPercent": 0,
"Status": "IN_PROGRESS",
"TargetVolumeValues": {
"OpenZFSConfiguration": {
"DestinationSnapshot": "fsvolsnap-04a7aa621ad320632",
"CopyStrategy": "FULL_COPY",
"DeleteIntermediateData": true
}
}
}
VOLUME_UPDATE_WITH_SNAPSHOTが今回の更新操作です。今回は検証のためwatch -n 15で15秒ごとに確認しました。自動化する場合も、API呼び出しの成功だけで完了扱いにせず、StatusがCOMPLETEDまたはFAILEDになるまで追う必要があります。FAILEDの場合はFailureDetailsを確認します。
この辺りはStepFunctionsと組み合わせて自動化するのが良さそうだなと個人的に考えながら検証してました。
大阪側には、処理中にDestinationSnapshotと同じIDのスナップショットが作成状態で現れました。完了時には利用可能になっています。AWSの説明では、次回のINCREMENTAL_COPYは送信元と送信先が共有する直近の共通バックアップを基準に、差分を転送します。ただし、今回は2回目を実行していないため、今回作られたスナップショットを使った増分コピーの動作までは確認できていません。詳しくは増分コピーの説明をご確認ください。
実測結果
完了を確認したときはStatusがCOMPLETED、ProgressPercentが100になっていました。TotalTransferBytesは10,756,153,304バイト、RemainingTransferBytesは0です。書き込んだファイルは10,737,418,240バイト(10 GiB)なので、転送量はそれより約18.7 MB多い値でした。
その差分には、増分コピーの基準となる共通バックアップを識別するためのメタデータが付与されている可能性があります。
なおTotalTransferBytesとRemainingTransferBytesは、今回のIN_PROGRESS時のレスポンスには含まれておらず、完了時に現れました。転送量ベースで進捗を追いたい場合は、ProgressPercentとあわせて確認することになりそうです。
| 観測した項目 | 値 |
|---|---|
| コピー対象のデータ量 | 10 GiB |
| 処理中の状態 |
IN_PROGRESS、0% |
| 完了確認時の状態 |
COMPLETED、100% |
TotalTransferBytes |
10,756,153,304バイト |
リクエスト受付から約10分後に完了を確認した、というのが今回の観測結果です。正確な完了時刻は取得していないため、転送自体に要した時間とは区別します。
大阪側のEC2からdfを確認すると、東京側と同じUsed: 10492928、Use%: 16%になりました。
Filesystem 1K-blocks Used Available Use% Mounted on
fs-xxxxxxxx.fsx.ap-northeast-3.amazonaws.com:/fsx 67107840 10492928 56614912 16% /mnt/fsx
さらに大阪側のCloudWatchでは、使用可能なストレージ容量が約68.72 GBから57.97 GBへ減り、ストレージ使用率が15.64%になっています。東京側と大阪側のdf、AWS側のメトリクスが、おおむね10 GiBのデータを持つ状態で整合しました。ただし、今回はファイルのハッシュ値や内容の比較はしていません。dfの一致だけでファイル単位の整合性を証明したわけではない点は、区別しておきます。
実効転送速度を概算してみる
TotalTransferBytesと所要時間から、今回の実効転送速度を概算します。
所要時間は、記事中の「リクエスト受付から約10分後に完了を確認」と、スクリーンショットの時刻(IN_PROGRESSの確認が16:12台、COMPLETEDの確認が16:20台)から、8〜10分と置きました。正確な完了時刻は取得できていないため、幅を持たせています。
| 想定した所要時間 | 平均速度(MB/s) | 平均速度(MiB/s) | 平均速度(Mbps) |
|---|---|---|---|
| 10分(600秒) | 約17.9 | 約17.1 | 約143 |
| 8分(480秒) | 約22.4 | 約21.4 | 約179 |
計算に使った転送量はTotalTransferBytesの10,756,153,304バイトです。たとえば10分の場合は、10,756,153,304 ÷ 600 ≒ 17,927,000 B/sとなります。
大阪側に設定したスループットキャパシティ(256 MBps)に対しては、7〜9%程度でした。
この数値の読み方
この値は、あくまで平均速度の目安です。
- 「完了を確認した時刻」は「完了した時刻」より後になるため、実際の平均速度はここに示した値より高い可能性があります。
- 所要時間には、複製の起動処理や、
FULL_COPY中の送信先ボリュームのアンマウント・再マウントが含まれている可能性があります。純粋なデータ転送だけの速度ではありません。 - 転送量が10 GiBと小さいため、立ち上がりの時間が平均に与える影響が大きいと考えられます。
そのため、「今回の条件では、設定値の1割弱の実効速度だった」とは言えますが、「256 MBpsに設定しても1割しか出ない」と一般化することはできません。転送の実行時間帯を絞るには、送信先のCloudWatchメトリクスを1分粒度で確認する方法がありそうです。
DR設計の観点では、スループットキャパシティの設定値をそのままRPO・RTOの見積もりに使うと、転送時間を過小に見積もるおそれがあります。実環境に近いデータ量で一度計測してから見積もるのが安全だと感じました。
DR設計で持ち帰りたいこと
リージョンをまたぐ複製では、リージョン間転送のレイテンシーと実効スループットを考慮する必要があります。FSx側にもデプロイタイプごとにスループットキャパシティの下限があり、今回は大阪側を256 MBpsに設定しました。ただし、この設定値がそのままリージョン間の転送速度になるわけではありません。
スループットキャパシティは、採用するDR戦略にも大きく左右されます。変更にはそれなりの時間がかかるため、「普段は小さい値で運用し、DR発動時に増強してから複製する」というコスト削減策は、要件次第では成り立たない可能性があります。
RPOには、スナップショットの取得間隔に加えて、スナップショットがAVAILABLEになるまでの待ち時間と、複製の完了時間が関わります。現実的には、最短でも10分間隔程度は見込んでおくのがよさそうです。
今回は東京側のスナップショットを手動で作成し、AVAILABLEになるのを待ってから複製しました。この作成から利用可能になるまでの時間も、スケジュールに織り込む必要があります。特に初回は共通スナップショットがないためFULL_COPYによる全量転送になり、定期運用時の増分コピーとは分けて見積もるべきです。スナップショット作成から複製完了までを定期的に実行して共通スナップショットを維持すれば、以降は増分コピーが使えます。
そのため、システムのリリース前に一度FULL_COPYを済ませておき、以降は増分コピーで運用する形にしておくのが安全だと感じました。
自動化には、Amazon EventBridge SchedulerでAWS Step Functionsのステートマシンを定期起動する構成が向いてそうだなと感じました。
待機やポーリングはWaitステートで表現でき、AWS SDK統合を使えば各API呼び出しをLambdaなしで組めます。複製に時間がかかっても、Lambdaの実行時間制限を気にする必要がありません。(この用途ではStandardワークフローを前提に書いてます)
前回の複製が終わる前に次の処理を始めない制御も必要です。運用上の配慮であると同時に、サービス側の制約でもあります。1つのファイルシステムが同時に関われるオンデマンドレプリケーションは、送信元・送信先のどちらであっても1件までで、前のタスクが完了または取り消されるまで次のリクエストは出せません。
なお、AWSもLambdaを使った定期レプリケーションの構成例を公開しており、全体の流れの参考になります。









