> [!abstract] 概要(原文 Abstract の日本語訳)
> 現代のアプリケーションは、様々な機能をクラウドサービスに依存するクラウドベースのプログラミングモデルへと移行しつつある。こうした「クラウドネイティブ」な実践は、アプリケーションの展開を大幅に簡素化し、クラウドの恩恵(例えば可用性)を実現する。一方で、不透明なクラウドと予測しづらいインターネット接続の障害モデルに対処するという、新たな信頼性の課題を課す。
>
> 本論文では、これらの信頼性の課題を論じる。我々は、クラウドを利用するアプリケーションを一般的な一時的障害に対して脆弱にするバグの taxonomy(分類法)を開発する。一回の REST 呼び出しインタラクションのエラーの(誤った)処理だけでも、アプリケーションの正しさに悪影響を与えうることを示す。
>
> 我々は、これらの課題に対処する第一歩として、あらゆるクラウドを利用するアプリケーション向けの基本的な SDK ユーティリティとして、Rainmaker という名の「push-button」型信頼性テストツールを構築する。Rainmaker は、開発者が新しいポリシー・オラクル・テストケースを書く必要なく、クラウドベースの障害モデルの下で起こりうる無数のエラーを想定するのを助ける。Rainmaker は既存のテストスイートと直接連携し、既存のテスト環境向けのプラグアンドプレイ型ツールである。Rainmaker はアプリケーションとクラウドサービスとのインタラクションに障害を注入する。これは REST 層で行われるため、テスト対象のアプリケーションに対して透過的である。さらに重要なことに、Rainmaker は分類したバグパターンの各種をカバーする自動フォールトインジェクションポリシーと、既存のインハウスなソフトウェアテストを活用する自動オラクルを組み込んでいる。現時点で、Rainmaker は 11 個の広く使われるクラウドを利用するアプリケーションにおいて 73 件のバグ(確認 55 件・修正 51 件)を検出した。
## 論文情報
- タイトル: Push-Button Reliability Testing for Cloud-Backed Applications with Rainmaker
- 著者: [[Yinfang Chen]]・[[Xudong Sun]]([[University of Illinois Urbana-Champaign]])、[[Suman Nath]]([[Microsoft Research]])、[[Ze Yang]]・[[Tianyin Xu]]([[University of Illinois Urbana-Champaign]])
- 媒体: 20th USENIX Symposium on Networked Systems Design and Implementation(NSDI '23)、2023年4月17–19日、Boston, MA
- ページ: pp. 1701–1716
- コード: https://github.com/xlab-uiuc/rainmaker
- 発表スライド: https://www.usenix.org/system/files/nsdi23_slides_chen-yinfang.pdf(本 ingest では未取り込み。§0.6 の対象は明示要求時のみ)
## 概要
クラウドを利用するアプリケーション(cloud-backed applications)は、REST API/SDK 経由でクラウドサービス(Azure Storage・AWS S3 等)に依存するが、クラウドサービス・SDK 側のエラー通知には標準や一貫性がない。本論文はこの不整合に起因する 4 パターンのエラー処理バグの taxonomy を提示し、それらを push-button(コード変更・ポリシー記述不要)で検出する HTTP プロキシ型フォールトインジェクションツール Rainmaker を構築、11 個の実運用 .NET アプリケーションで 73 件の新規バグを発見した。
## 問題設定
- **対象**: RESTful なクラウドサービス(Azure Storage・Azure CosmosDB・AWS S3・AWS SQS 等)を利用する既存のクラウドを利用するアプリケーションと、そのテストスイート。
- **入力**: 既存のテストスイート(コード変更なし)と、望む網羅率指標(§4.2.2)。
- **前提となる課題**(Figure 1): 従来型アプリケーションは POSIX のような標準化された共有障害領域(ライブラリ呼び出し・システムコール)を持つのに対し、クラウドを利用するアプリケーションの障害領域はクラウドサービスごとに異種で予測不能・不透明である。
- **エラー通知の 3 要素**の不整合(§2.1–2.2.1):
1. クラウドサービスからのエラー応答(HTTP ステータスコード + サービス固有のエラーコード。例: Azure Blob Storage は同一の HTTP 409 に対し 44 種の異なるエラーコードを持つ)。
2. 一時的エラーに対する SDK の自動リトライ(Table 1: Azure Storage・CosmosDB・AWS S3/SQS でリトライ対象のステータスコードが異なり、同一プロバイダでも言語別 SDK 間で挙動が異なる)。
3. リトライ失敗・恒久的エラーをアプリケーションへ伝播する方法(例外化)。
- **中心的な技術課題**: 非冪等な REST API へのリトライは、無自覚な状態不整合(remote data corruption)を招きうる。加えてクラウド障害は稀にしか発生しないため、小規模・短時間の機能テストではこの種のバグを見逃しやすい(§2.2.2)。
![[_attachments/nsdi23-chen-yinfang/fig01-fault-domains.png]]
**Figure 1: 従来型アプリケーションとクラウドを利用するアプリケーションの障害領域比較**
(Figure 1. (a) 従来型アプリケーションは Application → Database/Storage という共有・標準化された障害領域(syscall・lib call)を持つ。(b) クラウドを利用するアプリケーションは REST call を介して Database Service・Storage Service と通信し、一時的障害(transient fault)・低速接続・サーバービジー・内部サーバーエラーという異種の障害に直面する。Source: Figure 1, §1.)
## 提案手法
### バグ taxonomy(§3)
一回の REST API 呼び出しインタラクション(とその SDK リトライ)に閉じた障害モデルの下で、エラー処理が壊れるパターンを 4 分類する。
![[_attachments/nsdi23-chen-yinfang/fig02-bug-taxonomy.png]]
**Figure 2: エラー処理バグの taxonomy**
(Figure 2. Transient Error Handling Bugs は No Error Handling(§3.1)と Buggy Error Handling に分岐し、後者はさらに Throwing Unrelated Exceptions(§3.2)・Silent Semantic Violations(§3.3)・State Divergence(§3.4)の 3 種に分岐する。taxonomy は一つの REST API 呼び出しインタラクション中に発生した一時的エラーの処理ロジックのみを対象とする。Source: Figure 2, §3.)
1. **No Error Handling(§3.1)**: アプリケーションが特定の一時的エラーを一切処理しない。例えば Azure Storage .NET SDK v12.3.0 以前は一部の一時的エラーコードをリトライしないため、アプリケーションが「SDK が全ての一時的エラーをマスクする」と誤って想定しているとクラッシュ等につながる。
2. **Throwing Unrelated Exceptions(§3.2)**: エラー処理の誤りが、根本原因とは無関係の新たな未処理エラーを生む。典型例はリトライで、タイムアウトが応答経路で起きた場合(元のリクエストはサービス側で成功済み)、リトライは元のリクエストが前提条件を無効化したことで異なるエラーで失敗する。Microsoft BotBuilder の実例(Figure 3、本ページでは図として未収録)では、Azure Blob Storage への Blob 作成がタイムアウト後に自動リトライされ、Blob が既に作成済みのため 409(BlobAlreadyExists)で失敗し、この無関係な例外が while ループを破壊してログ記録が失われる。
3. **Silent Semantic Violations(§3.3)**: 誤ったエラー処理が観測可能な症状を出さずに REST API 仕様のセマンティクスを違反する。例えば Microsoft Orleans は Azure Queue Storage の `GetQueueMessage()` を非冪等な `ReceiveMessagesAsync` で実装しており、タイムアウトによる複数回リトライがキュー全体を空にしてしまう(呼び出しは「メッセージを1件取得する」という API 仕様に違反)。
4. **State Divergence(§3.4)**: ローカル状態とリモート状態が乖離する。楽観的にローカル状態を更新した直後に REST 呼び出しが一時的エラーで失敗し、その復元(rollback)が行われない場合に発生する。Microsoft BotBuilder の実例(Figure 5)では、コンテナ作成前にローカルのコンテナ一覧へ追加してしまい、実際の `CreateBlobContainer` 呼び出しが 503 で失敗すると、ローカル側にダングリングなコンテナ参照が残りクラッシュを招く。
### アーキテクチャ(§4.1, §4.5)
Rainmaker は既存のテストスイートを変更せずに動作する「push-button」ツールであり、スタンドアロンの HTTP プロキシとしてアプリケーションからのアウトバウンド REST API 呼び出しを傍受する。HTTP プロキシの実装には MockServer([[MockServer]] とは別。論文注 [18])を用い、フォールトインジェクションポリシーは MockServer のルールとして Java で実装、オラクルは Python で実装する。Windows Internet Services のシステムプロキシとして登録し、あらゆる REST API 呼び出しアプリケーションに透過的に適用できる。HTTP 層での介入は (1) SDK リトライを含む細粒度の REST 呼び出しを傍受できる、(2) HTTP ステータスコード単位でエラー処理を扱える、(3) アプリケーションの言語・アーキテクチャに依存しない、(4) 複雑な例外オブジェクトでなく HTTP レスポンスの操作だけで済むという 4 つの技術的利点をもたらす。
### アルゴリズム/手法の詳細
**フォールトインジェクションポリシー(§4.2.1)**: taxonomy の 4 パターンを網羅するのに、わずか 4 種類のポリシー P1–P4 で足りることを示す。
![[_attachments/nsdi23-chen-yinfang/fig06-fault-injection-policies.png]]
**Figure 6: Rainmaker のフォールトインジェクションポリシー P1–P4**
(Figure 6. P1(最初の応答のみタイムアウト)は前提条件無効化に起因するバグを、P2(全応答をタイムアウト)は silent semantic violation と state divergence を、P3(全リクエストに 5XX を返す)は state divergence を、P4(最初の応答をタイムアウトし以降のリクエストに 5XX を返す)も state divergence を誘発しうる。デフォルトでは request 側に 503(ServiceUnavailable)、response 側にタイムアウトを注入する。リトライしない REST 呼び出しでは 4 ポリシーは 2 種類に縮退する。Source: Figure 6, §4.2.1。バグパターンとポリシーの対応は Table 2 に整理される。)
**網羅率指標と call-site 追跡(§4.2.2)**: テストスイートが発行する REST 呼び出しは膨大(1アプリで数千〜数百万件)なため、全件への注入は非現実的(Orleans では 588 日を要すると推定)。Rainmaker は C1(全テストの最初の REST 呼び出しのみ)からC4(全テストの全ユニーク call site、同一 call site には最初の呼び出しのみ注入)までの 4 段階の網羅率指標(Table 3)を提供し、既定は最も網羅的な C4 を用いる。HTTP プロキシは別プロセスであるため呼び出し元コードの call site が直接見えないという課題に対し、(1) .NET プロファイリング API による自動計装で SDK API 呼び出しを検出、(2) inheritable thread-local storage (ITLS) を用いて非同期実行下でも子スレッドへ call site 情報を伝播させ、HTTP ヘッダー経由でプロキシへ渡す、という 2 つの技術で解決する。テスト実行計画は、まず無注入のリファレンス実行で各テストの実行時間と発行される REST 呼び出しを観測し、その後オフラインで(C3 は線形計画法(LP)ソルバを用いて)最小限のフォールトインジェクション対象を選ぶテストプランを生成する。
**テストオラクル(§4.3)**: アプリケーション固有知識に依存しない汎用オラクルを 2 種用意する。
- **Exception Oracle(§4.3.1)**: (1) テストが例外で失敗し、(2) その例外がテストコードでなくアプリケーションコード内で生成され、(3) その例外が注入した障害と不整合である、という 3 条件を満たす場合のみバグとして報告する。条件(3)により、「意図的にハンドリングしようとしたが不十分だった」ケースのみを拾い、単純な想定内の例外伝播を除外する。
- **Assertion Violation Oracle(§4.3.2)**: 例外でなくアサーション違反でテストが失敗した場合にバグ候補として報告する。注入した一時的障害が正しく処理されていればアサーションは違反されないはずという前提に基づく。
**診断支援(§4.4)**: call site 情報とランタイム例外・アサーションのコールスタックを紐付け、バグ再現(同じフォールトインジェクション計画の再実行)を可能にする。
### 実装上の工夫
- 新しいクラウドサービスのサポート追加には、(1) SDK ネームスペース(例: `Azure.Storage*`)と (2) リクエスト ID タグ(例: `x-ms-client-request-id`)の 2 つの設定のみが必要という軽量な拡張性を持つ。
- .NET コアライブラリのわずか 4 つの HTTP クライアント API ファミリ(例: `HttpClient.SendAsync`)を計装するだけで、全 Azure SDK からのアウトバウンド HTTP 呼び出しを捕捉できる。
- REST/SDK API の仕様(冪等性など)を意図的にポリシーへエンコードしない設計方針。仕様は保守コストが高く、しばしば不完全・陳腐化するため。
## 新規性
- 既存のフォールトインジェクション研究(Envoy・Istio 等の HTTP 層ツールを含む)は、基本的なランダム化ポリシーとクラッシュオラクルしか提供せず、開発者が自前でポリシー・オラクルを実装する必要があった。Rainmaker は taxonomy に基づく自動ポリシーと汎用オラクルを組み込むことで、これを不要にする(push-button 化)。
- アプリケーション・ドメイン固有知識に依存する既存手法(データベースの一貫性・分離性検査、ファイルシステムのクラッシュ一貫性検査等)は特定領域にしか使えないが、Rainmaker はどのクラウドを利用するアプリケーションにも適用可能な基本ユーティリティとして設計されている。
- プログラムレベルのフォールトインジェクション(例外・errno 注入)は、(1) silent semantic violation のような粒度の細かいバグを捉えられない、(2) 複雑な例外オブジェクトの構築が非自明、(3) クラウド側の状態を考慮できない、という 3 つの限界を持つ。Rainmaker は REST インタフェース層への注入によりこれらを回避する。
- [[障害注入]] の既存議論(ChaosMesh 等によるマイクロサービス間のランタイム注入)とは軸が異なり、Rainmaker は「単一アプリケーションと RESTful マネージドクラウドサービスの境界」という新しい注入点を確立した。
## 実験設定
- **対象アプリケーション**: 6 種のクラウドサービス(Azure Blob/Queue/Table Storage・CosmosDB、AWS S3/SQS)を利用する 11 個の .NET アプリケーション(Table 4)。GitHub スター数 20〜11.7K、コード規模 1.3K〜842.4K 行。Microsoft 製の Orleans・BotBuilder・EF Core・FHIR Server、NuGet の Insights、Petabridge の Alpakka などを含む。
- **テスト実行環境**: Azure 系サービスは Azurite(Blob/Queue/Table)・CosmosDB エミュレータで実行、AWS 系(S3/SQS)は公式エミュレータが存在しないため実サービスで実行。
- **比較対象**: exhaustive(全 REST 呼び出しへの注入)を baseline とし、C1–C4 の 4 種の網羅率指標と比較。
- **評価指標**: 検出した新規バグ数・確認数・修正数、テストオラクルの誤検知率、網羅率指標ごとのテスト実行回数・実行時間。
## 実験結果
- **バグ発見(§5.1、Table 5)**: 73 件の新規バグを発見(No Error Handling 29 件、Throwing Unrelated Exceptions 23 件、Silent Semantic Violations 4 件、State Divergence 17 件)。66 件を報告済みで、うち 55 件が確認、51 件が修正された。全 11 アプリケーションでバグを検出しており、Table 6 によると unrelated exception の外部化(36 件)・操作失敗(35 件)・不正な結果/状態(13 件)・アプリケーションクラッシュ(11 件)・データ損失/アクセス不能(4 件)・リソースリーク(2 件)という深刻な帰結を伴う(1 バグが複数の帰結を持つ場合を含む)。
- **誤検知率(§5.2)**: 2,654 件のテスト失敗のうち誤検知はわずか 52 件(1.96%)。もしオラクルなしで例外を直接報告していたら 3.07 倍の誤検知が生じていたと試算。誤検知の主因は Insights の無効リクエストテスト(10 件)と Alpakka/IronPigeon のフレーキーテスト(42 件、短い接続タイムアウトが注入で誘発される)。
- **実行時間と網羅率のトレードオフ(§5.3、Table 8、Figure 9)**: C4 は baseline(exhaustive)と比べて平均 64.47% のテスト実行回数を削減しつつ、C1–C3 が検出する全てのバグを検出する。Orleans では反復ストレステストの重複 REST 呼び出しを「同一 call site への注入は 1 回のみ」というルールで削減し、394,172 件(99.04%)のテスト実行を削減(削減なしでは 588 日を要する試算)。全アプリケーションの実行時間は 0.57–212.77 マシン時間(C4)。
![[_attachments/nsdi23-chen-yinfang/fig09-coverage-vs-bugs.png]]
**Figure 9: 網羅率指標ごとのテスト実行回数とバグ検出数**
(Figure 9. 棒グラフ(左軸、対数)は baseline・C1–C4 各指標のテスト実行回数、赤い点線(右軸)はその指標で検出されたバグ数を示す。Orleans では baseline が10万件超のテスト実行を要するのに対し C4 は大幅に削減しつつ全バグを検出する。アプリケーションによっては C1(最小網羅率)でも C4 と同数のバグを検出する場合がある一方、Storage.NET のように網羅率を上げるほど検出バグ数が増える場合もある。Source: Figure 9, §5.3。)
## 考察
- Rainmaker の有効性は既存テストスイートの充実度に依存する。例えば Microsoft Orleans では 7,002 件中 155 件のテストしかクラウドサービスと相互作用しない。より一般的なプラクティスである REST API のモック化は Rainmaker では利用できないため、著者らはモックテストを自動的に書き換えて Rainmaker が利用可能な形にすることを将来課題として挙げる。
- 発見したバグの中には修正が容易でないものもある。例えば応答経路でのタイムアウトは、失敗したリクエストがクラウドサービス側で実際に成功したかどうかを SDK/アプリケーションが知る手段を持たない。著者らは HTTP ETag ベースのバージョニングやトランザクション的な API サポートといったサーバー側の支援が非冪等 API の問題緩和に役立ちうると指摘する。
- Rainmaker のプロトタイプは .NET 限定だが、HTTP プロキシによる注入というアイデア自体は言語非依存であり、動的計装・inheritable thread-local storage も .NET 固有ではなく Java 等でも利用可能と論じる。
- 評価過程で、AWS S3 の同一 REST API がリージョンによって異なる一貫性保証を持つなど、クラウドサービス自体の正しさの問題も観測しており、Rainmaker を将来的にクラウドサービス側のバグ検出にも拡張しうると示唆する。
- 本 taxonomy・ポリシーは「一つの REST API 呼び出しインタラクション」に閉じたモデルであり、複数の相関する呼び出し(例: あるサービスへの書き込みと別サービスからの読み込みの間の不整合)にまたがるバグは対象外と論文自身が明言する(著者らは "investigating" と述べるのみで具体策は示していない)。
## 強み / 弱点・課題
**強み**
- 既存テストスイートへのコード変更を一切要求しない「push-button」性と、HTTP プロキシによる言語非依存の透過的注入。
- taxonomy に基づく網羅的な自動ポリシー(P1–P4)と、既存のテストのアサーション・例外を再利用する低コストなオラクル設計。
- call-site 単位の網羅率指標と ITLS による call site 伝播により、非同期実行下でも効率的なテスト計画(exhaustive 比 64.47% 削減)を実現。
- 11 個の実運用アプリケーションでの評価により 73 件の新規バグ・低誤検知率(1.96%)という実証的な有効性を示した。
**弱点・課題**
- taxonomy とポリシーは単一の REST API 呼び出しインタラクションに限定され、複数呼び出しにまたがる相関バグ(cascading な不整合)を扱えない(論文が明言する限界)。
- Exception Oracle は不完全であり、No Error Handling パターン(§3.1)についてはユニットテストレベルでは判定不能な場合があると論文自身が認める。
- 有効性はテストスイートがクラウドサービスと相互作用するテストをどれだけ含むかに依存し、モックベースのテスト環境ではそのままでは使えない。
- .NET 実装に限定されたプロトタイプであり、他言語への一般化は将来課題として述べられるに留まる(具体的な移植は未実施)。
- 網羅率指標が高いアプリケーション(EF Core・FHIR Server 等)では数百マシン時間規模の実行コストがかかる(Table 8: 最大 212.77 時間)。
## 関連
- ソース: [[@2026__UIUC PhD Thesis__Agentic Failure Management of Cloud Systems]](本論文の内容は同博士論文第2章の一次論文にあたる)
- 概念: [[障害注入]]
- エンティティ: [[Rainmaker]] / [[Yinfang Chen]] / [[Xudong Sun]] / [[Suman Nath]] / [[Ze Yang]] / [[Tianyin Xu]] / [[University of Illinois Urbana-Champaign]] / [[Microsoft Research]]
- 関連 MOC: [[LLM4SRE - MOC]] / [[SRE - MOC]]