設問とコンテキスト
注文サービスは、1つのビジネスオペレーション内で注文の作成、在庫の減算、および台帳エントリの書き込みを行わなければなりません。DynamoDBのコミット後にネットワークタイムアウトが発生する可能性があるため、クライアントがリクエストを再送信することがあります。TransactWriteItemsを使用して、キャパシティコストやリージョン境界を含め、アトミックな書き込み、条件、冪等なリトライ、および照合(リコンシリエーション)を設計してください。
面接官が評価するポイント
- アトミックコミット、条件付き失敗、およびネットワーク切断後の不明な結果(unknown result)を区別できているか。
ClientRequestToken、永続的なビジネス冪等性キー、および条件式を正しく使用しているか。- 追加のトランザクションキャパシティ、API制限、およびホットキー競合を考慮しているか。
- リトライ、補償、照合、メトリクス、およびクロスリージョン整合性が1つの設計としてまとまっているか。
明確化のための質問
- 注文、在庫、台帳のテーブルは同じAWSリージョンおよびアカウント境界内にありますか?
- 売り越しは許可されていますか?また、台帳はイミュータブルな追記専用(append-only)レコードである必要がありますか?
- タイムアウト後、クライアントはビジネス冪等性キーによって最終状態を問い合わせることができますか?
- トークンの有効期間を過ぎてリトライが発生する可能性はありますか?
- クロスリージョンのディザスタリカバリ書き込みが必要ですか、それとも単一リージョンでの原子性で十分ですか?
30秒回答
各ビジネスオペレーションに対して安定した冪等性キーを作成し、1つのリージョンでTransactWriteItemsを使用して、注文の作成、在庫の条件付き減算、台帳エントリの書き込みをアトミックに実行します。リクエストにはClientRequestTokenを含め、永続的なビジネス状態と条件によって重複減算を防止します。タイムアウト後は、リトライ前にビジネスキーによる読み取りを行います。競合、条件付き失敗、キャパシティ、不明な結果を監視します。クロスリージョン処理については、トランザクションのアトミック境界がリージョン単位であるため、イベントと照合を使用します。
詳細な回答
ステップ1: ビジネスインバリアント(不変条件)を定義する
インバリアントを定義します。注文が成功すると在庫が1回減算され、1つの台帳エントリが作成されます。注文および台帳レコードには1つのoperationIdを使用し、在庫項目にはavailable >= quantityを必須とします。クライアントのタイムスタンプのみをキーとして使用しないでください。リトライやクロックスキューによって重複オペレーションが発生する可能性があります。
ステップ2: トランザクションアクションを構成する
Put、Update、Delete、およびConditionCheckのアクションを1つのTransactWriteItemsリクエストに組み合わせます。注文のPutはキーが存在しないことを要求し、在庫のUpdateはバージョンまたは利用可能数量をチェックし、台帳のPutは一意のキーとしてoperationIdを使用します。1つのトランザクション内で同じ項目に対して2回操作を行わないようにし、アクション数およびリクエストサイズの制限を遵守してください。
ステップ3: 2層の冪等性レイヤーを構築する
ClientRequestTokenにより、有効期間内であれば同じトランザクションリクエストを安全にリトライできます。注文と台帳に永続化されたビジネス冪等性キーは、より長いライフサイクルをカバーします。両者は同一のオペレーションを識別しなければならず、リトライ時に新しいビジネスキーを生成してはなりません。トークンの有効期間後は、トランザクションを再構築する前にビジネス状態を読み取ります。
ステップ4: 失敗と不明な結果を分離する
条件競合、キャパシティエラー、バリデーション失敗は通常、実行可能な失敗パスを提供します。エラーに応じてビジネスエラーを返すか、制限付きのバックオフを伴うリトライを実行します。送信後の接続切断は結果が不明(unknown)です。直ちに在庫を元に戻してはいけません。operationIdによって注文、在庫バージョン、台帳を読み取り、ステートマシンにリトライまたは照合を選択させます。
ステップ5: コストとホットキーを考慮する
DynamoDBはトランザクションの準備とコミットのために基礎となる読み取りまたは書き込みを実行するため、キャパシティ使用量は通常の単一書き込みよりも高くなります。項目サイズ、同時実行性、リトライの増幅からスループットを見積もり、ホットな在庫項目をシャーディングするか予約キューを使用します。平均WCUだけでは不十分です。条件付き失敗や競合もレイテンシとキャパシティの予算を消費します。
ステップ6: リージョン要件を処理する
トランザクションの原子性は、呼び出し元リージョン内のトランザクション境界に適用されます。分析環境やレプリカが別の場所にある場合は、operationIdを含むイベントを発行します。コンシューマは冪等に書き込み、照合によって欠落や重複を検出します。レプリケーションの遅延中、リモートのリードモデルは即時のトランザクションコミットの証明にはなりません。
ステップ7: オブザーバビリティとリカバリ
トランザクションの成功、条件付き失敗、競合、スロットリング、リトライ回数、不明な結果、テーブルごとのキャパシティ、エンドツーエンドのレイテンシを記録します。PENDING、COMMITTED、RECONCILING、FAILEDなどの状態を使用します。スキャナーが不明な状態を処理し、台帳を完了させるか手動処理用のキューを作成します。リクエストログ、テーブル項目、イベントをoperationIdで関連付けます。
モデル回答
各注文に対して安定したoperationIdを作成し、1つのリージョンでTransactWriteItemsを使用して、注文の作成、在庫の条件付き減算、およびそのIDをキーとする台帳項目の書き込みをアトミックに実行します。注文はキーが存在しないことを要求し、在庫はそのバージョンとavailable >= quantityをチェックし、台帳は自然に重複排除されます。リクエストには安定したClientRequestTokenも含めます。条件付き失敗は説明可能なビジネスエラーを返し、コミット後のタイムアウトでは、無闇に在庫を戻すのではなく、まずoperationIdによって3つのレコードすべてを読み取ります。キャパシティの見積もりには、トランザクションの準備とコミットの処理、ホットキー、リトライの増幅を含めます。クロスリージョンへの伝播には、クロスリージョンの原子性を主張するのではなく、冪等なイベントと照合を使用します。メトリクスには、競合、キャパシティ、不明な結果、ステートマシンの復旧時間を網羅します。
よくある間違い
- タイムアウトをトランザクション失敗の証拠として扱い、直ちに在庫を元に戻すこと。
- リトライのたびに新しいビジネスキーを生成し、注文や台帳エントリの重複を引き起こすこと。
ClientRequestTokenのみに依存し、永続的なビジネス冪等性を省略すること。- 条件競合、トランザクション制限、および追加のトランザクションキャパシティを無視すること。
- グローバルテーブルのレプリケーションやリモート読み取りをトランザクションコミットの証拠として扱うこと。
- ログの手動検査以外に、不明な状態のスキャナーや照合パスを用意していないこと。
フォローアップの質問
フォローアップ1: ClientRequestTokenは永続的な冪等性を保証しますか?
いいえ。APIで定義された有効期間のみをカバーします。長期的な冪等性には、注文、台帳、またはオペレーションテーブルにおけるビジネスキーと最終状態が必要です。
フォローアップ2: 在庫の条件失敗はリトライすべきですか?
在庫不足の場合、リトライしても結果は変わらないため、ビジネス失敗を返すべきです。一時的な競合やスロットリングは、バックオフ、同一のオペレーションキー、制限付きの試行回数でリトライできます。
フォローアップ3: タイムアウト後の結果はどのように判断しますか?
operationIdによって注文、在庫バージョン、台帳を読み取ります。整合性のあるレコードはコミットを示します。部分的な可視性や不一致がある場合はRECONCILINGに移行し、ワークフローによって完了処理または手動対応を選択します。
フォローアップ4: クロスリージョンの書き込みを1つのトランザクションにまとめないのはなぜですか?
APIは複数のリージョンにわたって原子性を拡張しないためです。結果整合性のウィンドウと機能低下時の動作を文書化した上で、イベント、冪等なコンシューマ、および照合を使用します。
フォローアップ5: トランザクションの競合はどのように特定しますか?
operationId、項目キー、条件バージョン、リトライ回数をログに記録し、ホットキーごとに競合を集計します。持続的に競合が発生する在庫項目には、シャーディング、事前予約、またはキューベースの割り当てが必要になる場合があります。
フォローアップ6: 不明な結果のパスはどのようにテストしますか?
サーバーがコミットを確認した後にレスポンスを破棄して、クライアントのタイムアウトをシミュレートします。ルックアップ、リトライ、状態遷移、イベント重複排除、および照合を検証し、在庫と台帳が2重に適用されないことを確認します。