高併發高可用的秒殺或搶券系統設計思考

對於一個秒殺系統來說,瞬時的大量請求會對後臺服務造成衝擊,需要保證服務的可用性以及業務的正確性。

設計了一個高併發高可用的系統簡要流程架構如下圖:

1.將商品(或券)的信息等靜態數據放到cdn節點,實現動靜分離

2.業務請求和業務處理之間使用MQ對請求進行削峯

3.讀寫分離:對於邏輯複雜(用戶驗證,風控管理,行爲分析)的系統,可以將讀寫部署兩套服務進行分離

4.使用緩存:

  • 像庫存這種信息無法放到靜態頁面,爲了應對大併發讀問題,可以在服務端做本地緩存用於讀取,一般緩存時間設置爲數秒,緩存失效時(最好在失效前一兩秒)重新拉取redis中的庫存信息。防止超買問題由扣減行爲保證,因此即使和緩存不一致,讀本地緩存也不會導致超賣,讀場景一般允許髒數據情況。
  • 高併發時,大量的mysql操作會有很大性能問題,因此使用redis集羣作爲緩存進行讀取。

5.防止緩存雪崩:

  • 減少緩存滲透:可以在服務中進行布隆過濾,可以將不存在的商品或券訪問在服務端過濾掉;或者對緩存中沒有的數據key置爲null並設置較短的過期時間,優點是簡單易操作,缺點要增加大量的null key,增大了與mysql的不一致性,需要消息機制和mysql保持同步
  • 限流:對key的操作加鎖排隊(利用setnx進行分佈式鎖),即同時只允許一個線程訪問。
  • 防止緩存同時失效:設置key的過期時間時,採用固定時間+隨機時間的方法,可以有效防止緩存同時過期引起雪崩的問題
  • 增加二級緩存: A1爲原始緩存,A2爲拷貝緩存,A1失效時,可以訪問A2,A1緩存失效時間設置爲短期,A2設置爲長期。

6.合理設置redis中的key,使其均勻的分佈到各個節點,防止大量請求訪問到少量節點的熱點問題,而且可以減少單個節點宕機造成的影響。

7.由於商品或券具有獨立性, 每個商品或券分配一個獨有id,可以根據id範圍劃分到各個服務集羣中,服務在訪問對應範圍的的redis緩存,這樣可以大大增加訪問的併發性。實現方式一個是在web服務中將id路由到對應的消息隊列topic中,另一個是在消息隊列後部署消息路由集羣,相對來說方案一更好,因爲方案而增加了鏈路長度和故障點。

8.在7的基礎上,爲了進一步提升性能防止少量熱點數據影響全量數據的操作性能,可在服務中統計熱點數據(比如LRU),並將熱點數據獨立存放到一個集羣中去,這樣可以將熱點數據和其它數據隔離開來。當然這樣會增加熱點數據遷移的工作,增加了系統的複雜性。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章