[轉帖]Redis如何繫結CPU

济南小老虎發表於2024-06-21
https://wenfh2020.com/2023/10/08/https/

釋出時間:2022-03-08 09:44:39 閱讀:649 作者:小新 欄目:開發技術
開發者測試專用伺服器限時活動,0元免費領,庫存有限,領完即止! 點選檢視>>

這篇文章主要介紹了Redis如何繫結CPU,具有一定借鑑價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之後大有收穫,下面讓小編帶著大家一起了解一下。

繫結 CPU

Redis 6.0 開始支援繫結 CPU,可以有效減少執行緒上下文切換。

CPU 親和性(CPU Affinity)是一種排程屬性,它將一個程序或執行緒,「繫結」到一個或一組 CPU 上。也稱為 CPU 繫結。

設定 CPU 親和性可以一定程度避免 CPU 上下文切換,提高 CPU L1、L2 Cache 命中率。

早期「SMP」架構下,每個 CPU 透過 BUS 匯流排共享資源。CPU 繫結意義不大。

Redis如何繫結CPU
而在當前主流的「NUMA」架構下,每個 CPU 有自己的本地記憶體。訪問本地記憶體有更快的速度。而訪問其他 CPU 記憶體會導致較大的延遲。這時,CPU 繫結對系統執行速度的提升有較大的意義。

Redis如何繫結CPU
現實中的 NUMA 架構比上圖更復雜,通常會將 CPU 分組,若干個 CPU 分配一組記憶體,稱為 「node」

你可以透過 「numactl -H 」 命令來檢視 NUMA 硬體資訊。

$ numactl -H
available: 2 nodes (0-1)node 0 cpus: 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38
node 0 size: 32143 MB
node 0 free: 26681 MB
node 1 cpus: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39
node 1 size: 32309 MB
node 1 free: 24958 MB
node distances:
node 0 1
  0: 10 21
  1: 21 10

上圖中可以得知該機器有 40 個 CPU,分組為 2 個 node。

node distances 是一個二維矩陣,表示 node 之間 「訪問距離」,10 為基準值。上述命令中可以得知,node 自身訪問,距離是 10。跨 node 訪問,如 node 0 訪問 node 1 距離為 21。說明該機器「跨 node 訪問速度」比「node 自身訪問速度」慢 2.1 倍。

其實,早在 2015 年,有人提出 Redis 需要支援設定 CPU 親和性,而當時的 Redis 還沒有支援 IO 多執行緒,該提議擱置。

而 Redis 6.0 引入 IO 多執行緒。同時,也支援了設定 CPU 親和性

我畫了一張 Redis 6.0 執行緒家族供你參考。

Redis如何繫結CPU

上圖可分為 3 個模組

  • 主執行緒和 IO 執行緒:負責命令讀取、解析、結果返回。命令執行由主執行緒完成。

  • bio 執行緒:負責執行耗時的非同步任務,如 close fd。

  • 後臺程序:fork 子程序來執行耗時的命令。

Redis 支援分別配置上述模組的 CPU 親和度。你可以在 redis.conf 找到以下配置(該配置需手動開啟)。

# IO 執行緒(包含主執行緒)繫結到 CPU 0、2、4、6
server_cpulist 0-7:2
# bio 執行緒繫結到 CPU 1、3
bio_cpulist 1,3
# aof rewrite 後臺程序繫結到 CPU 8、9、10、11
aof_rewrite_cpulist 8-11
# bgsave 後臺程序繫結到 CPU 1、10、11
bgsave_cpulist 1,10-11

我在上述機器,針對 IO 執行緒和主執行緒,進行如下測試:

首先,開啟 IO 執行緒配置

io-threads 4 # 主執行緒 + 3 個 IO 執行緒io-threads-do-reads yes # IO 執行緒開啟讀和解析命令功能

測試如下三種場景:

  1. 不開啟 CPU 繫結配置。

  2. 繫結到不同 node。
    「server_cpulist 0,1,2,3」

  3. 繫結到相同 node。
    「server_cpulist 0,2,4,6」

透過 redis-benchmark 對 get 命令進行基準測試,每種場景執行 3 次。

$ redis-benchmark -n 5000000 -c 50 -t get --threads 4

結果如下:

1.不開啟 CPU 繫結配置

throughput summary: 248818.11 requests per second
throughput summary: 248694.36 requests per second
throughput summary: 249004.00 requests per second

2.繫結不同 node

throughput summary: 248880.03 requests per second
throughput summary: 248447.20 requests per second
throughput summary: 248818.11 requests per second

3.繫結相同 node

throughput summary: 284414.09 requests per second
throughput summary: 284333.25 requests per second
throughput summary: 265252.00 requests per second

根據測試結果,繫結到同一個 node,qps 大約提升 15%

使用繫結 CPU,你需要注意以下幾點:

  1. Linux 下,你可以使用 「numactl --hardware」 檢視硬體佈局,確保支援並開啟 NUMA。

  2. 執行緒要儘可能分佈在 「不同的 CPU,相同的 node」,設定 CPU 親和度才有效。否則會造成頻繁上下文切換和遠距離記憶體訪問。

  3. 你要熟悉 CPU 架構,做好充分的測試。否則可能適得其反,導致 Redis 效能下降。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Redis如何繫結CPU”這篇文章對大家有幫助,同時也希望大家多多支援億速雲,關注億速雲行業資訊頻道,更多相關知識等著你來學習!

相關文章