GH GambleHub

Exactly-once語義

什麼是exactly-once實際上是

「Exactly-once」通常被理解為兩種不同的東西:
  • 交付:消息將恰好傳遞給消費者一次。
  • 處理:最終副作用(DB記錄,平衡變化,其他事件的發射)將恰好發生一次,即使交付或嘗試更大。

在分布式系統中,談論處理語義更為可靠。交付完全難以提供(重復和重復是不可避免的),但是可以使最終狀態等同於單個處理。


何時需要EOS,何時不需要

需要EOS,如果:
  • 現金交易和資產負債表:雙重註銷是不可接受的。
  • 許可證/配額核算,計費表。
  • 不可逆的外部調用(例如,一次性密鑰激活)。
如果:
  • 效果是可逆的或可補償的(傳奇,回報)。
  • 允許在店面/徽標中臨時重復。
  • 比將交易拖過整個路線便宜。

模型: 終端vs. hop-by-hop

Hop-by-hop EOS:每個部分(源→處理器→接收器)確保其操作正確應用一次。
終端EOS:整個鏈確保從「事實」到「側面效應」的結果等同於單個處理。

實際上,通過在每個跳上結合事務和/或冪等來實現端到端。


基本構件

1.等效手術

在操作密鑰上重復相同的請求會產生相同的結果。

Ключи: `idempotency_key`/`event_id`/`operation_id`.

實現:TTL的「所見」運算表≥輸入日誌的拒絕。

2.「Read-process-write」交易)

在一個原子單元中,工作記錄了副作用和閱讀進展(正面/位置)。這消除了「鬼魂」在步驟之間的下降。

3.Version/SEQUENCE

對於單元,存儲版本/計數器;僅當「expected_version」匹配時才應用更改。相同事件的重播不會一次增加版本→效果。

4.重復數據消除

索引通過「(consumer_id,event_id)」或自然的「business_id」操作。


實現模式

1)帶有正交提交的Transactional Log+ Transactional sink

非常適合流處理。

我們從日誌中閱讀(僅確認記錄)。
我們正在進行處理。

在一個事務中:
  • (a)將效果寫成sink (DB/表),
  • (b)以「讀到ofset N」(在同一DBD)記錄。
  • Commit。在重新開始時,要麼全部被埋葬(並且將移位),要麼一無所有。

屬性:重復執行不會傷害;效果上的「恰好一次」,即使消息讀了兩次。

2) Outbox+偶數消費者

用於事務制作服務。

在一個DB事務中:我們修改域條目並在outbox中編寫事件。
Republicator使用相同的「event_id」將事件傳遞到總線。
消費者平均應用事件(「event_id」的前提)。

屬性:制作人確保事實不會丟失;消費者保證一個效果。

3)Kafka/Flink樣系統中的EOS(概念上)

相同的制作人:在發貨回程時防止拍攝。
制作人交易:一組錄音到拓撲+consumer移位在原子上進行;讀者使用「read_committed」隔離。
處理方存儲狀態(state store)並將其與事務一起發布。

屬性:重新啟動托架/塔斯卡不會產生雙重效果;復制的「不可見」下遊。

4)通過upsert/merge進行異位的「siki」(sinks)

Sink接受"operation_id"/"event_id"並執行"UPSERT……WHERE NOT EXISTS`.

副作用(例如權重)在原子上執行,並檢查「是否已應用」。

屬性:便宜的EOS方法與存儲邊緣,沒有分布式事務。


實現的關鍵細節

操作標識符

必須確定重播(不要在轉發時生成新的UUID)。
具有穩定的可見性區域(每個消費者/每個單元/每個系統)。

重復數據消除表

Колонки: `consumer_id`, `operation_id`, `applied_at`, `ttl_expires_at`.

「(consumer_id,operation_id)」索引。
TTL ≥最大重播窗口(log retency+潛在延遲)。

樂觀的競爭

在write模型中,存儲單元版本。
當應用事件/命令時,請使用「WHERE版本=:expected」;復制不會增加版本。

訂單/順序

EOS不等於「完全相同的順序」。通過批次密鑰(所有聚合事件→單個批次)和/或比較「序列」來確保一致性。

異位外部挑戰

對於不安全的方法(例如HTTP webhooks到第三方服務),請添加「Idempotency-Key」,並要求合作夥伴支持它。


頻繁的陷阱

EOS只在一個地方:如果sink是偶然的,但是您會在沒有偶然性的情況下發布次要事件,則將獲得「完全多次」下遊。
兩種commites:首先在DB中,然後在經紀人中商量ofset-它們之間的下降會產生重復的效果。
原始CDC向外:DB計劃的改變打破了消費者的平均水平。
不穩定的鍵:「operation_id」取決於時間/隨機,並在轉發時更改。


成本和權衡

潛伏期:交易/孤立閱讀→ p95/p99增長。
跨存儲:重復數據消除表、狀態存儲、事務日誌。
操作難度:交易定時,線程重組,「折疊」會話。
診斷:更多狀態("kamite","顯示為read_committed","滾動")。

逐點選擇EOS:用於關鍵聚合和效果;其余的則由等效性和補償性覆蓋。


exactly-once測試

1.斷層噴射:步驟之間的過程下降「記錄了效果」和「記錄了正交」。
2.重復:將相同的消息抽出2-5次,確保一個效果。
3.重新啟動和重新調整:停止/重新啟動竊賊,檢查是否存在雙重處理。
4.Network flappy:在事務中間的時間間隔,commit重播。
5.負載測試:隊列增長→是否降級為「永久事務」。


迷你模板(偽版)

具有正交固定功能的Idempotent sink

pseudo begin tx if not exists(select 1 from dedup where consumer_id=:c and op_id=:id)
then apply_effect(...)    -- upsert / merge / add_one_time_action insert into dedup(c, id, applied_at) values(:c,:id, now)
end if update offsets set pos=:pos where consumer_id=:c commit

具有聚合版本的命令

pseudo begin tx update account set balance = balance +:delta,
version = version + 1 where id=:account_id and version=:expected_version;
if row_count=0 then error CONCURRENT_MODIFICATION commit

安全和合規性

PII/PCI在重復數據消除表中:存儲最小值,使用令牌代替「原始」數據。
審計:編寫「operation_id」,「trace_id」,結果(APPLIED/ALREADY_APPLIED)。

保留策略: TTL在dedup表上,歸檔期權/log.


反模式

「真正的exactly-once交付」:試圖消除傳輸協議級別的雙打,而沒有效果的冪等。
全局分布式事務到所有:通過所有服務的XA/2PC是脆弱和緩慢的。
混合非偶數小袋(例如,電子郵件發送到ofset commit)。
缺少操作密鑰:重視有效載荷的「唯一性」。


生產支票清單

  • 在每個關鍵效應上都有等效鍵。
  • Ofset/讀取位置被固定在一個具有效果的事務中。
  • 已對重復數據消除表進行索引;TTL ≥博客的關註。
  • 對於單元,包括樂觀的競爭(版本/序列)。
  • 流/拓撲以「僅加密」模式(如果可用)讀取。
  • CI/CD中存在重復和下降測試。
  • Dashbords:重播、交易失敗、鎖定時間、滯後率。
  • 關於「Idempotency-Keu」/重復/時間表的集成商文檔。

FAQ

無需事務即可提供EOS?

通常,是的-通過sink's(upsert/merge)的冪等性和單元的旋轉。交易簡化了保修,但增加了成本。

每個人都需要一個「exactly-once」嗎?
沒有。他是道路。在無法補償的地方/道路上逐點應用。

如何將電子郵件/webhooks鏈接到EOS?

將通知緩沖到commit,在提交效果後發送;保存「notification_id」並使發送具有等效性。

更重要的是-交付或處理?

處理。交貨可能會重復;最終狀態必須正確且唯一。


結果

Exactly-once是關於效果的正確性,而不是關於布線中缺少配音。它通過相容性,原子鎖定效果和閱讀進展,合理分期和考試紀律的結合來實現。將EOS應用到錯誤成本不可接受的地方,並通過跌倒和雙打測試檢查其現實-不相信運輸。

Contact

與我們聯繫

如有任何問題或支援需求,歡迎隨時聯絡我們。我們隨時樂意提供協助!

開始整合

Email 為 必填。Telegram 或 WhatsApp 為 選填

您的姓名 選填
Email 選填
主旨 選填
訊息內容 選填
Telegram 選填
@
若您填寫 Telegram,我們將在 Email 之外,同步於 Telegram 回覆您。
WhatsApp 選填
格式:國碼 + 電話號碼(例如:+886XXXXXXXXX)。

按下此按鈕即表示您同意我們處理您的資料。