Redis 自帶了一個叫redis-benchmark的工具來模擬 N 個客戶端同時發出 M 個請求。 (類似於 Apacheab程式)。使用指令 redis-benchmark -h 可以查看基準測試參數。
以下参数被支持: Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests> [-k <boolean>] -h <hostname> Server hostname (default 127.0.0.1) -p <port> Server port (default 6379) -s <socket> Server socket (overrides host and port) -c <clients> Number of parallel connections (default 50) -n <requests> Total number of requests (default 10000) -d <size> Data size of SET/GET value in bytes (default 2) -k <boolean> 1=keep alive 0=reconnect (default 1) -r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD Using this option the benchmark will get/set keys in the form mykey_rand:000000012456 instead of constant keys, the <keyspacelen> argument determines the max number of values for the random number. For instance if set to 10 only rand:000000000000 - rand:000000000009 range will be allowed. -P <numreq> Pipeline <numreq> requests. Default 1 (no pipeline). -q Quiet. Just show query/sec values --csv Output in CSV format -l Loop. Run the tests forever -t <tests> Only run the comma separated list of tests. The test names are the same as the ones produced as output. -I Idle mode. Just open N idle connections and wait.</tests></numreq></numreq></keyspacelen></keyspacelen></boolean></size></requests></clients></socket></port></hostname></boolean></requests></clients></port></host>
你需要在基準測試之前啟動一個 Redis 實例。一般這樣啟動測試:
redis-benchmark -q -n 100000
這個工具使用起來非常方便,同時你可以使用自己的基準測試工具, 不過開始基準測試時候,我們需要注意一些細節。
每次執行redis-benchmark時不必預設執行所有測試。你可以使用參數"-t" 來指定需要運行的測試案例,例如以下範例:
$ redis-benchmark -t set,lpush -n 100000 -q SET: 74239.05 requests per second LPUSH: 79239.30 requests per second
在上面的測試中,我們只運行了SET 和LPUSH 命令, 並且運行在安靜模式中(使用-q參數)。
也可以直接指定命令來直接運行,例如下面的範例:
$ redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')" script load redis.call('set','foo','bar'): 69881.20 requests per second
預設情況下面,基準測試使用單一的 key。在一個基於記憶體的資料庫裡, 單一 key 測試和真實情況下面不會有巨大變化。當然,擴大密鑰範圍可以模擬真實情況下的快取未命中。
這時候我們可以使用-r指令。例如,如果我們希望連續進行100 萬次SET 操作,每次使用10 萬個隨機key,可以使用以下命令:
$ redis-cli flushall OK $ redis-benchmark -t set -r 100000 -n 1000000 ====== SET ====== 1000000 requests completed in 13.86 seconds 50 parallel clients 3 bytes payload keep alive: 1 99.76% `<h3>使用pipelining</h3><p>預設情況下,每個客戶端都是在一個請求完成之後才發送下一個請求(benchmark 會模擬50 個客戶端除非使用-c指定特別的數量), 這意味著伺服器幾乎是按順序讀取每個客戶端的命令。 Also RTT is payed as well.</p><p>真實世界會更複雜,Redis 支援/topics/pipelining,使得可以一次性執行多條命令成為可能。使用Redis pipelining可以增加伺服器的每秒事務處理率。 </p><p>下面這個案例是在Macbook air 11" 上使用pipelining 組織16 個指令的測試範例:</p><pre class="brush:php;toolbar:false">$ redis-benchmark -n 1000000 -t set,get -P 16 -q SET: 403063.28 requests per second GET: 508388.41 requests per second
記得在多條指令需要處理時候使用pipelining。
第一點是顯而易見的:基準測試的黃金準則是使用相同的標準。進行Redis 不同版本的測試時,可以採取同等任務量測試或使用相同參數進行測試。如果把Redis 和其他工具測試,那就需要小心功能細節差異。
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-benchmark 刻意讓基準測試看起來更好,所表現出來的數據像是人造的,而不是真實產品下面的。
Redis-benchmark 工具能夠迅速簡便地計算出在特定硬體條件下機器的性能參數。 但是,通常情況下面這並不是Redis 伺服器可以達到的最大吞吐量。使用 pipelining 和更快的客戶端(如hiredis),能夠實現更高的吞吐量。redis-benchmark 預設情況下面僅使用並發來提高吞吐量(創建多條連接)。它沒有採用pipelining或其他並發技術,只是使用了多個連接而非多線程。
如果想使用 pipelining 模式來進行基準測試(了達到更高吞吐量),可以使用-P參數。許多在生產環境中使用 Redis 的應用採用了這種方案以提高性能。
最後,基準測試需要使用相同的操作和數據來對比,如果這些不一樣, 那麼基準測試是無意義的。
例如,Redis和memcached可以在單執行緒模式下進行GET/SET操作的比較。兩者都是記憶體資料庫,協定基本上相同,甚至把多個請求合併為一條請求的方式也類似 (pipelining)。在使用相同數量的連接後,這個對比是很有意義的。
下面這個很不錯的例子是在 Redis(antirez)和 memcached(dormando)測試。
antirez 1 - On Redis, Memcached, Speed, Benchmarks and The Toilet
dormando - Redis VS Memcached (slightly better bench)
antirez 2 - An update on the Memcached/Redis benchmark
你可以發現相同條件下面最終結果是兩者差異不大。請注意最終測試時候, 兩者都經過了充分優化。
最後,當特別高效能的伺服器在基準測試時候(例如 Redis、memcached 這類), 很難讓伺服器效能充分發揮,通常情況下,客戶端回事瓶頸限製而不是伺服器端。在這種情況下面,客戶端(例如 benchmark 程式本身)需要最佳化,或使用多實例, 從而達到最大的吞吐量。
有幾個因素直接決定 Redis 的性能。它們能夠改變基準測試的結果, 所以我們必須注意到它們。通常情況下, Redis 的預設參數已經足夠提供高效的效能,因此不需要進行調優。
網路頻寬和延遲通常是最大短板。我建議在進行基準測試之前先使用 ping 命令對服務端和用戶端之間的延遲進行檢測。根據頻寬,可以計算出最大吞吐量。例如將 4 KB 的字串塞入 Redis,吞吐量是 100000 q/s,那麼實際需要 3.2 Gbits/s 的頻寬,所以需要 10 GBits/s 網路連接, 1 Gbits/s 是不夠的。在許多線上服務中,網路頻寬往往比 CPU 更早成為限制Redis吞吐量的因素。為了達到高吞吐量突破 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 回環介面。
當使用大量 pipelining 時,Unix 網域套接字的好處就變得不那麼顯著了。
當使用網路連線時,且乙太網路封包在 1500 bytes 以下時, 將多條指令包裝成 pipelining 可以大大提高效率。事實上,處理 10 bytes,100 bytes, 1000 bytes 的請求時候,吞吐量是差不多的,詳細可以見下圖。
Redis 的效能在多核心 CPU 伺服器上也取決於 NUMA 配置和處理器綁定位置。 Redis-benchmark的最顯著的影響是它會隨機地利用CPU核心。為了獲得精準的結果, 需要使用固定處理器工具(在 Linux 上可以使用 taskset 或 numactl)。最有效的辦法是將客戶端和服務端分離到兩個不同的 CPU 來高校使用三級快取。這裡有一些使用 4 KB 資料 SET 的基準測試,針對三種 CPU(AMD Istanbul, Intel Nehalem EX, 和 Intel Westmere)使用不同的配置。請注意, 這不是針對 CPU 的測試。
在高配置下面,客戶端的連線數也是一個重要的因素。 Redis 的事件循環得益於 epoll/kqueue,因此具有很高的可擴展性。 Redis 已經在超過 60000 連接下面基準測試過, 仍然可以維持 50000 q/s。一條經驗法則是,30000 的連線數只有 100 連線的一半吞吐量。下面有一個關於連線數和吞吐量的測試。
在高配置下面,可以通过调优 NIC 来获得更高性能。最高性能在绑定 Rx/Tx 队列和 CPU 内核下面才能达到,还需要开启 RPS(网卡中断负载均衡)。更多信息可以在thread。Jumbo frames 还可以在大对象使用时候获得更高性能。
在不同平台下面,Redis 可以被编译成不同的内存分配方式(libc malloc, jemalloc, tcmalloc),他们在不同速度、连续和非连续片段下会有不一样的表现。若非编译自行进行的 Redis,可用 INFO 命令验证内存分配方式。 请注意,大部分基准测试不会长时间运行来感知不同分配模式下面的差异, 只能通过生产环境下面的 Redis 实例来查看。
任何基准测试的一个重要目标是获得可重现的结果,这样才能将此和其他测试进行对比。
一个好的实践是尽可能在隔离的硬件上面测试。需要检查基准测试是否受到其他服务器活动的影响,如果无法实现的话。
有些配置(桌面环境和笔记本,有些服务器也会)会使用可变的 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 命令会严重影响测试准确性。
这些测试模拟了 50 客户端和 200w 请求。
使用了 Redis 2.6.14。
使用了 loopback 网卡。
key 的范围是 100 w。
同时测试了 有 pipelining 和没有的情况(16 条命令使用 pipelining)。
Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (with pipelining)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -P 16 -q SET: 552028.75 requests per second GET: 707463.75 requests per second LPUSH: 767459.75 requests per second LPOP: 770119.38 requests per second
Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (without pipelining)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q SET: 122556.53 requests per second GET: 123601.76 requests per second LPUSH: 136752.14 requests per second LPOP: 132424.03 requests per second
Linode 2048 instance (with pipelining)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q -P 16 SET: 195503.42 requests per second GET: 250187.64 requests per second LPUSH: 230547.55 requests per second LPOP: 250815.16 requests per second
Linode 2048 instance (without pipelining)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q SET: 35001.75 requests per second GET: 37481.26 requests per second LPUSH: 36968.58 requests per second LPOP: 35186.49 requests per second
$ redis-benchmark -n 100000 ====== SET ====== 100007 requests completed in 0.88 seconds 50 parallel clients 3 bytes payload keep alive: 1 58.50% <p>注意:包大小从 256 到 1024 或者 4096 bytes 不会改变结果的量级 (但是到 1024 bytes 后,GETs 操作会变慢)。同样的,50 到 256 客户端的测试结果相同。当使用10个客户端时,总吞吐量无法达到最大吞吐量。</p><p>不同机器可以获的不一样的结果,下面是Intel T5500 1.66 GHz 在 Linux 2.6下面的结果:</p><pre class="brush:php;toolbar:false">$ ./redis-benchmark -q -n 100000 SET: 53684.38 requests per second GET: 45497.73 requests per second INCR: 39370.47 requests per second LPUSH: 34803.41 requests per second LPOP: 37367.20 requests per second
另外一个是 64 位 Xeon L5420 2.5 GHz 的结果:
$ ./redis-benchmark -q -n 100000 PING: 111731.84 requests per second SET: 108114.59 requests per second GET: 98717.67 requests per second INCR: 95241.91 requests per second LPUSH: 104712.05 requests per second LPOP: 93722.59 requests per second
Redis2.4.2 。
默认连接数,数据包大小 256 bytes。
Linux 是SLES10 SP3 2.6.16.60-0.54.5-smp,CPU 是 2 xIntel X5670 @ 2.93 GHz。
固定 CPU,但是使用不同 CPU 内核。
使用 unix domain socket:
$ numactl -C 6 ./redis-benchmark -q -n 100000 -s /tmp/redis.sock -d 256 PING (inline): 200803.22 requests per second PING: 200803.22 requests per second MSET (10 keys): 78064.01 requests per second SET: 198412.69 requests per second GET: 198019.80 requests per second INCR: 200400.80 requests per second LPUSH: 200000.00 requests per second LPOP: 198019.80 requests per second SADD: 203665.98 requests per second SPOP: 200803.22 requests per second LPUSH (again, in order to bench LRANGE): 200000.00 requests per second LRANGE (first 100 elements): 42123.00 requests per second LRANGE (first 300 elements): 15015.02 requests per second LRANGE (first 450 elements): 10159.50 requests per second LRANGE (first 600 elements): 7548.31 requests per second
使用 TCP loopback:
$ numactl -C 6 ./redis-benchmark -q -n 100000 -d 256 PING (inline): 145137.88 requests per second PING: 144717.80 requests per second MSET (10 keys): 65487.89 requests per second SET: 142653.36 requests per second GET: 142450.14 requests per second INCR: 143061.52 requests per second LPUSH: 144092.22 requests per second LPOP: 142247.52 requests per second SADD: 144717.80 requests per second SPOP: 143678.17 requests per second LPUSH (again, in order to bench LRANGE): 143061.52 requests per second LRANGE (first 100 elements): 29577.05 requests per second LRANGE (first 300 elements): 10431.88 requests per second LRANGE (first 450 elements): 7010.66 requests per second LRANGE (first 600 elements): 5296.61 requests per second
以上是Redis基準參數怎麼查看的詳細內容。更多資訊請關注PHP中文網其他相關文章!