Redis壓測
測試命令
這條命令redis自帶
redis-benchmark [option] [option value]
redis 效能測試工具可選引數如下所示:
序號 | 選項 | 描述 | 預設值 |
---|---|---|---|
1 | -h | 指定伺服器主機名 | 127.0.0.1 |
2 | -p | 指定伺服器埠 | 6379 |
3 | -s | 指定伺服器 socket | |
4 | -c | 指定併發連線數 | 50 |
5 | -n | 指定請求數 | 10000 |
6 | -d | 以位元組的形式指定 SET/GET 值的資料大小 | 2 |
7 | -k | 1=keep alive 0=reconnect | 1 |
8 | -r | SET/GET/INCR 使用隨機 key, SADD 使用隨機值 | |
9 | -P | 通過管道傳輸 請求 | 1 |
10 | -q | 強制退出 redis。僅顯示 query/sec 值 | |
11 | –csv | 以 CSV 格式輸出 | |
12 | -l | 生成迴圈,永久執行測試 | |
13 | -t | 僅執行以逗號分隔的測試命令列表。 | |
14 | -I | Idle 模式。僅開啟 N 個 idle 連線並等待。 |
案例一 效能資訊分析
機器配置
1.png
2.png
3.png
# 測試100個併發連線 # 一個併發連線有100000個請求 [root@node-a ~]# redis-benchmark -h 1.1.1.1 -p 6379 -c 100 -n 100000 -q PING_INLINE: 94696.97 requests per second PING_BULK: 116550.12 requests per second SET: 121654.50 requests per second GET: 121359.23 requests per second INCR: 121065.38 requests per second LPUSH: 122399.02 requests per second RPUSH: 121802.68 requests per second LPOP: 119189.52 requests per second RPOP: 121654.50 requests per second SADD: 121065.38 requests per second HSET: 121802.68 requests per second SPOP: 122399.02 requests per second LPUSH (needed to benchmark LRANGE): 122850.12 requests per second LRANGE_100 (first 100 elements): 59701.50 requests per second LRANGE_300 (first 300 elements): 20088.39 requests per second LRANGE_500 (first 450 elements): 13825.52 requests per second LRANGE_600 (first 600 elements): 10363.77 requests per second # 每秒處理87719個請求 MSET (10 keys): 87719.30 requests per second
set
[root@node-a ~]# redis-benchmark -h 1.1.1.1 -p 6379 -c 100 -n 100000 -t set
====== SET ======
10000 requests completed in 0.11 seconds
100 parallel clients
3 bytes payload
keep alive: 1
99.08% <= 1 milliseconds
100.00% <= 1 milliseconds
90090.09 requests per second
get
[root@node-a ~]# redis-benchmark -h 1.1.1.1 -p 6379 -c 100 -n 100000 -t get ====== GET ====== 100000 requests completed in 1.03 seconds 100 parallel clients 3 bytes payload keep alive: 1 99.87% <= 1 milliseconds 100.00% <= 1 milliseconds 96711.80 requests per second
pipelining
預設情況下,每個客戶端都是在一個請求完成之後才傳送下一個請求 (benchmark 會模擬 50 個客戶端除非使用 -c 指定特別的數量), 這意味著伺服器幾乎是按順序讀取每個客戶端的命令。Also RTT is payed as well.
真實世界會更復雜,Redis 支援 /topics/pipelining,使得可以一次性執行多條命令成為可能。 Redis pipelining 可以提高伺服器的 TPS。 下面這個案例是在 Macbook air 11” 上使用 pipelining 組織 16 條命令的測試範例:
[root@node-a ~]# redis-benchmark -h 1.1.1.1 -p 6379 -n 100000 -t set,get -P 16
====== SET ======
100000 requests completed in 0.14 seconds
50 parallel clients
3 bytes payload
keep alive: 1
54.66% <= 1 milliseconds
100.00% <= 1 milliseconds
740740.69 requests per second
====== GET ======
100000 requests completed in 0.09 seconds
50 parallel clients
3 bytes payload
keep alive: 1
98.96% <= 1 milliseconds
100.00% <= 1 milliseconds
1063829.88 requests per second
小結
- Redis 是一個伺服器:所有的命令都包含網路或 IPC 消耗。這意味著和它和 SQLite, Berkeley DB, Tokyo/Kyoto Cabinet 等比較起來無意義, 因為大部分的消耗都在網路協議上面。
- Redis 的大部分常用命令都有確認返回。有些資料儲存系統則沒有(比如 MongoDB 的寫操作沒有返回確認)。把 Redis 和其他單向呼叫命令儲存系統比較意義不大。
- 簡單的迴圈操作 Redis 其實不是對 Redis 進行基準測試,而是測試你的網路(或者 IPC)延遲。想要真正測試 Redis,需要使用多個連線(比如 redis-benchmark), 或者使用 pipelining 來聚合多個命令,另外還可以採用多執行緒或多程序。
- Redis 是一個記憶體資料庫,同時提供一些可選的持久化功能。 如果你想和一個持久化伺服器(MySQL, PostgreSQL 等等) 對比的話, 那你需要考慮啟用 AOF 和適當的 fsync 策略。
- Redis 是單執行緒服務。它並沒有設計為多 CPU 進行優化。如果想要從多核獲取好處, 那就考慮啟用多個例項吧。將單例項 Redis 和多執行緒資料庫對比是不公平的。
影響 Redis 效能的因素
有幾個因素直接決定 Redis 的效能。它們能夠改變基準測試的結果, 所以我們必須注意到它們。一般情況下,Redis 預設引數已經可以提供足夠的效能, 不需要調優。
-
網路頻寬和延遲通常是最大短板。建議在基準測試之前使用 ping 來檢查服務端到客戶端的延遲。根據頻寬,可以計算出最大吞吐量。 比如將 4 KB 的字串塞入 Redis,吞吐量是 100000 q/s,那麼實際需要 3.2 Gbits/s 的頻寬,所以需要 10 GBits/s 網路連線, 1 Gbits/s 是不夠的。 在很多線上服務中,Redis 吞吐會先被網路頻寬限制住,而不是 CPU。 為了達到高吞吐量突破 TCP/IP 限制,最後採用 10 Gbits/s 的網絡卡, 或者多個 1 Gbits/s 網絡卡。
-
CPU 是另外一個重要的影響因素,由於是單執行緒模型,Redis 更喜歡大快取快速 CPU, 而不是多核。這種場景下面,比較推薦 Intel CPU。AMD CPU 可能只有 Intel CPU 的一半效能(通過對 Nehalem EP/Westmere EP/Sandy 平臺的對比)。 當其他條件相當時候,CPU 就成了 redis-benchmark 的限制因素。
-
在小物件存取時候,記憶體速度和頻寬看上去不是很重要,但是對大物件(> 10 KB), 它就變得重要起來。不過通常情況下面,倒不至於為了優化 Redis 而購買更高效能的記憶體模組。
-
Redis 在 VM 上會變慢。虛擬化對普通操作會有額外的消耗,Redis 對系統呼叫和網路終端不會有太多的 overhead。建議把 Redis 執行在物理機器上, 特別是當你很在意延遲時候。在最先進的虛擬化裝置(VMWare)上面,redis-benchmark 的測試結果比物理機器上慢了一倍,很多 CPU 時間被消費在系統呼叫和中斷上面。
-
如果伺服器和客戶端都執行在同一個機器上面,那麼 TCP/IP loopback 和 unix domain sockets 都可以使用。對 Linux 來說,使用 unix socket 可以比 TCP/IP loopback 快 50%。 預設 redis-benchmark 是使用 TCP/IP loopback。 當大量使用 pipelining 時候,unix domain sockets 的優勢就不那麼明顯了。
-
當大量使用 pipelining 時候,unix domain sockets 的優勢就不那麼明顯了。
-
當使用網路連線時,並且乙太網網資料包在 1500 bytes 以下時, 將多條命令包裝成 pipelining 可以大大提高效率。事實上,處理 10 bytes,100 bytes, 1000 bytes 的請求時候,吞吐量是差不多的,詳細可以見下圖。
-
在多核 CPU 伺服器上面,Redis 的效能還依賴 NUMA 配置和 處理器繫結位置。 最明顯的影響是 redis-benchmark 會隨機使用 CPU 核心。為了獲得精準的結果, 需要使用固定處理器工具(在 Linux 上可以使用 taskset 或 numactl)。 最有效的辦法是將客戶端和服務端分離到兩個不同的 CPU 來高校使用三級快取。 這裡有一些使用 4 KB 資料 SET 的基準測試,針對三種 CPU(AMD Istanbul, Intel Nehalem EX, 和 Intel Westmere)使用不同的配置。請注意, 這不是針對 CPU 的測試。
-
在高配置下面,客戶端的連線數也是一個重要的因素。得益於 epoll/kqueue, Redis 的事件迴圈具有相當可擴充套件性。Redis 已經在超過 60000 連線下面基準測試過, 仍然可以維持 50000 q/s。一條經驗法則是,30000 的連線數只有 100 連線的一半吞吐量。 下面有一個關於連線數和吞吐量的測試。
-
在高配置下面,可以通過調優 NIC 來獲得更高效能。最高效能在繫結 Rx/Tx 佇列和 CPU 核心下面才能達到,還需要開啟 RPS(網絡卡中斷負載均衡)。更多資訊可以在thread 。Jumbo frames 還可以在大物件使用時候獲得更高效能。
-
在不同平臺下面,Redis 可以被編譯成不同的記憶體分配方式(libc malloc, jemalloc, tcmalloc),他們在不同速度、連續和非連續片段下會有不一樣的表現。 如果你不是自己編譯的 Redis,可以使用 INFO 命令來檢查記憶體分配方式。 請注意,大部分基準測試不會長時間執行來感知不同分配模式下面的差異, 只能通過生產環境下面的 Redis 例項來檢視。
其他需要注意的點
任何基準測試的一個重要目標是獲得可重現的結果,這樣才能將此和其他測試進行對比。
- 一個好的實踐是儘可能在隔離的硬體上面測試。如果沒法實現,那就需要檢測 benchmark 沒有受其他伺服器活動影響。
- 有些配置(桌面環境和筆記本,有些伺服器也會)會使用可變的 CPU 分配策略。 這種策略可以在 OS 層面配置。有些 CPU 型號相對其他能更好的調整 CPU 負載。 為了達到可重現的測試結果,最好在做基準測試時候設定 CPU 到最高使用限制。
- 一個重要因素是配置儘可能大記憶體,千萬不要使用 SWAP。注意 32 位和 64 位 Redis 有不同的記憶體限制。
- 如果你計劃在基準測試時候使用 RDB 或 AOF,請注意不要讓系統同時有其他 I/O 操作。 避免將 RDB 或 AOF 檔案放到 NAS 或 NFS 共享或其他依賴網路的儲存裝置上面(比如 Amazon EC2 上 的 EBS)。
- 將 Redis 日誌級別設定到 warning 或者 notice。避免將日誌放到遠端檔案系統。
- 避免使用檢測工具,它們會影響基準測試結果。使用 INFO 來檢視伺服器狀態沒問題, 但是使用 MONITOR 將大大影響測試準確度;
111