追求性能極致:Redis6.0的多線程模型( 二 )


追求性能極致:Redis6.0的多線程模型

文章插圖
既然讀寫網絡的 read/write 系統調用占用了Redis 執行期間大部分CPU 時間,那么要想真正做到提速,必須改善網絡IO性能 。我們可以從這兩個方面來優化:
  • 提高網絡 IO 性能,典型實現方式比如使用 DPDK 來替代內核網絡棧的方式
  • 使用多線程 , 這樣可以充分利用多核CPU,同類實現案例比如 Memcached 。
協議棧優化的這種方式跟 Redis 關系不大,所以最便捷高效的方式就是支持多線程 ??偨Y起來,redis支持多線程就是以下兩個原因:
  • 可以充分利用服務器CPU的多核資源,而主線程明顯只能利用一個
  • 多線程任務可以分攤 Redis 同步 IO 讀寫負荷 , 降低耗時
6.0版本優化之后 , 主線程和多線程網絡IO的執行流程如下:
追求性能極致:Redis6.0的多線程模型

文章插圖
具體步驟如下:
  • 主線程建立連接,并接受數據,并將獲取的 socket 數據放入等待隊列;
  • 通過輪詢的方式將 socket讀取出來并分配給 IO 線程;
  • 之后主線程保持阻塞,一直等到 IO 線程完成 socket 讀取和解析;
  • I/O 線程讀取和解析完成之后,返回給主線程 ,主線程開始執行 Redis 命令;
  • 執行完Redis命令后,主線程阻塞 , 直到IO 線程完成 結果回寫到socket 的工作;
  • 主線程清空已完成的隊列,等待客戶端新的請求 。
本質上是將主線程 IO 讀寫的這個操作 獨立出來,單獨交給一個I/O線程組處理 。這樣多個 socket 讀寫可以并行執行,整體效率也就提高了 。同時注意 Redis 命令還是主線程串行執行 。
開啟多線程的方式Redis6.0的多線程默認是禁用的,只使用主線程 。如需開啟需要修改redis.conf配置文件:
# io-threads-do-reads noio-threads-do-reads yes開啟多線程后,還需要設置線程數,否則是不生效的 。同樣修改redis.conf配置文件 。關于線程數的設置,官方有一個建議:4 核的機器建議設置為 2 或 3 個線程 , 8核的建議設置為 6 個線程 , 線程數一定要小于機器核數 。線程數并不是越大越好,官方認為超過了 8 個就很難繼續提效了,沒什么意義 。
# 假設你的CPU核數是8核,盡量配置成 5~6io-threads 5總結
  • 6.0之前,Redis所謂的單線程并不是所有工作都是只有一個線程在執行,而是指Redis的網絡IO和讀寫是由一個線程來完成的 。其他諸如持久化、異步刪除、集群數據同步等,其實是由額外的線程執行的 。
  • 互聯網飛速發展 , 開發人員面臨的線上流量場景越來越大 , 再使用單線程模式會導致在網絡 I/O 浪費太多時間 , 極大的降低吞吐量,而普遍多核的cpu又沒有得到有效的利用 。
  • 使用多線程,這樣可以充分利用多核CPU,提高網絡的 read/write 效率 。
  • 配置 Threaded I/O 多線程模式的時候,線程數一定要小于機器核數,否著意義不大 。
【追求性能極致:Redis6.0的多線程模型】

推薦閱讀