Redis高性能原因解析——Redis內部的阻塞式操作及應對方法

Redis被廣泛使用的一個很重要的原因是它的高性能。因此我們必要要重視所有可能影響Redis性能的因素、機制以及應對方案。影響Redis性能的五大方面的潛在因素,分別是:

  • Redis內部的阻塞式操作
  • CPU核和NUMA架構的影響
  • Redis關鍵系統配置
  • Redis內存碎片
  • Redis緩衝區

本篇文章我們主要了解Redis內部的阻塞式操作以及應對方法。

Redis實例有哪些阻塞點

在分析阻塞點前,我們先來看看和Redis實例交互的對象和操作有哪些:

  • 客戶端:網絡IO,鍵值對增刪改查操作,數據庫操作;
  • 磁盤:生成RDB快照,記錄AOF日誌,AOF日誌重寫;
  • 主從節點:主庫生成、傳輸RDB文件,從庫接收RDB文件、清空數據庫、加載RDB文件;
  • 切片集羣實例:向其他實例傳輸哈希槽信息,數據遷移。

這些交互操作可能會產生潛在的阻塞點。

阻塞點

  • 集合全量查詢和聚合操作:要重視複雜度爲O(n)的操作。
  • bigkey刪除:刪除操作的本質是要釋放鍵值對佔用的內存空間,一下子釋放了大量內存,會造成Redis主線程的阻塞。
  • 清空數據庫:頻繁刪除鍵值對是潛在風險,清空數據庫必然也是一個潛在風險。
  • AOF日誌同步寫:一個同步寫磁盤的操作的耗時大約1~2ms,如果有大量寫操作需要記錄到AOF日誌並同步寫回,就會阻塞主線程。
  • 從庫加載RDB文件:RDB文件越大,阻塞越久。

哪些阻塞操作可以異步執行

異步執行對操作的要求:如果一個操作 有被異步執行,意味着它不是Redis主線程的關鍵路徑上的操作

上面的五個阻塞點中,是關鍵路徑操作的有:

  • 集合全量查詢和聚合操作;
  • 從庫加載RDB文件。

異步執行機制

下面我們來了解一下異步執行機制。主線程通過一個鏈表形式的任務隊列和子線程進行交互,如下圖所示:

異步子線程執行機制

Redis主線程啓動後,會創建三個子線程來負責AOF日誌寫操作、鍵值對刪除以及文件關閉的異步執行。

異步的鍵值對刪除和數據庫清空操作是Redis 4.0後提供的功能,Redis也提供了新的命令來執行這兩個操作:

  • 鍵值對刪除:當你的集合類型中有大量元素(例如有百萬級別或千萬級別元素)需要刪除時,我建議你使用UNLINK命令。
  • 清空數據庫:可以在FLUSHDB和FLUSHALL命令後加上ASYNC選項,這樣就可以讓後臺子線程異步地清空數據庫。例如:FLUSHDB ASYNCFLUSHALL AYSNC

建議

  • 集合全量查詢和聚合操作:可以使用SCAN命令,分批讀取數據,再在客戶端進行聚合計算;
  • 從庫加載RDB文件:把主庫的數據量大小控制在2~4GB左右,以保證RDB文件能以較快的速度加載。

本文就寫到這了,有人看的話再抽時間寫一下後面四篇吧,

也許乾巴巴的文字看起來有寫枯燥,如果單看文字不是很容易消化的話,可以進羣973961276來跟大家一起交流學習,羣裏也有許多視頻資料和技術大牛,配合文章一起理解應該會讓你有不錯的收穫。

推薦一個不錯的c/c++ 初學者課程,這個跟以往所見到的只會空談理論的有所不同,這個課程是從六個可以寫在簡歷上的企業級項目入手帶領大家學習c/c++,正在學習的朋友可以瞭解一下。

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