Skip to main content

Command Palette

Search for a command to run...

冪等性 Idempotence

Updated
2 min read
冪等性 Idempotence

冪等性(Idempotence) 是分散式系統和微服務架構中的一個關鍵概念, 尤其是在處理 retry 與 防止重複操作時非常重要. 簡單來說, 冪等性意味著無論你發送相同的命令多少次, 結果都是一樣的, 系統不會改變其狀態, 甚至可能不會執行重複的操作. 對於網路異常或請求超時等情況下非常重要, 因為 client 可能會 retry, client 屬於我們不可控的對象, 但我們服務方會希望避免同一操作被重複執行.

冪等性的關鍵概念

  1. 冪等操作 該操作是冪等的, 表示重複執行不會產生額外的影響或狀態的改變. 例如, 使用相同的數據來更新資料的狀態, 或調用建立紀錄的端點, 這些都不會導致重複紀錄的產生.
  1. 冪等欄位(Idempotency Key) 在許多系統的設計中, 請求或命令中都會包含一個唯一識別符(冪等欄位), 以確保如果請求被retry, 系統能夠識別這是重複操作, 可以選擇跳過執行. 冪等欄位通常是由client端產生.

Retry Attack(重試攻擊) 是一種與網絡安全相關的攻擊方式,攻擊者利用系統允許的重試機制,通過多次嘗試重複提交請求,來實現以下目標:

  • 繞過安全檢查:例如,發送多次支付請求,試圖重複扣款或重複使用一次性 token。
  • 猜測敏感數據:例如,不斷重試不同的憑證或密碼,試圖獲取有效的憑據。
  • 利用系統異常:利用系統在某些情況下的異常行為(如高併發導致系統容量耗盡或錯誤處理),達成攻擊目的。

冪等欄位的設計原則

  • 唯一性:每個請求都應該有一個唯一的標識符,避免重複。
  • 可追蹤性:冪等欄位應該能讓服務端快速定位相關請求, (很類似 OpenTelemetry 中的 Trace Id)。
  • 安全性:避免使用敏感內容(如用戶名、密碼)作為冪等欄位。
  • 可控性:通常由client端生成,因為服務端無法完全控制請求的重發行為

肯定有人會提出, 那讓client端請求前先跟server端獲取一個冪等值, 給client發出請求時攜帶著. retry時就重複使用該冪等值. 但client端的邏輯是我們不可控制的, 搞不好他每次retry都重新獲取一個冪等值 QQ

冪等欄位的組成

冪等欄位通常是一個唯一識別符(UUID 或類似的值),但可以根據業務需求進行擴展設計。以下是常見的組成方式:

  1. 使用 UUID(Universally Unique Identifier)或 GUID(Globally Unique Identifier)。 idempotency_key: "4f9e8c3a-9a6b-4d7a-8c3e-123456789abc"

優點:生成簡單且不依賴具體業務邏輯。 缺點:無法反映請求的業務語義,僅適合通用場景。

  1. 基於業務的唯一標識符 將業務相關的資訊組合起來,生成冪等欄位。例如: idempotency_key: "order_12345_user_67890"

優點:冪等欄位與業務強相關,便於排查問題。 缺點:欄位設計需要根據具體業務場景定制, 不容易有統一標準.

  1. 基於 Hash 的唯一標識符 將請求的核心參數內容(如用戶 ID、訂單 ID、請求時間等)拼接後產生 hash value 作為冪等欄位。 idempotency_key: SHA256("user_67890_order_12345_20250124T095200")

優點:減少冪等欄位的長度,並隱藏業務細節。 缺點:需要額外的hash計算,增加了一些處理成本。

  1. 基於 Timestamp 的唯一標識符 在唯一標識符中加入時間戳,確保每次請求的冪等欄位不同。Snowflake IdUUIDv7 就基於這種概念. idempotency_key: "4f9e8c3a-9a6b-4d7a-8c3e-123456789abc_20250124T095200"

優點:適合需要頻繁生成冪等欄位的場景。 缺點:client 端如果是使用發出請求時的 timestamp 來產生唯一標識符, 會影響重試機制的有效性。

數字或唯一標識符字串(UUID這類), 各有優缺點. 數字的優點是好比較, payload size小; 缺點是極易被猜測出來範圍. 唯一值字串反過來, 但缺點大部分能用鈔能力解決.

應用場景

假設是在電商或金流系統中進行支付. 你發送了一次支付請求, 但因為網路問題, client 不確定支付是否成功.

  • 如果沒有冪等性的設計, client 端 retry 請求可能導致支付被重複處理.
  • 如果有冪等性的設計, client 端在retry之後, 服務方檢查到此請求已處理過, 通常會回傳原始的回應內容, 而選擇不會重複執行操作.

實現冪等性的步驟

  1. Client 端產生冪等欄位與值
  2. Server 端儲存冪等欄位與值
  3. Server 端檢查冪等欄位與值是否存在
    • 如果已經存在, 回傳儲存的結果而不重複執行操作
    • 不存在, 則執行操作並儲存冪等欄位與值, 應設置冪等欄位的 Expiration, 避免儲存列表無限增長

冪等欄位, Nullifier, Nonce

當我們談到冪等欄位會發現還有兩個術語的改念與這很向, 分別是NullifierNonce 時,這三個名詞都與分散式系統、區塊鏈和密碼學中的「唯一性」和「防止重複操作」的需求密切相關。雖然它們的具體用途和應用領域不同,但核心概念有一定的相似性。以下是對這三個名詞的統一說明及比較。

Nullifier 和 Nonce 可以被視為冪等欄位的一種實現形式,只是它們的應用領域和具體功能略有不同。 統一的核心概念 這三個名詞的共同點在於:

唯一性:每個值都必須是唯一的,避免重複操作或數據衝突。 一次性使用:一旦被使用,就不能再次重複使用,從而保證系統的正確性和安全性。 防止重複執行或攻擊:這三者的設計目的是防止因重複執行請求、交易或操作而導致的錯誤或攻擊。

三者的具體定義與應用場景

冪等欄位(Idempotency Key)

定義:冪等欄位是一個唯一的標識符,用於標記一次操作(如 API 請求)是否已經執行過,從而保證即使重複執行相同的操作,系統的狀態也不會改變。

應用場景: 分散式系統:當客戶端因網路超時或錯誤而重發請求時,服務端可以通過檢查冪等欄位來確保操作不會被重複執行。 支付系統:避免同一支付請求重複扣款。

特點: 通常由客戶端生成,並附加到請求中。 服務端需要記錄已使用的冪等欄位,並檢查其唯一性。

示例:

{
  "idempotency_key": "123e4567-e89b-12d3-a456-426614174000",
  "action": "create_order",
  "data": { ... }
}

Nullifier

定義:Nullifier 是一個唯一的標識符,用於標記某個資源或交易是否已經被使用過,特別是在隱私保護協議中,用於防止雙花(Double-Spending)或重複使用。

雙花(Double-Spending) 是區塊鏈和加密貨幣領域中的一個關鍵問題,指的是同一筆加密貨幣被用戶多次花費的情況。這種情況如果發生,會破壞加密貨幣系統的完整性和信任基礎。

應用場景: 隱私幣(如 Zcash):用於標記某筆資金是否已經被花費。 匿名交易協議(如 Tornado Cash):確保用戶提現後,不能再次使用相同的憑證進行提現。

特點: 通常由服務端或協議生成,基於某些唯一的資源(如交易 ID 或用戶密鑰)計算得出。 與隱私保護密切相關,Nullifier 本身不暴露具體資源內容。

示例:

Nullifier = Hash(User_Private_Key || Resource_ID)

Nonce

定義:Nonce 是一個用一次的數字或唯一值,用於加密協議、身份驗證或區塊鏈中,確保操作的唯一性或防止重放攻擊。JWT RFC 7800 中也有使用到Nonce。

應用場景: 區塊鏈挖礦:礦工調整 Nonce 值,直到找到滿足特定哈希條件的區塊。 交易順序:以太坊中的交易 Nonce 用於標記交易的順序,防止交易亂序或重複執行。 防重放攻擊:在 API 調用或身份驗證中,Nonce 確保每次請求都是唯一的。

特點: 可以是隨機生成的數字,也可以是遞增的整數(根據具體應用場景)。 一旦使用,便失效,不能重複使用。

示例: 區塊鏈挖礦中的 Nonce:

Nonce = 42

API 請求中的 Nonce:

{
  "user_id": "12345",
  "action": "login",
  "nonce": "a1b2c3d4e5"
}

分散式事務與補償處理

在分散式系統中,操作可能涉及多個服務或資料庫,難以保證所有操作都在同一事務中完成。因此,經常使用以下設計模式來處理一致性問題:

分散式事務:通過 2PC或 3PC 來保證多個節點的一致性,但這種方式通常會降低性能,並且在高併發場景下不一定實用。

補償處理(Compensating Transactions):當某些操作失敗時,通過執行反向操作(補償操作)來撤銷已完成的部分。例如,若訂單支付成功但扣庫存失敗,則需要補償支付操作(退款)。

參考微服務瞎談(7) Saga Pattern

冪等性與分散式事務/補償處理的關聯

在分散式系統中,冪等性和補償處理經常結合使用,因為它們可以共同解決以下問題:

(1)重試機制中的冪等性 在分布式事務中,網絡波動可能導致某些操作需要重試。如果操作具有冪等性,多次執行不會對系統狀態造成影響,這樣可以簡化重試邏輯,避免數據錯亂。

例如:

在支付服務中,當支付請求因網絡超時被重試時,冪等性可以保證多次支付請求只會成功一次。

(2)補償操作的冪等性 補償操作本身也需要冪等性,因為補償可能因網絡問題或重試機制被多次執行。如果補償操作不是冪等的,可能會導致系統狀態不一致。

例如:

若退款操作被多次執行,可能導致多次退款給用戶,這是不可接受的。通過冪等性,系統可以保證只退款一次。

(3)分布式事務的簡化 在一些場景下,冪等性可以減少對分散式事務的依賴。例如,當操作本身具有冪等性時,系統可以允許某些操作失敗後重試,而不必執行複雜的分散式事務協調。

實現冪等性的常見方法

在設計分散式系統時,為了實現冪等性,通常會採用以下方法:

  • 冪等欄位:為每個請求生成冪等欄位,服務端根據冪等欄位判斷請求是否已處理過。
  • 樂觀鎖:通過版本號控制更新操作,避免多次執行導致數據錯亂。
  • 狀態機檢查:在執行操作前檢查當前狀態,確保操作是否符合預期。
  • 資料去重複:在資料層面設計去重機制,避免重複執行對數據造成影響。

總結

冪等性是分散式系統中處理網路retry 與防止重複執行操作的關鍵. 對於複雜場景可以結合分散式事務設計與補償處理.

1.2K views

More from this blog

Claude Code 監控秘錄:OpenTelemetry(OTel/OTLP)實戰指南

稟告主公:此乃司馬懿進呈之兵書,詳解如何以 OpenTelemetry 陣法,令臥龍神算之一舉一動盡在掌握,知糧草消耗、察兵器效能、辨戰報異常,使主公運籌帷幄於大帳之中。 為何需要斥候情報? 司馬懿稟告主公: 臥龍神算(Claude Code)乃當世利器,然若無斥候回報,主公便如蒙眼行軍——兵器耗損幾何、糧草消費幾許、哪路斥候出了差錯,一概不知。臣以為,此乃兵家大忌。 無情報之弊,有四: 軍

Feb 19, 202610 min read173
Claude Code 監控秘錄:OpenTelemetry(OTel/OTLP)實戰指南

工程師的 Claude Code 實戰指南:從零開始到高效開發

工程師的 Claude Code 實戰指南:從零開始到高效開發 本文整合 Anthropic 官方 Best Practices 與社群實戰 Tips,帶你由淺入深掌握 Claude Code。 什麼是 Claude Code?為什麼值得學? 如果你還在用「複製程式碼貼到 ChatGPT,再複製答案貼回去」的工作流程,Claude Code 會讓你大開眼界。 Claude Code 是 Anthropic 推出的命令列工具,它直接活在你的 terminal 裡,能夠讀懂你的整個 codeb...

Feb 18, 20265 min read76
工程師的 Claude Code 實戰指南:從零開始到高效開發

System Design Interview Ch 12 Digital Wallet

確立問題與設計範疇 角色對話內容 面試者我們應該只關注兩個數位錢包之間的餘額轉帳操作嗎?我們是否需要擔心其他功能? 面試官讓我們只關注餘額轉帳操作。 面試者該系統需要支援多少 TPS(每秒交易次數)? 面試官讓我們假設是 1,000,000 TPS (每秒 100 萬次交易)。 面試者數位錢包對正確性有嚴格的要求。我們可以假設事務保證 就足夠了嗎? 面試官聽起來不錯。 面試者我們需要證明正確性嗎? 面試官這是一個很好的問題。正確性(Correctness)通常只有在交...

Feb 2, 202610 min read191
System Design Interview Ch 12 Digital Wallet

Claude Code 利用 Event-Driven Hooks 打造自動化開發大腦

在現代 AI 輔助開發中,我們不僅需要 AI 寫程式,更需要它懂規則、記性好,並且能自動處理那些繁瑣的雜事。透過 Claude Code Hooks 機制,我們可以介入 AI 的思考與執行迴圈,實現真正的「人機協作自動化」。 一、 動機與痛點:為什麼你需要介入 AI 的生命週期? 在預設狀態下,Claude Code 雖然強大,但它是「被動」且「無狀態」的,這導致了開發者常遇到以下痛點: 記憶重置 (Session Amnesia): 痛點:每次重啟終端機,AI 就像失憶一樣。 解法:你...

Jan 24, 20266 min read481
Claude Code 利用 Event-Driven Hooks 打造自動化開發大腦
M

MicroFIRE

71 posts