Rubrikの継続的データ保護(CDP)は、ほぼゼロの目標復旧時点(RPO)の達成を可能とすることで、お客様のミッションクリティカルなVMwareワークロードの保護を支援します。復旧作業は現地でも遠隔地でも行えます。さらに、Rubrikのアプリケーション連携による自動復旧ともシームレスに連携して、お客様の災害復旧において、ほぼゼロのRPOと目標復旧時間(RTO)の短縮を実現します。

これは、Rubrikの技術スタックにおけるさまざまな専門家の働きによって可能となったすばらしい成果で、ネットワークの輻輳、パーティション、保護対象仮想マシンのI/Oバーストなどの多くの課題に対してレジリエントな機能の構築を可能にしました。このブログではソリューションを構成する要素をひとつひとつ取り上げ、どのようにして超高速でフォールトトレランスな継続的データ保護パイプラインを実現できたのかを解説していきます。

セットアップが不要

Rubrik CDPはRubrikのプラットフォームにシームレスに統合されています。お客様はRubrikが提供する標準のバックアップおよびレプリケーション機能に加えて、サービスレベル合意(SLA)ウィザードのトグルにより、SLAの一部としてCDP保護機能を有効にすることができます。Rubrikにより、現地でも遠隔地でも過去24時間の任意の時点へ復旧できます(Resync時の短期間を除く。これについては本ブログの終わり頃に取り上げます)。CDPを開始するには、CDMを使用してRubrikのI/Oフィルタをインストールする必要があります。I/Oフィルタをインストールすると、CDP SLAが有効になっている仮想マシンは、SLAに従って、次のスナップショットから自動的に直近数時間のI/Oデータの取得と保存を開始します。

CDPアーキテクチャ

img


図1. CDPアーキテクチャの概要

CDPはRubrik I/OフィルタとCDMの2つの部分に分けることができます。

RubrikのI/Oフィルタ

I/OフィルタはVMwareのvSphere APIs for IO filtering (VAIO) フレームワークを使用して作成されています。これにより、仮想マシン上で発生するI/O(入出力)操作へのアクセスが可能となります。他のいくつかのベンダーとは異なり、RubrikのすべてのI/Oフィルタは広範囲にわたる試験を受けて、VMware Acceptedとして、VMwareの認定を受けています。I/Oフィルタには、ディスクに導入されるI/OフィルタインスタンスとESXiホスト内で実行されるデーモンの2つの部分があります。これらはフレームワークの一部として互いに直接通信することはできず、通信には共有メモリを使用します。

I/Oフィルタのエンジニアリング要件は以下のとおりです。

  • ユーザーの本番ワークロードに影響を与えるような重大な遅延をI/Oパスにもたらさないこと

  • 仮想マシンのすべてのI/OをRubrikに送信すること。その際、I/Oにビット反転などの誤りやアウトオブオーダーな記述(アプリケーションロジックエラーなど)がないことを確認する。

  • 仮想マシン上のデータ発生のペースに合わせたRubrikへのデータ送信を一時的に妨げるI/Oバーストおよび/またはネットワークパーティションに対する回復機能を備えていること

img


図2:I/Oフィルタの簡易説明図

上の図はI/Oフィルタの仕組みを表すおおまかなアーキテクチャを示したものです。VAIOフレームワークは、I/OスタックからI/Oが処理されると、I/Oフィルタインスタンスにコールバックを提供します。I/Oフィルタインスタンスはすべての正常なI/Oを取り込み、以下の事柄を共有メモリに書き込みます。

  • 圧縮I/O

  • I/Oのチェックサム

  • 通し番号 

  • ESXで生成されたモノトニック時刻のタイムスタンプ

通し番号はI/Oごとに1つずつ増えていく番号です。これはモノトニックタイムスタンプとともに、I/Oの順序を保証するのに使われます。チェックサムはデータ破損に対するレジリエンス確保に使用され、 Atlas(Rubrikのクラウドスケールのファイルシステム)への永続化処理中や復旧中など、Rubrikサイドのあらゆる段階でチェックされます。I/Oフィルタインスタンスの動作は非常に軽量となるよう十分にテストされており、本番ワークロードに影響しないことを確認しています(非常に高い設定でFIOを実行して、I/Oフィルタが本番ワークロードに有意に影響していないことを検証するなど)。

その後、共有メモリに書き込まれたデータをデーモンが読み込み、ネットワークパフォーマンスの最適化のために、それをCDMへ一括で送信します。バッチサイズは考慮すべき重要パラメーターです。バッチサイズごとに、ネットワーク使用量とESXiホスト上のメモリ消費とはトレードオフの関係にあります。バッチサイズは、ネットワーク利用への影響を考慮して小さくしすぎても、インメモリバッファ要件を考慮して大きくしすぎてもいけません。同様の問題を解決する場合に備えて、このトレードオフについて実験し、パラメーターを適切に調整してみることは、読者の皆様にとって面白い演習となるでしょう。 

ハッピーパス(理想的な状況下)では、I/Oフィルタは上記のように機能します。これは、仮想マシンのすべてのI/Oと同期していることから、同期モードと呼ばれます。

ただし、ここには注意しなければならない問題があります。ネットワーク上の問題が発生した場合、たとえば、ネットワークパーティションや、大量のTCPドロップ(パケットロス)と再送によりデーモンが未処理分を抱え、I/Oを取り込むべき共有メモリがいっぱいになってしまったら、どうなるでしょう。このような状況に対処するために、Rubrikがたどり着いたのはResync(再同期)という戦略でした。

先ほどのいくつかの例のような場合、すべてのI/OをCDPサービスに送信することができません。このような場合、I/OフィルタはすべてのI/Oの追跡を停止し、代わりにCDPサービスが正常に認識したI/Oの変更されたブロックのみを追跡します。Rubrikの処理が追いつきI/Oフィルタが再び同期モードになるまで、この変更ブロックが送信されます。Resync(再同期)によってCDPは一時的な障害に対して非常に高いレジリエンスを獲得しています。内部テストにおいて、100台を超える仮想マシン(すべてのマシンに大規模データが流入し続け、ランダムな間隔のI/Oバーストが発生している)を保護対象とする負荷設定で、CDPはネットワークのパーティションやパフォーマンス劣化が発生した場合はいつでも、Resync(再同期)に移行し同期モードに復帰することが確認されており、本製品に対する確かな信頼となっています。

以上がESXサイドからRubrikがデータを受け取る仕組みについてのおおまかな説明です。では、今度はCDPサービスのRubrikサイドについて見ていきましょう。

RubrikのCDPサービスはI/Oフィルタからのすべてのデータを受け取ります。CDPサービスは以下を必要とします。

  • Rubrik独自のファイルシステムであるAtlasをフルに活用できる効率性の高いデータパイプライン

  • 保護対象の仮想マシンにおけるI/Oバーストの一般的なユースケース(短時間に大量のI/O処理が必要となる場合がある)への対策

  • データの保存先への効率的なレプリケーション

話を先に進める前に、いくつかの用語を取り上げておきます。AtlasでI/Oを記録するジャーナルファイルを操作する時、CDPサービスはファイルに対して以下の2つのメソッドを呼び出します。

  • フラッシュ(Flush) - ディスクへのデータの単純な書き込み。フラッシュ直後には、データのすべての複製がRubrikの分散ファイルシステムに書き込まれることが保障されてはいないことに注意が必要です。これはバックグラウンドで非同期的に行われます。

  • 同期(Sync) - ファイルシステムに対する呼び出しを行って、確実にデータがレプリケートされフォールトトレランスが確保されるようにします(たとえば、同期後にはノードがクラッシュしたとしてもデータの利用は保証されます。これはフラッシュ後には保証されないことです)。

ここで挙げた問題を解決するために私たちは意見を出し合い、さまざまなオプションを検討した結果、それぞれが役割の一部を担い互いに連携する多層的なアーキテクチャにたどり着きました。CDPサービスのデータレシーバは以下の部分から成っています。

  1. レシーバ:これはI/Oフィルタなど外部応答に対する外向きの通信レイヤです。

  2. ストリームハンドル:ストリームハンドルは1つのI/Oフィルタインスタンスまたは1つのVMDK/ディスクに対応しています。ハンドルの状態に関連する情報を格納しています。

  3. ストリームハンドルマネージャ:このレイヤはスレッドプールを使用してスケジュール設定される非同期処理のための大量のロジックから成ります。すべてのストリームハンドルの管理も行います。

img


図3:CDPサービスのデータパイプラインの簡易説明図

受信されたデータはまず、各レイヤでいくつかの基本的なチェックが行われ(通し番号の増加やタイムスタンプなど)、それからインメモリバッファに格納されます。各ハンドルにはローカルバッファがあり、制限はあるものの大容量のメモリをグローバルバッファから割り当てることができます。これらのバッファは、ファイルシステムがビジ―状態で、アプリケーションにすべてのデータを一時的に書き込むのに十分なスループットを割けない場合に、保護対象の仮想マシンのI/Oバーストへの対策となります。

ストリームハンドルマネージャレイヤには、Atlasにデータをフラッシュ/同期するスレッドプールがあります。ハンドルのバッファ内にしきい値を超えるデータが格納された場合や定められた一定期間にフラッシュが行われていない場合には常にスケジューラに通知され、スレッドプールのタスクキュー内にデータをフラッシュするためのタスクがスケジュール設定されます。スレッドはFIFO(先入れ先出し)でスケジュール設定されたタスクキューからタスクを取り出します。スレッドプールでハンドルにスケジュールできるタスクは常に1つだけです。これにより、空間的局所性のメリットを活用して大規模にチャンクをまとめて書き込みながら、公平性を確保できます。

データをファイルシステムにフラッシュするようスレッドがスケジュール設定される時、特定のしきい値を超える未同期データがあったり、最後の同期から特定の設定期間以上経過していたりする場合は、Atlasへのデータの同期も同時に行われます。これにより、ほぼ常に、たとえばデータセンターが停電するような災害が突然、発生した場合でも、最新の時点への復旧が可能となります(1分未満のRPO)。

賢明な読者の皆様は、ここに調整可能な要素が数多くあることに気付かれるでしょう。それらをひとつひとつ取り上げ、どのように調整したかを見ていきましょう。

  • スレッドプールサイズ:

    • 一度にあまりに多くの書き込みがあるとファイルシステムにスラッシングを引き起こすことになるため、サイズをあまり大きくすることはできない。

    • 数値を変えながら、Atlasで得られるスループット値を確認することで調整を行った。

  • インメモリバッファサイズ:

    • システム性能に影響を及ぼさずに、Rubrikから得られるメモリ容量を確認して決定した。

    • CDPサービスがシステムに対する大きなメモリ負荷となることが決してないよう、システムのRAMの空き容量が一定のしきい値未満の場合はグローバルバッファ全体のサイズが増えないようにするというロジックによって、CDPサービスを構築している。

  • フラッシュするデータ量

    • 一回の書き込みに多くの時間を費やすのは好ましくないため、データ量を非常に大きくするのは困難なことがわかる。特にAtlasのスループットが低いときには注意が必要。

    • これは、Atlasを飽和状態にすることが可能で、この量の書き込みにかかる時間と比較した場合のスケジューリングのオーバーヘッドが非常に小さい(約0.01%)ことを確認して検証されている。Linuxがコンテキストスイッチのオーバーヘッドを最小化できるようタイムスライスを定義する仕組みと同様。

  • その後に同期するデータ量

    • データサイズを小さくするとMBごとの同期コストが増すことから、データ量を非常に小さくするのは困難なことがわかる。

    • これは、どの値のセットによってAtlasのスループットを最大化できるかを確認し、妥当な値を選択することで調整する。

これらの値の調整によって、ファイルシステムを最大限に活用することができます。CDPサービスが対応できる仮想マシンの一定の最大スループットは、Atlasが維持できる一定の最大スループットとちょうど同じでした。

さらに、CDPサービスはSLAに記載されている遠隔地へのすべてのI/Oのレプリケートも行い、レプリケーション先で1分未満のRPOへの復旧を可能にします。これを達成するために、Rubrikでは以下のようなシンプルながら効率的な手法を用いています。

  • レプリケーションのスレッドプールはインメモリバッファからデータを読み込み、それをレプリケーション先に送信する。これにより、ファイルシステムへの追加の読み込みI/Oの発行を回避し、ファイルシステムのスループットを解放できる。

  • リモートCDMクラスタへのリクエストのフォーマットをソースクラスタで受け付けるリクエストのものに合わせることで、I/Oのローカル処理のコードをすべて再利用している。

実際のところ、プライマリクラスタとは異なり、リモートクラスタの保護ワークロードは通常あまり多くないため、プライマリサイトよりリモートサイトのRPOを低く設定している場合があります 😄

まとめ

高い効率性を備えたデータプレーンを構築するには、多くの工夫をこらし、試行錯誤を重ねて、さまざまなコンピューターサイエンスの概念を巧みに組み合わせることが必要です。本ブログでは、継続的データ保護によって、さまざまなストレス要因の下にある仮想マシンを保護するにあたっての実際的な問題について見てきました。一方で、データ破損やアプリケーションバグの防止策をアプリケーションロジック自体に構築することは、これらの問題からエンジニアリング要件を作成し、チェックサム、スレッドプール、空間的局所性などの標準的手法を用いることで解決しました。合わせて、調整可能な要素の複数の組み合わせを試すことで、非常に効率的なデータプレーンを実現することができました。