分散式處理 冪等設計
最近做的專案的效能調優中關於冪等設計的一些總結
場景:假設有這樣一個方法,包含了一些DB操作,check if existing then update else save. 如果兩個執行緒同時去執行這個方法,並且他們處理的是同一條資料,期望應該是其中一個執行緒是save,另外一個是update。但是有可能執行緒的處理時間相當重合,執行緒A在check的時候,執行緒B也在check,這時A和B都認為資料不存在,都去save,在資料庫有unique 約束的情況下其中一個操作會失敗,而我們期望的可能是後面一個操作應該update(取決於具體業務)。
這是很典型的多執行緒問題,check - then do something,在單系統環境中這很容易用執行緒同步來處理(syncronised). 但是如果是分散式系統,這兩個執行緒在不同的server上面,syncronised 是不會起效的,而且同步往往降低效率,並不是我們想要的。
擁有相同引數的多次請求對系統造成的副作用應該是相同的,這就是冪等性。在這個例子裡面就是說保證相同的ID組合只會插入一條資料到DB裡面,如果一個請求是save,後續的都應該update這條。在單系統中也可以用冪等的設計來規避使用syncronized,因為那會降低效率。一般情況下資料庫就能保證這種冪等性--用unique關鍵字,以上面的場景為例,假如其中一個執行緒的save操作失敗,我們可以用catch 特定的exception然後判斷是不是要進行update操作的方式來試圖保證冪等。在分散式系統中更應該考慮冪等設計,尤其是高併發,高效能要求下。併發量高的情況下,執行緒的衝突很容易發生。即使是小概率時間,也是必然會發生的。
我們系統的實際需求是需要在一個方法裡面做很大DB操作,其中就包括了check if existing then update else save,開始的時候我們估計重複資料的概率很小,但是在後來的效能測試中發現還是會出現,我們的測試併發量是30000 TPS左右,有8個node。
分散式系統中一定要考慮冪等的設計,因為相較於進行分散式事務設計,冪等設計輕量級的多。