討論一下分布式系統傳輸過程中常見的at least once 還是 at most once 問題。一般在一次傳輸過程中,失敗與否是使用最大等待時間(記為time out)來判斷是否傳輸成功,如果超過了這個時間,說明傳輸失敗。但是用time out來判斷是否傳輸成功,如果失敗的時候無法判斷是傳送過程中出問題還是返回過程中出問題,所以只能是選擇失敗的時候重傳或者不重傳。如果選擇不重傳,這樣假定了在返回成功消息的時候出錯,而此時服務器已經收到數據,但這樣如果是傳輸過程出問題,那么服務器沒有收到數據,所以有可能出現數據丟失,不丟失也最多傳了一份數據,這時就是 at most once;如果假定是傳輸過程出現問題,而服務器沒有收到數據,這樣time out之后重傳數據。但這可能是返回成功消息的時候出問題,而此時服務器已經收到數據,這樣會因為重傳而收到多份數據,這就是 at least once。我們會根據不同的應用場景決定選擇哪種情形,比如TCP有超時重傳,則是at least once,大數據kafka中也有決定哪種情形的策略。
接下來介紹冪等性的概念,冪等性是指允許多次傳輸重復的應用。冪等性其實是數學中的一個概念,表達的是N次變換與1次變換的結果相同。分布式系統中的冪等性指的就是用戶對於同一操作發起的一次請求或者多次請求的結果是一致的,不會因為多次點擊而產生了錯誤的結果。最直觀的例子就是支付的時候,點擊支付時,因為網絡或其他原因導致異常,但是錢已經扣掉了,還沒來得及返回給用戶,此時用戶又點擊了支付,此時發生了二次扣費。我的理解冪等性說白了就是數據重復時的去重操作,kafka是用全局ID實現事務來保證冪等性的。在非冪等性應用中是不允許重復的,或者是沒法對其進行冪等性處理的,此時就必須使用at most once 如果出錯在通過檢查數據、回滾等操作做后續的處理(處理比較麻煩、回滾事務費時間)。