1. 程式人生 > >Redis效能篇(二)CPU核和NUMA架構的影響

Redis效能篇(二)CPU核和NUMA架構的影響

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

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

這一講,我們來學習一下CPU對Redis的效能影響及應對方法。

主流CPU架構

學習之前,我們先來了解主流CPU架構有哪些,有什麼特點,以便我們更好地瞭解CPU是如何影響Redis的。

CPU多核架構

  • 一個CPU處理器中一般有多個執行核心,稱為物理核。
  • 物理核包括私有的一級指令/資料快取(L1快取)和二級快取(L2快取)。
  • 每個物理核會執行兩個超執行緒,也叫作邏輯核。同一個物理核的邏輯核會共享使用L1、L2快取。
  • 不同的物理核共享三級快取(L3快取)

多CPU Socket架構

在多CPU架構上,應用程式可以在不同的處理器上執行。

應用程式在不同的Socket間排程執行時,訪問之前的Socket的記憶體,這種訪問屬於遠端記憶體訪問。

和訪問Socket直接連線的記憶體相比,遠端記憶體訪問會增加應用程式的延遲。

把這個架構稱為非統一記憶體訪問架構(Non-Uniform Memory Access,NUMA架構)。

CPU多核對Redis效能的影響

如果在CPU多核場景下,Redis例項被頻繁排程到不同CPU核上執行的話,那麼,對Redis例項的請求處理時間影響就更大了。每排程一次,一些請求就會受到執行時資訊、指令和資料重新載入過程的影響,這就會導致某些請求的延遲明顯高於其他請求。

要避免Redis總是在不同CPU核上來回排程執行。最直接的方法是把Redis例項和CPU核綁定了,讓一個Redis例項固定執行在一個CPU核上。

通過taskset命令進行綁核:

taskset -c 0 ./redis-server

綁核不僅對降低尾延遲有好處,同樣也能降低平均延遲、提升吞吐率,進而提升Redis效能。

CPU的NUMA架構對Redis效能的影響

在實際應用Redis時,有一種做法:為了提升Redis的網路效能,把作業系統的網路中斷處理程式和CPU核繫結。

在CPU的NUMA架構下,當網路中斷處理程式、Redis例項分別和CPU核繫結後,就會有一個潛在的風險:如果網路中斷處理程式和Redis例項各自所綁的CPU核不在同一個CPU Socket上,那麼,Redis例項讀取網路資料時,就需要跨CPU Socket訪問記憶體,這個過程會花費較多時間。

為了避免Redis跨CPU Socket訪問網路資料,我們最好把網路中斷程式和Redis例項綁在同一個CPU Socket上,這樣一來,Redis例項就可以直接從本地記憶體讀取網路資料了。

CPU的NUMA架構下進行繫結要注意CPU核的編號規則,可以執行lscpu命令來檢視核的編號。

lscpu

Architecture: x86_64
...
NUMA node0 CPU(s): 0-5,12-17
NUMA node1 CPU(s): 6-11,18-23
...

 

不過,凡事都有兩面性,綁核也存在一定的風險。接下來就來了解下它的潛在風險點和解決方案。

綁核的風險和解決方案

方案一:一個Redis例項對應綁一個物理核

在給Redis例項綁核時,我們不要把一個例項和一個邏輯核繫結,而要和一個物理核繫結,也就是說,把一個物理核的2個邏輯核都用上。

方案二:優化Redis原始碼

通過修改Redis原始碼,把子程序和後臺執行緒綁到不同的CPU核上。

參考資料

  • 17 | 為什麼CPU結構也會影響Redis的效能?