1. 程式人生 > >由Redis的hGetAll函式所引發的一次服務宕機事件

由Redis的hGetAll函式所引發的一次服務宕機事件

昨晚通宵生產壓測,終於算是將生產服務宕機的原因定位到了,心累。這篇部落格,算作一個覆盤和記錄吧。。。

 

先來看看Redis的快取淘汰演算法思維導圖:

說明:當實際佔用的記憶體超過Redis配置的maxmemory時,Redis就會根據使用者選擇淘汰策略清除被選中的key。

 

業務場景:使用者通過微信入口來訪問一個頁面;

測試場景:通過多執行緒模擬定量的併發來訪問頁面服務;

涉及架構:springsession+Redis叢集,容器部署;

問題描述:固定併發數壓測10分鐘,壓測開始後半小時,Redis連線數激增,連線耗盡,服務重啟;

處理邏輯:

①、使用者通過入口頁面訪問服務時,springsession給每個使用者建立一個session,將key儲存在Redis中;

②、Redis預設配置每隔半小時,利用hGetAll函式遍歷session-key所在的集合,將最近一分鐘內要過期的key全部delete,釋放記憶體;

宕機原因:

①、Redis是單執行緒處理,由於高併發壓測,產生了百萬級的key儲存在set集合中,當hGetAll函式遍歷集合刪除過期session的key時,大量使用者連線失效;

②、失效瞬間,Redis需要建立大量連線,如果TPS超過了設定的最大連線數,則Redis服務容器健康檢查不通過;

③、通過選舉,Redis叢集主從切換時需要將master的資料複製到salve;

④、主從複製時,Redis定位區域buffer(軟連結)超時,最終導致服務宕機重啟。

優化方案:

①、選擇Redis預設淘汰策略,每秒鐘選擇10次,每次不超過25個,即每秒鐘淘汰≤250個key;

缺點:記憶體好用較高,需要通過橫向擴充套件資源來應對該問題;

②、通過壓測確定當前系統配置下的最大可處理閾值,通過閘道器限流、服務降級等措施來保障服務的穩定執行;

缺點:如果實際流量超過限流配置,則使用者可能看到一些“友好介面”,使用者體驗不太好;

PS:在實際生產環境中,系統穩定性和可用性勝於一切!!!

相關參考:

Redis快取淘汰演算法

Redis的hGetAll函式的效能問題

 

以上就是此次問題覆盤,雖然通宵帶來的後遺症導致現在還有點迷糊,但從中學到了很多新的東西,值得思考與學習。。。