【アットレーストワンスはいしん】

At-least-once配信 とは?

最終更新:
💡 届いた確認が取れなければ、同じメッセージを再配信

保存と再試行などの前提の下で、メッセージを少なくとも1回配信する保証。同じメッセージが複数回届く可能性があるため、処理結果を重複させない設計が重要。

📌 このページのポイント
確認が届かないと、もう一度配信 配信側 処理側 ① メッセージ ID 42 処理する ② 完了確認が途切れる 完了を確認できず再試行 ③ 同じ ID 42 を再配信 重複し得る 冪等な処理で、結果を一度分に 受信回数と結果の回数は別
処理済みでも確認が届かず、同じIDを再配信する例。青・橙の矢印は配信、赤は途中で途切れた確認。保存期間や復旧などの前提があり、あらゆる障害で永久に届く保証ではない。
ひよこ ひよこ
At Least Once配信ってどういう意味?
ペンギン先生 ペンギン先生
少なくとも1回の配信を保証する方式だよ。同じメッセージが2回以上届く可能性はある。保存や再試行、障害からの復旧などの条件の下での保証で、どんな障害でも永久に届くという意味ではないんだ。
ひよこ ひよこ
なぜ同じメッセージが2回届くの?
ペンギン先生 ペンギン先生
受信側が処理を終えても、その確認が配信側に届かないことがあるからだよ。配信側は完了を確認できず、もう一度同じメッセージを配信する。SQSの標準キューでは、冗長なコピーの一部を削除できず再び受信する場合もあるんだ。
ひよこ ひよこ
受け取る側はどう対処するの?
ペンギン先生 ペンギン先生
同じメッセージを何度処理しても、一度処理したのと同じ結果になる冪等性を持たせるよ。例えば処理済みIDを記録して重複を除く。ただし、IDの記録と実際の更新が食い違わないようにし、同時実行も考える必要があるんだ。
ひよこ ひよこ
どんなシステムでも、届くまで残るの?
ペンギン先生 ペンギン先生
仕様と設定によるよ。例えばSQSには保存期間があり、期限を超えたメッセージを永久には保持しない。Kafkaでも、処理してから消費位置を記録する構成では、記録前の障害で同じものを再処理し得る。製品名だけで保証範囲を決めないようにしよう。
ひよこ ひよこ
Exactly Onceとの違いは?
ペンギン先生 ペンギン先生
Exactly Onceは、対象範囲で処理結果が一度分になるようにする保証として使われるよ。受信処理が物理的に一度しか呼ばれないとは限らない。Kafka内の処理の保証を、外部のデータベースへの更新などに広げるには、相手側との協調も必要なんだ。
もっと詳しく知りたい人へ

処理済みIDを保存するだけで二重更新を防げる?

保存と更新を別々に行うだけでは不十分だよ。同じDBで扱えるなら、処理済みIDを一意なキーで挿入し、実際の更新と同じトランザクションで確定する方法がある。失敗したら両方を取り消し、重複IDなら更新しない。外部APIの呼び出しなど、同じトランザクションに入らない処理には別の重複対策が必要だよ。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「At Least Once」って出てきたら「重複を許して再配信する方式」と思えばだいたいOK!保証の条件と、重複への対処も確認しよう。
📖 おまけ:英語の意味
「At Least Once Delivery」 = 少なくとも1回の配信
💬 at leastは「少なくとも」、onceは「1回」という意味だよ。配信は重複し得るので、処理結果を一度分にする設計とは区別するんだ。

参考資料

← 用語集にもどる