冪等性
同じ操作を何度実行しても結果が変わらない性質で、分散システムの信頼性を支える
分散システムAPI
冪等性とは
冪等性 (Idempotency) は、同じ操作を何度実行しても結果が変わらない性質である。ネットワーク障害でリトライが発生する分散システムでは、冪等性がないと二重処理 (二重課金、二重注文) が発生する。
HTTP メソッドの冪等性
HTTP メソッドの冪等性を以下にまとめる。
| メソッド | 冪等 | 安全 | 説明 |
|---|---|---|---|
| GET | ✅ | ✅ | 何度取得しても同じ結果 |
| PUT | ✅ | ❌ | 同じデータで何度更新しても同じ状態 |
| DELETE | ✅ | ❌ | 既に削除済みなら何も起きない |
| POST | ❌ | ❌ | 実行するたびに新しいリソースが作成される |
| PATCH | ❌ | ❌ | 操作内容による |
POST を冪等にする: 冪等キー
POST を冪等にする: 冪等キーのコード例を示す。
// クライアントが一意の冪等キーを生成
const idempotencyKey = crypto.randomUUID();
fetch('/api/orders', {
method: 'POST',
headers: { 'Idempotency-Key': idempotencyKey },
body: JSON.stringify({ productId: 'P1', quantity: 2 }),
});
DynamoDB の条件付き書き込み
DynamoDB の条件付き書き込みのコード例を示す。
// 冪等な書き込み: 同じ orderId で 2 回実行しても 1 件だけ作成
await db.put({
TableName: 'orders',
Item: { orderId, ...orderData },
ConditionExpression: 'attribute_not_exists(orderId)', // 既に存在したらエラー
});
Lambda Powertools の Idempotency
Lambda Powertools の Idempotency のコード例を示す。
import { makeIdempotent } from '@aws-lambda-powertools/idempotency';
const processOrder = makeIdempotent(async (event) => {
return await createOrder(event);
}, { persistenceStore: new DynamoDBPersistenceLayer({ tableName: 'idempotency' }) });
冪等でない操作の危険性
冪等でない操作の危険性を図で示す。
1. クライアントが POST /orders を送信
2. サーバーが注文を作成、レスポンスを返す途中でネットワーク障害
3. クライアントはレスポンスを受け取れず、リトライ
4. サーバーが同じ注文をもう 1 件作成 → 二重注文!
理論と実装の両面から学ぶなら関連書籍が参考になる。
この記事は役に立ちましたか?
関連用語
リトライパターン
一時的な障害に対して自動的にリクエストを再試行し、指数バックオフで間隔を調整する設計パターン
SQS FIFO キュー
メッセージの順序保証と厳密な 1 回配信を提供する Amazon SQS のキュータイプ
REST API
HTTP メソッドとリソース指向の URL で設計する Web API のアーキテクチャスタイル
コードの不吉な匂い
リファクタリングが必要であることを示唆するコード上の兆候や構造的な問題のパターン
JSON Patch
JSON ドキュメントの部分更新操作を記述する標準フォーマット (RFC 6902)
レースコンディション
複数のプロセスやスレッドが共有リソースに同時アクセスし、実行順序によって結果が変わる不具合