コンテンツに移動
データベース

カオステストで Spanner のフォールト トレラント設計の信頼性をさらに強化

2024年5月29日
James Corbett

Software Engineer

※この投稿は米国時間 2024 年 5 月 10 日に、Google Cloud blog に投稿されたものの抄訳です。

Spanner の信頼性を裏付けているものの一つは、信頼性チームによる幅広いカオステストの実施です。カオステストは、本番環境同様のデータベース インスタンスに意図的に障害を注入するプロセスです。エンジニアは「ハッピーパス」のテストに重点を置きますが、ほとんどのソフトウェア バグは異常時に発生します。Given Spanner のアーキテクチャは複雑で、またコードベースは絶えず進化していることを考えると、バグが入り込むことは避けられません。ここでは、Google で採用しているカオステストのタイプと、そのテストで検出されるバグの種類の概要を説明します。

フォールトトレラント設計の基盤

Spanner は、故障率が低いマシン、ディスク、ネットワーク ハードウェアなど、「ほとんどは信頼できる」コンポーネントで構築されています。とはいえ、異常は発生するものです。メモリやディスクの不良によってデータの破損が生じる場合もあれば、ファイル アクセスによって一時的または永続的なエラーや破損が発生する場合もあります。また、データセンター内またはデータセンター間のネットワーク接続が制限されたり完全に失われたりする場合もあります。最悪な場合には、ソフトウェア バグによって同じバージョンのコードを実行しているすべてのサーバーで相関障害が発生することもあります。

正確性と可用性のどちらも重要であるため、Spanner は、フォールトトレラント設計の原則を使用して、これらのコンポーネントの障害をマスクして信頼性の高いサービスを実現しています。たとえば、データの破損を検出するために、さまざまなレベルでチェックサムが使用されています。データベースのフラグメントが保存された Spanner タブレットは、3 つまたは(通常は)それ以上のデータセンター間で複製され、読み取りと書き込みにはPaxos を使用して、分散状態のコンセンサスと整合性を実現しています。また、チェックサムは、タブレット レプリカの破損の検出にも使用されています。これらのタブレットのデータはファイルに保存されており、ファイル システムは破損したブロックの検出にチェックサムを使用し、データセンター内にデータブロックの複数のコピーを保持します。最後に、新しいソフトウェア バージョンをリリースする際には、新しいバグによって引き起こされる可能性のある異常に注意しながら、慎重に作業を進めます。

カオステストによる信頼性の向上

Google では、Spanner の設計と実装が実際に障害をマスクして信頼性の高いサービスを提供していることを検証するために、毎週 1,000 件を超えるシステムテストを実施しています。テストごとに、数百のプロセスで構成された、本番環境同様の Spanner インスタンスを作成します。これらのプロセスは、本番環境の Spanner と同じコンピューティング プラットフォーム上で実行され、同じ依存システム(ファイル システム、ロック サービスなど)を使用します。ほとんどのテストは 124 時間実行され、数万あるいは数十万のトランザクションを実行します。

本番環境での実際の障害は、非常に低い確率で発生します。Spanner のエラー処理やフォールト トレラントのメカニズムもテスト範囲に含めるために、こうしたシステムテストでは、はるかに高い確率で障害(ファイルエラーやネットワーク エラーなど)を注入します。

これらの障害によってバグが発見された場合、テストは次のいずれかの状態で失敗します。

  1. データベースに対する読み取りまたはクエリが期待される結果を返さない。ランダムに生成されたデータが入力されたデータベースに対する、ランダムに生成された読み取り / クエリの予想される結果を算出できるようにするのは、簡単なことではありません。Spanner 強整合性モデルは、読み取り / クエリの結果を効率的に検証するための鍵となります。各トランザクションはその効果を要約したログを記録し、後続のトランザクションはこれらのログを再生して、モニタリングすべき状態を算出します。これについては、以前の記事で詳しく説明しています。

  2. Spanner API 呼び出しが予期しないエラーを返す。

  3. Spanner サーバーが予期しない方法でクラッシュする。注入した障害によってはサーバーがクラッシュしますが、そのようなクラッシュを除外して、新しい予期しないクラッシュが発生した場合にのみテストを不合格にします。

  4. Spanner の内部整合性チェッカーの一つが問題を報告している。チェックサムは以下について検証します。

    1. ファイルが漏洩していない(Unix fsck のようなものですが、分散ファイル システムで検証)

    2. セカンダリ インデックスが、インデックス付けされたテーブルと一致している

    3. 宣言されたチェックと外部キー制約が満たされている

    4. タブレットのすべてのレプリカが等しい

では、Spanner のカオステストを行う際に注入する障害の種類を見てみましょう。

1. サーバーのクラッシュ

注入する最も基本的な障害の一つは、(Unix SIGABRT シグナルなどを使用して)サーバーを強制的に突然クラッシュさせることです。この単純な障害により、次のような多数の複雑な障害復旧ロジックが実行されます。

  1. サーバーはディスクベースのログを使用してメモリ内の状態の損失を防ぎます。そのため、クラッシュが発生すると、クラッシュしたサーバーにあったすべてのタブレットの状態をログから復元するロジックが実行されます。

  2. ロックはメモリ内に保持されるため、クラッシュしたサーバーによって調整されているすべての分散トランザクションは中断されて再起動される必要があります。

  3. クラッシュしたサーバーから読み取りやクエリによってデータを取得していたクライアントは、別のレプリカに強制的にフェイルオーバーされます。クライアントは、最初からやり直すのではなく操作を再開する必要があり、結果が失われたり重複して作成されたりすることはありません。

再起動ロジックは非常に複雑であり、サーバーをクラッシュさせずに再起動をトリガーして、結果のストリーミングのさまざまなポイントで再起動ロジックを実行することもあります。

2. ファイルの障害

Spanner サーバーは、永続データを Colossus ファイル システムに保存します。システムテストでは、このファイル システムへのすべての呼び出しをインターセプトし、次のようなさまざまな種類の障害をランダムに注入します。

  1. エラーコード: ファイル システム呼び出し(OpenCloseReadWrite など)がサーバーにエラーコードを返すようにします。再試行できる一時的なエラーを示すコードと、永続的なエラーを表すコードがあります。

  2. コンテンツの破損: Read / Write 呼び出しによって読み取られた / 書き込まれたコンテンツを破損させます。チェックサムでこれが検出されるはずです。

  3. リクエストのブラックホール: データセンターのファイル システムを、メンテナンスのために無効にする場合があります。これにより、ファイル システムが再度有効になるまで、ファイル システム呼び出しはハングします(返しません)。ファイル システムを読み取り専用に設定した場合は、書き込みのみがハングします。Spanner はこれを検出して、別のデータセンターにある代替レプリカを使用するようにフェイルオーバーする必要があります。

たとえば、私たちは、カオステストを通じて、Spanner タブレットの圧縮と Colossus ストレージ レイヤの相互作用に関連するバグを見つけました。Spanner タブレットは、メモリ内テーブルと Colossus ファイルセットとともに、ログ構造化マージツリーを使用して格納されます。ファイル数を制限するために、タブレットは複数のファイルを 1 つに結合することで定期的に圧縮されます。このテストでは、まれに発生する Colossus エラーコードをランダムに注入しました。圧縮コードがそれをファイルの終わりを意味するコードとして扱った結果、ランダムなデータ損失が発生したことが判明しました。このようなテストにより、複雑なシステムの相互作用から生じるわずかなデータ破損の問題が、本番環境に持ち込まれる可能性を極力排除しています。

3. RPC の障害

Google のリモート プロシージャ コール(RPC)システムを使用すると、送信 RPC をさまざまな方法でインターセプトしたり操作したりできます。このメカニズムを使用して、次のようなさまざまな障害を注入できます。

  1. 遅延を挿入して、タイムアウトをトリガーします。

  2. 一時的または永続的なエラーを挿入して、さまざまなサービス / API のエラー処理コードを実行します。

  3. 特定の(シミュレートする)データ センターへの RPC をブロックして、ネットワーク パーティションをシミュレートします。

  4. 特定の依存システムへの RPC をブロックしたりエラーを返させたりして、そのシステムがダウンした場合に何が起こるかをシミュレートします。たとえば、Spanner のデータファイルは暗号化されており、これらのファイルのキーは、各データセンターで実行されている個別のキーサービスから RPC 経由で取得されます。このキーサービスが停止すると、データセンター内のレプリカは事実上停止しますが、クライアントが他の正常なレプリカにフェイルオーバーするのが妨げられてはいけません。

  5. 特定のネットワーク優先順位を持つ RPC を削除して、ネットワーク スロットリングの影響をシミュレートします。データセンター間リンクが飽和状態になると、優先順位の低いパケットは破棄されます。一部の RPC は他の RPC よりも重要度が高く、このテストにより、重要な RPC に適切なネットワーク優先順位が設定されているかを確認できます。

4. メモリ / 割り当ての障害

サーバーはメモリ不足に陥ると、プッシュバックと呼ばれる状態になります。この状態になると、クライアントは負荷を他の(それほどビジーではない)レプリカにリダイレクトします。この動作をテストするためにサーバーを強制的にプッシュバック状態にし、サーバーがこの状態でスタックしないか確認します。また、ときにはコンテナがサーバーを強制終了するのに十分なメモリリークを発生させてサーバーを強制的に停止させ、この厄介な状況がうまく処理されるかを確認することもあります。

Spanner では、ユーザーごとにディスク容量、メモリ、フラッシュ ストレージの割り当てが適用されます。これらの上限に達すると、操作は特別な「割り当て超過」エラーで失敗します。このような障害を注入して、スタックを通じてそれが適切に処理されるかを確認します。

5. クラウドの障害

Google Cloud Platform から Spanner へのアクセスは、Spanner API フロントエンド サーバーによって仲介され、Google Cloud に送信されるリクエストを Google Front End を介して Spanner データベースにプロキシします。外部クライアントは、Spanner データベースとのセッションを開き、これらのセッションでトランザクションを実行します。Spanner では、Spanner API フロントエンド サーバーをクラッシュさせ、セッションを他の Spanner API フロントエンド サーバーに強制的に移行します。これは、(遅延する場合があることを除き)クライアントにはわからないようにする必要があります。

6. リージョンの停止

システムテストでシミュレートする最大の障害は、リージョン全体の停止で、Spanner が他のリージョンのクォーラムからデータを提供するようにします。システムテストの大部分では、ファイル システムまたはネットワークの停止によってトリガーされるさまざまな種類のリージョンの停止をシミュレートし、Spanner がサービスの提供を続行するか検証します。この復元力は Paxos アルゴリズムの特性であり、レプリカのクォーラム(3 個中 2 個、または 5 個中 3 個)が正常である限り、進行が保証されます。

信頼性において高い評価を得ている Spanner

Spanner はフォールト トレランスを重視して設計されています。Google は、カオステストを採用した、大規模なランダム化したシステムテストを多数実行することで、Spanner の信頼性を継続的に検証しています。

Spanner の独自性や使用例について詳しくは、こちらをご覧ください。または、90 日間無料で、あるいは月額わずか 65 米ドルで、中断を伴う再構築やダウンタイムなしでビジネスの成長に合わせて拡張できる本番環境対応のインスタンスを実際にお試しください。

-ソフトウェア エンジニア James Corbett

投稿先