GH GambleHub

相似性和鑰匙

什麼是相容性

相似性是操作的屬性,其中具有相同標識符的重復不會更改最終效果。在分布式系統中,這是使結果等效於「正好一個處理」的主要方法,盡管有轉發,重復消息和計時器。

關鍵思想:每個可能重復的操作都必須用一個鍵標記,系統通過該鍵識別「已經完成」並應用最多一次的結果。

這在哪裏很重要

付款和資產負債表:「operation_id」註銷/貸記。
預訂/配額/限額:同一時段/資源。
Webhooks/通知:重新交付不應復制效果。
導入/遷移:重新運行文件/數據包。
流處理:經紀人/CDC的配音。

密鑰的種類及其範圍

1.操作鍵是特定業務操作嘗試的ID

示例:「idempotency_key」(HTTP),「operation_id」(RPC)。
區域:服務/單位;存儲在重復數據消除表中。

2.事件密鑰-唯一事件/消息ID

示例:「event_id」(UUID),「(producer_id,序列)」。
領域:消費者/消費者群體;保護投影。

3.商業鑰匙是學科領域的自然鑰匙

例如:「payment_id」,「invoice_number」,「(user_id,日)」。
區域:聚合體;適用於唯一性/版本檢查。

💡 通常一起使用:'operation_id'保護命令,'event_id'-交付,'business key'-聚合不變量。

TTL和保留策略

TTL密鑰≥可能的重播窗口:log retency+網絡/處理延遲。
對於關鍵域(付款),TTL-天/周;遙測-時鐘。
用jobami清除祖先表;用於審計-歸檔。

密鑰存儲(重復數據消除)

事務性DB(推薦):可靠的upsert/unique索引,協同效應事務。
KV/Redis:快速,方便短的TTL,但沒有與OLTP的聯合交易-謹慎。
State store流處理器:經紀人中的本地+cheinjlog;在Flink/KStreams很好。

電路(DB中的變體):
  • idempotency_keys

`consumer_id` (или `service`), `op_id` (PK на пару), `applied_at`, `ttl_expires_at`, `result_hash`/`response_status` (опц.).

索引:「(consumer_id,op_id)」是唯一的。

基本實現技術

1)交易「效應+進展」

在單個事務中寫入結果並提交讀/位置進度。

pseudo begin tx if not exists(select 1 from idempotency_keys where consumer=:c and op_id=:id) then
-- apply effect atomically (upsert/merge/increment)
apply_effect(...)
insert into idempotency_keys(consumer, op_id, applied_at)
values(:c,:id, now)
end if
-- record reading progress (offset/position)
upsert offsets set pos=:pos where consumer=:c commit

2) Optimistic Concurrency(單元版本)

在比賽中防止雙重影響:
sql update account set balance = balance +:delta,
version = version + 1 where id=:account_id and version=:expected_version;
-- if 0 rows are updated → retry/conflict

3)異位夾具(upsert/merge)

一次累積操作:
sql insert into bonuses(user_id, op_id, amount)
values(:u,:op,:amt)
on conflict (user_id, op_id) do nothing;

協議中的冪等性

HTTP/REST

標題「Idempotency-Key: 」.

服務器存儲密鑰條目並重新返回相同的響應(或不變性沖突中的代碼「409」/「422」)。
對於「不安全」的POST,「Idempotency-Key」+可持續的taymout/retray政策是必需的。

gRPC/RPC

元數據「idempotency_key」,「request_id」+deadline。
服務器實現-如REST:事務中的重復數據消除表。

經紀人/流媒體(Kafka/NATS/Pulsar)

制片人:穩定的「event_id」/偶數制片人(支持的地方)。
消費者:「(consumer_id,event_id)」和/或聚合的業務版本。
單獨的DLQ,用於非偶數/損壞的消息。

Webhuki和外部合作夥伴

在合同中要求「Idempotency-Key」/「event_id」;重新交付必須安全。
存儲「notification_id」和發送狀態;在轉發-不要重復。

密鑰設計

確定性:retrai必須發送相同的密鑰(在客戶/編排器上提前生成)。
可見性區域:將「op_id」形成「服務:aggregate: id: purpose」。
沖突:使用來自業務參數的UUIDv7/ULID或哈希(必要時與鹽)。
層次結構:前面的通用「operation_id」 →翻譯成所有子運算(偶數鏈)。

UX和產品方面

對密鑰的重新查詢必須返回相同的結果(包括主體/狀態)或顯式「已經完成」。
向用戶顯示「操作/完成」狀態,而不是「為好運」重新嘗試。
對於冗長的操作-按鍵(「GET/operations/{op_id}」)。

可觀察性

編寫「op_id」,「event_id」,「trace_id」,結果:「APPLIED」/「ALREADY_APPLIED」。
度量標準:重復百分比、去勢表大小、事務時間、版本沖突、DLQ投註。
Trace:關鍵必須通過命令→事件→投影→外部呼叫。

安全性和合規性

不要將PII存儲在密鑰中;密鑰是ID,不是付費。
在冗長的TTL中加密重復數據消除記錄中的敏感字段。
保留政策:TTL和檔案;被遺忘的權利-通過加密擦除響應/元數據(如果其中包含PII)。

測試

1.重復:運行一個消息/請求2-5次-效果恰好是一個。
2.在步驟之間下降:記錄效果之前/之後,正交固定之前/之後。
3.消費者重啟/重組:無雙重用途。
4.競爭:具有一個「op_id」 →一個效果的並行查詢,第二個效果是「ALREADY_APPLIED/409」。
5.長壽命密鑰:TTL過期和恢復後重復檢查。

反模式

每個回程的隨機新鍵:系統無法識別重復。
兩個獨立的公用程序:首先是效果,然後是失真-它們之間的下降復制了效果。
僅信任經紀商:在合成器/設備中沒有重復數據消除。
缺少聚合版本:重復事件第二次更改狀態。
胖鍵:鍵包括業務領域/PII →泄漏和復雜的索引。
沒有可重復的答案:客戶無法安全地回避。

示例

🚨 Check Alignment of POST

客戶端:「POST/payments」+「Idempotency-Key: k-789」。
服務器:事務-創建「payment」並寫入「idempotency_keys」。
重播:返回相同的「201」/身體;不變性沖突為「409」。

獎金(sink)

sql insert into credits(user_id, op_id, amount, created_at)
values(:u,:op,:amt, now)
on conflict (user_id, op_id) do nothing;

事件投影

消費者存儲該單元的「seen(event_id)」和「版本」;重復-忽略/等效的upsert。
讀取進度與投影更新記錄在相同的事務中。

生產清單

  • 對於所有不安全的操作,都定義了冪等鍵及其可見性區域。
  • 有帶有TTL和唯一索引的重復數據消除表。
  • 讀取效果和進度以原子方式計算。
  • 寫作模型包括樂觀的競爭(版本/序列)。
  • API合同記錄了「Idempotency-Key」/「operation_id」和重播行為。
  • 度量指標和日誌包含「op_id」/「event_id」/「trace_id」。
  • 復制、摔倒和比賽測試-在CI。
  • 符合TTL/存檔政策和 PII安全性。

FAQ

「Idempotency-Key」與「Request-Id」有什麼不同?
'Request-Id'-跟蹤;它可以在後臺進行更改。「Idempotency-Key」是操作的語義ID,在重復時必須相同。

沒有DB就能達到等效性嗎?
對於短窗口,是的(Redis/進程內關節),但是如果沒有聯合交易,雙倍的風險就會增加。在關鍵域中-在單個DB交易中更好。

如何與外部合作夥伴合作?

商定密鑰和可重復的響應。如果合作夥伴不支持-將呼叫包裹到其冪等層中並存儲「已經應用」。

如何選擇TTL?

總結最大延遲:log+worst-case 網絡/rebalance+緩沖區。添加庫存(× 2)。

底線

相似性是鑰匙,交易和版本的學科。穩定的操作ID+原子固定的效果和閱讀進展+等效的sinks/投影可產生「完全相同的效果」,而無需傳輸層魔力。使密鑰確定性,TTL逼真,測試惡意。然後,撤退和重復將成為例行公事而不是事件。

Contact

與我們聯繫

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

開始整合

Email 為 必填。Telegram 或 WhatsApp 為 選填

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

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