實戰並發-使用分布式緩存和有限狀態機


簡介    

這里的並發不是高並發,只是將正式環境的一小段流量同時打到我的自測環境。一個請求同時多次發送,真正意義上並發處理同一個數據,主要需求是保證數據冪等性和正確性。

主要技術是用分布式緩存做多次相同請求的冪等處理和用有限狀態機來解決MQ消息的不保證有序。

 

場景

k8s集群可以進行事件監聽,靜兒這次使用了一個美團內網線下的小集群。把這個小集群的對node節點和pod節點的監聽事件發送到MQ,3台服務器在同時工作。也就是說一個事件會被重復收到三次。其中兩台機器事件發送基本上是同時的,剩下一台是我自己的電腦。因為在家里,連着vpn,連接公司內網大概有2.5ms的延時。

在MQ事件的接收端,美團內部監控系統CAT上看到數據如下:

 

問題

當一個請求被重復在並發和有延遲的情況下會被重復收到。k8s自身也會短時間發送一些相同的請求。這些重復的請求在不考慮重復執行的副作用前提下,每次都同樣的方式執行,后端的壓力也會非常大。如果考慮重復執行的副作用,就是說重復的請求不冪等,數據不准確了,整個服務就非常糟糕了。

另外,不管是MQ還是k8s事件,接收處理事件的服務都不能保證先收到的事件是先產生的。多台機器的情況下,就算是先產生的,也會因為不同機器的處理速度不一樣,導致后產生的事件先被執行。

 

解決

如果下面解決方法中的概念不是很清楚,可以先看5W,再回來看方法。

使用分布式緩存解決請求去重的問題

首先考慮對請求處理的維度。比如靜兒舉例的場景中,對node節點的watch事件,可以用node作為緩存的key,用node需要處理的關鍵字段作為value。如果請求中的信息與緩存中的一致,則直接返回不處理。不一致則先更新緩存為最新值,再進行處理。

注意,因為保證消息不會被並發處理。剛才的緩存值獲取get和重設put操作都是用分布式鎖進行了加鎖的。

使用有限狀態機解決亂序的問題

之所以有「亂序」這個定義,說明系統本身是消息的順序是有要求的。順着這個思路來考慮,可以順理成章的得到解決方案:設定好原本的一個介紹順序。如果收到事件A則執行事件B。如果收到事件B則執行事件C。如果沒收到事件A先收到了事件B,則把MQ消息打回去重發。在打回去的階段事件A收到處理完了,這時候再收到事件B就可以繼續執行了。

剛才說的這種執行順序的方法就是有限狀態機。有限狀態機在程序里的實現主要有兩種。一種是通過switch case的方法。就是如果A則B的最容易理解的實現。通常被稱為“可執行代碼”方式。

另外一種方式是:如果每種狀態要做的處理比較復雜。用switch case比較難看。就可以將處理方法抽象成一個類。將這些類的實例放到映射表里。這種實現通常被稱為“被動數據”方式。

 

5W

Q:為什么MQ消息不保證有序?

A:因為MQ消息在服務器上是分區存儲的,每個分區自己是有序的。分區被接收端消費的時候。一般也是多個接收端一起消費。中間的每個環節都是只能保證局部有序。如果想全局有序。就需要分區只有一個,並且接收端服務器是單點,而且一次只處理一個請求。

Q:MQ的使用上還有什么關鍵注意點?

A:一般情況下MQ除了不保證消息有序還不保證消息不重復。因為在「網絡不可達」的情況下,MQ不能確認消息接收方收到了消息必然會重試。重試除了本文講的冪等處理外,還可以采用每個消息有唯一的ID+去重表實現。

Q:什么是分布式緩存?

A:分布式緩存有時候也叫「集中式緩存」。是相對於「本地緩存」而言的。因為在目前的多服務器部署(分布式)時代。「本地緩存」這種將信息存儲於當前服務器上,其他服務器無法感知。這時候采用一個專門的緩存服務器就可以解決這個問題。這就是分布式緩存了。

Q:什么是有限狀態機?

A:有限狀態機也稱為FSM(Finite State Machine),是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。FSM可以把模型的多狀態、多狀態建的轉換條件解耦。可以使維護變得容易,代碼也更加具有可讀性。

 

總結

並發問題對系統的影響

系統壓力造成的可用性問題、多個請求同時對同一個數據產生作用產生的數據准確性問題。

解決方案

可用性問題可以從設計上在業務邏輯層之前對數據去重,例如可以使用分布式鎖,讓真正耗時的業務邏輯對相同的多個請求只執行一次。

數據准確性問題可以通過有限狀態機保證不論收到請求順序如何,都按照正確的邏輯來執行。

相關閱讀     

《程序常用的設計技巧》

《到底多大才算高並發?》

《美團分布式服務通信框架及服務治理系統OCTO》

《學會用數據說話-分布式鎖究竟可以多少並發?》

《大話高可用》

《業務開發轉基礎開發,這三種「高可用」架構你會么?》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM