【イグザクトリーワンスはいしん】
Exactly Once配信 とは?
最終更新:
💡 重複も欠落もなく「ちょうど1回」を届ける、範囲限定の特急便
メッセージキューやストリーム処理で、1件のメッセージの結果が重複も欠落もなく「ちょうど1回」だけ反映されるようにする配信保証。保証される範囲と条件は製品ごとに決まっていて、外部システムへの書き込みまで含めるには受け側の工夫も必要になる。
📌 このページのポイント
- メッセージの結果が重複も欠落もなく1回だけ反映されることを保証する配信方式
- At Most Once(欠落の可能性あり)やAt Least Once(重複の可能性あり)より強い保証レベル
- Kafkaはべき等プロデューサーとトランザクションで、Kafka内の「読み取り→処理→書き込み」をExactly Onceにできる
- 保証は製品ごとの範囲と条件つき。DB更新やメール送信など外部への反映は、べき等な処理などを受け側で用意する
Exactly Once配信って、ぴったり1回だけ届くってこと?
そうだよ。重複もしないし、消えもしない、ちょうど1回だけ結果に反映されることを保証する方式なんだ。ただ、どこからどこまでを「1回」にするかは製品ごとに決まっていて、その範囲の中での約束だよ
それって難しいの?
かなり難しいんだよ。送った側が返事を受け取れなかったとき、「届いたけど返事が消えた」のか「そもそも届いていない」のか区別できないからね。再送すれば重複が起きうるし、再送しなければ欠落が起きうる。Kafkaも初期設定の保証はAt Least Once(重複の可能性あり)なんだ
どうやって実現するの?
Kafkaでは、ブローカーがプロデューサーごとにIDを割り当てて、メッセージに付いた連番で再送による重複を捨てる「べき等プロデューサー」があるよ。さらにトランザクションを使うと、複数のパーティションへの書き込みと「どこまで読んだか(オフセット)」の記録をまとめて確定できる。これでKafkaからKafkaへの読み取り→処理→書き込みをExactly Onceにできるんだ
じゃあKafkaを使えば送金処理も安心?
他のサービスにもExactly Onceってあるの?
Google CloudのPub/SubにもExactly Once配信があるけど、対象はpullサブスクリプションだけで、同じリージョンから接続する場合に限られるよ。確認応答に成功したメッセージは再配信されない一方、通常より配信の遅延がかなり大きくなると説明されているんだ。保証の範囲と引き換えのコストを確認してから選ぼうね
もっと詳しく知りたい人へ
Exactly Onceが使えない場面では、どうやって重複を防ぐ?
At Least Onceで受け取り、受け側の処理をべき等にするのが一般的だよ。たとえば注文IDや送金IDをDBの一意キーとして保存し、同じIDが2回来たら処理済みとしてスキップする。Kafkaの公式ドキュメントでも、外部システムへ出力する場合は、出力結果と読み取り位置(オフセット)を同じ場所に保存する方法が紹介されているよ。
まとめ:ざっくりこれだけ覚えればOK!
「Exactly Once」って出てきたら「決められた範囲の中で、重複も欠落もなく1回だけ反映する配信保証」と思えればだいたいOK!
📖 おまけ:英語の意味
「Exactly Once Delivery」 = ちょうど1回の配信
💬 「正確に(exactly)1回(once)」届けるという意味だよ。実際の製品では、ネットワークの再送そのものをなくすというより、重複を見つけて捨てたり、書き込みと読み取り位置の記録をまとめて確定したりして「結果として1回」にする仕組みが多いんだ