CPU架構
- 一個 CPU 處理器中一般有多個物理核。
- 每個物理核都擁有私有的一級緩存( L1 cache)和私有的二級緩存(L2 cache)。
- 不同的物理核還會共享一個共同的三級緩存
- 每個物理核通常都會運行兩個超線程,也叫作邏輯核。同一個物理核的邏輯核會共享使用 L1、L2 緩存
- 不同處理器間通過總線連接
問題
1、多CPU:如果應用程序先在一個 Socket(CPU處理器) 上運行,並且把數據保存到了內存,然后被調度到另一個 Socket 上運行,此時,應用程序再進行內存訪問時,就需要訪問之前 Socket 上連接的內存,這種訪問屬於遠端內存訪問。和訪問 Socket 直接連接的內存相比,遠端內存訪問會增加應用程序的延遲。(NUMA)
2、多核:Redis 主線程的運行時信息需要被重新加載到另一個 CPU 物理核上,而且,此時,另一個 CPU 物理核上的 L1、L2 緩存中並沒有 Redis 實例之前運行時頻繁訪問的指令和數據,所以,這些指令和數據都需要重新從 L3 緩存,甚至是內存中加載。
3、Redis 實例和網絡中斷程序的數據交互:網絡中斷處理程序從網卡硬件中讀取數據,並把數據寫入到操作系統內核維護的一塊內存緩沖區。內核會通過 epoll 機制觸發事件,通知 Redis 實例,Redis 實例再把數據從內核的內存緩沖區拷貝到自己的內存空間。可能存在跨CPU拷貝內存數據。
優化
1、把 Redis 實例和 CPU 物理核綁定了,讓一個 Redis 實例固定運行在一個 CPU 物理核上
2、把操作系統的網絡中斷處理程序和 CPU 物理核綁定。Redis 實例綁定在同一個物理核上。
3、使用源碼優化方案,既可以實現 Redis 實例綁核,避免切換核帶來的性能影響,還可以讓子進程、后台線程和主線程不在同一個核上運行,避免了它們之間的 CPU 資源競爭。
注:NUMA架構下,先給每個 CPU Socket 中每個物理核的第一個邏輯核依次編號,再給每個 CPU Socket 中的物理核的第二個邏輯核依次編號。