拋磚系列之redis監控命令

  

前言

redis是一款非常流行的kv數據庫,以高性能著稱,其高吞吐、低延遲等特性讓廣大開發者趨之若鶩,每每看到別人發出的redis故障報告都讓我產生一種居安思危,以史爲鑑的危機感,恰逢今年十一西安煙雨不斷,抽時間學習了幾個redis監控命令,和大家分享一波。

redis-cli --stat【連續統計】

 連續統計可能是實時監控 Redis 實例的鮮爲人知但非常有用的功能之一,要啓用此功能,請使用redis-cli --stat。

redis-cli --stat 默認每秒輸出一條新行,其中包含有用信息和每個採集點的請求次數差異。使用此命令可以輕鬆瞭解內存使用情況、客戶端連接計數以及有關已連接 Redis 數據庫的各種其他統計信息。

可以使用-i修改採樣頻率,默認值爲1秒,如下面這個命令代表每2s採集一次數據:

redis-cli --stat -i 2
------- data ------ --------------------- load -------------------- - child -
keys       mem      clients blocked requests            connections          
8890       131.89M  47      0       1705992846 (+0)     2595        
8890       131.93M  47      0       1705992897 (+51)    2595        
8890       131.93M  47      0       1705992954 (+57)    2595        
8890       131.97M  47      0       1705992991 (+37)    2595        
8890       131.89M  47      0       1705993043 (+52)    2595        
8890       131.97M  47      0       1705993088 (+45)    2595        
8890       132.01M  47      0       1705993122 (+34)    2595        
8890       132.01M  47      0       1705993168 (+46)    2595        
8890       132.01M  47      0       1705993194 (+26)    2595        
8890       131.93M  47      0       1705993267 (+73)    2595

 

redis-cli --bigkeys【統計大key】

這個命令用作鍵空間分析器,它掃描數據集中的大鍵,但也提供有關數據集所包含的數據類型的信息。

 
# redis-cli --bigkeys

# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).

[00.00%] Biggest hash   found so far '"hash_big"' with 6 fields
[00.00%] Biggest set    found so far '"set_big"' with 6 members
[00.00%] Biggest string found so far '"string_big"' with 979 bytes
[00.00%] Biggest string found so far '"string_big_2"' with 1365 bytes

-------- summary -------

Sampled 5 keys in the keyspace!
Total key length in bytes is 38 (avg len 7.60)

Biggest   hash found '"hash_big"' has 6 fields
Biggest string found '"string_big_2"' has 1365 bytes
Biggest    set found '"set_big"' has 6 members

0 lists with 0 items (00.00% of keys, avg size 0.00)
1 hashs with 6 fields (20.00% of keys, avg size 6.00)
3 strings with 2420 bytes (60.00% of keys, avg size 806.67)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
1 sets with 6 members (20.00% of keys, avg size 6.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)

在輸出的第一部分中,將報告遇到的每個大於前一個較大key(相同類型)的新key。摘要部分提供有關 Redis 實例內數據的一般統計信息。

該程序使用 SCAN 命令,因此它可以在繁忙的服務器上執行而不會影響操作,當然也可以使用-i選項來限制每個 SCAN 命令的指定秒數部分的掃描過程。

例如,redis-cli --bigkeys  -i 1 代表每次SCAN執行之後sleep 1s。

可以看到--bigkeys給出了每種數據結構的top 1 bigkey,同時給出了每種數據類型的鍵值個數以及平均大小。 

redis-cli monitor【監控命令執行】

 與“發佈/訂閱”模式類似,使用 MONITOR 命令後,將自動進入監視模式, Redis 實例接收的所有命令都將打印到標準輸出中:
redis-cli monitor
1665128881.578949 [0 127.0.0.1:46046] "COMMAND" "DOCS"
1665128885.870333 [0 127.0.0.1:46046] "get" "a"
1665128891.200705 [0 127.0.0.1:46046] "set" "a" "asdfasdfasd" "asdfasdf"
1665128897.234390 [0 127.0.0.1:46046] "sadd" "test" "aaa"
1665128902.439247 [0 127.0.0.1:46046] "smembers" "test"
1665128906.257225 [0 127.0.0.1:46046] "smembers" "test"
1665128910.073980 [0 127.0.0.1:46046] "smembers" "test"
1665128914.688753 [0 127.0.0.1:46046] "hget" "all" "hello"
1665128918.006031 [0 127.0.0.1:46046] "hget" "all" "hello"

可以看到目前smembers和hget命令執行的比較頻繁,可能是異常流量導致,需要引起我們的注意了。

更方便的是redis-cli monitor可以和管道配合使用,比如redis-cli monitor | grep goods_test_001

redis-cli monitor |grep goods_test_001
1665129150.063322 [0 127.0.0.1:46046] "get" "goods_test_001"
1665129150.935202 [0 127.0.0.1:46046] "get" "goods_test_001"
1665129151.486148 [0 127.0.0.1:46046] "get" "goods_test_001"
1665129152.012097 [0 127.0.0.1:46046] "get" "goods_test_001"
1665129152.550077 [0 127.0.0.1:46046] "get" "goods_test_001"
1665129153.059130 [0 127.0.0.1:46046] "get" "goods_test_001"
1665129153.595023 [0 127.0.0.1:46046] "get" "goods_test_001"
1665129154.166608 [0 127.0.0.1:46046] "get" "goods_test_001"
1665129154.687753 [0 127.0.0.1:46046] "get" "goods_test_001"
1665129155.204012 [0 127.0.0.1:46046] "get" "goods_test_001"

結合grep goods_test_001可以發現goods_test_001這個key當前有大量的讀請求。  

Pub/sub mode【發佈訂閱模式】

redis-cli可以用來發布/訂閱消息,如果你的系統中使用了redis的發佈訂閱功能,可以使用redis-cli的這一特性來進行一些調試工作。

比如,使用redis-cli發佈一條消息到mychannel

 redis-cli publish mychannel helloworld

同樣的,使用redis-cli訂閱mychannel發來的消息

 
redis-cli subscribe mychannel
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "mychannel"
3) (integer) 1
1) "message"
2) "mychannel"
3) "helloworld"

Monitoring the latency of Redis instances【監控延遲】

 redis常用來構建延遲敏感的應用,延遲涉及多個環節,客戶端到網絡層之間,網絡層到redis之間,redis自身處理等。

redis-cli提供了多種工具幫助我們發現延遲,涉及的指標有最小值、最大值、平均值、延遲分佈情況等。

基本的延遲檢查工具是redis-cli --latency。使用--latency,redis-cli 運行一個循環,以每秒100次的速度向redis發送PING命令,並測量收到回覆的時間,統計信息在控制檯中實時更新。

# redis-cli --latency
min: 0, max: 3, avg: 0.28 (536 samples)

統計數據以毫秒爲單位,上面的測試一共發了536個PING命令,最小響應時間爲0毫秒(0不代表沒有延遲,只是說毫秒統計不到),最大爲3毫秒,平均值爲0.28毫秒。

有時我們更希望看到redis延遲變化的趨勢,這時--latency-history就可以派上用場,它的工作機制和--latency相同,只是每15秒(默認)重新開啓一個測試會話。

redis-cli --latency-history
min: 0, max: 7, avg: 0.25 (1432 samples) -- 15.00 seconds range
min: 0, max: 1, avg: 0.24 (1435 samples) -- 15.00 seconds range
min: 0, max: 15, avg: 0.27 (1429 samples) -- 15.01 seconds range
min: 0, max: 5, avg: 0.28 (1431 samples) -- 15.01 seconds range
min: 0, max: 5007, avg: 7.71 (839 samples) -- 15.01 seconds range
min: 1, max: 18, avg: 3.58 (1092 samples) -- 15.01 seconds range
min: 0, max: 13, avg: 3.56 (1093 samples) -- 15.01 seconds range
min: 1, max: 15, avg: 3.61 (1090 samples) -- 15.00 seconds range
min: 1, max: 17, avg: 3.60 (1091 samples) -- 15.01 seconds range
min: 0, max: 26, avg: 2.57 (1178 samples) -- 15.00 seconds range

可以看到,上面每隔15秒輸出一組數據,在第5個15秒開始時耗時明顯增加。

內部還實現了另一個非比尋常的延遲檢測工具,它不檢查 Redis 實例的延遲,而是檢查運行的計算機的延遲,此延遲是內核計劃程序、虛擬機管理程序(如果是虛擬化實例)等所固有的。

redis稱之爲內在延遲,因爲它對程序員來說基本上是不透明的,如果 redis 實例具有高延遲,檢查其他因素之外,還值得檢查內核本身的延遲。

通過測量內在延遲,我們就知道這是基準,redis 無法超越內核,使用redis-cli --intrinsic-latency <持續時間>開啓測試,持續時間5秒。

redis-cli --intrinsic-latency 5
Max latency so far: 1 microseconds.
Max latency so far: 16 microseconds.
Max latency so far: 70 microseconds.
Max latency so far: 109 microseconds.
Max latency so far: 145 microseconds.
Max latency so far: 205 microseconds.
Max latency so far: 283 microseconds.
Max latency so far: 363 microseconds.
Max latency so far: 2507 microseconds.
Max latency so far: 4541 microseconds.

100063828 total runs (avg latency: 0.0500 microseconds / 49.97 nanoseconds per run).
Worst run took 90878x longer than the average latency.
# redis-cli --intrinsic-latency 5
Max latency so far: 1 microseconds.
Max latency so far: 39 microseconds.
Max latency so far: 41 microseconds.
Max latency so far: 45 microseconds.
Max latency so far: 62 microseconds.
Max latency so far: 8839 microseconds.
Max latency so far: 9357 microseconds.
Max latency so far: 10310 microseconds.
Max latency so far: 10322 microseconds.
Max latency so far: 10573 microseconds.
Max latency so far: 10682 microseconds.
Max latency so far: 11177 microseconds.
Max latency so far: 11514 microseconds.

35539207 total runs (avg latency: 0.1407 microseconds / 140.69 nanoseconds per run).
Worst run took 81840x longer than the average latency.

注意:--intrinsic-latency只能在redis實例所在機器運行。

從上面的輸出可以看到內核的最大延遲達到了11514微秒(115毫秒左右),也從側面說明執行redis命令的最大延遲起碼在115毫秒之上。

Replica mode【副本模式】

 副本模式是一項高級功能,對 redis 開發人員調試操作非常有用,它可以監控到主節點在複製流中發送到其副本的內容,使用redis-cli --replica開啓監控。
redis-cli --replica
sending REPLCONF capa eof
sending REPLCONF rdb-filter-only
SYNC with master, discarding bytes of bulk transfer until EOF marker...
SYNC done after 211 bytes. Logging commands from master.
sending REPLCONF ACK 0
"ping"
"SELECT","0"
"set","a","b"
"hset","hash","name","jack"

可以看到主節點上執行了set,hset等指令,命令行實時輸出。

如果你正在開發一個跨機房同步的redis同步工具,當你的從節點未按預期收到指令時,就可以使用這一命令做一些調試和診斷,爲了方便理解,我放一張老東家自研的redis跨機房同步工具流程圖。

 

 

Performing an LRU simulation【模擬LRU訪問】

 redis 通常用作具有 LRU 逐出功能的緩存,鍵的數量和內存大小(通過maxmemory指定)將決定緩存的命中率,藉助工具可以模擬命中率最終得到正確的maxmemory參數。

該工具使用80/20法則來執行 GET 、SET操作 ,意味着 20% 的key將在 80% 的次數內被請求,這符合一般緩存場景中的請求分佈。

我們假設給redis分配的內存爲10兆,內存驅逐策略爲allkeys-lru,預期有100萬個key,期望命中率是90%,測試一下看是否符合預期:

# 設置最大內存10兆
config set maxmemory 10MB
#  lru-test
redis-cli --lru-test 1000000
119250 Gets/sec | Hits: 43654 (36.61%) | Misses: 75596 (63.39%)
125250 Gets/sec | Hits: 46002 (36.73%) | Misses: 79248 (63.27%)
127500 Gets/sec | Hits: 46860 (36.75%) | Misses: 80640 (63.25%)
122500 Gets/sec | Hits: 45228 (36.92%) | Misses: 77272 (63.08%)
126750 Gets/sec | Hits: 46623 (36.78%) | Misses: 80127 (63.22%)
125250 Gets/sec | Hits: 46150 (36.85%) | Misses: 79100 (63.15%)
120000 Gets/sec | Hits: 43962 (36.63%) | Misses: 76038 (63.37%)
121000 Gets/sec | Hits: 44630 (36.88%) | Misses: 76370 (63.12%)
123250 Gets/sec | Hits: 45616 (37.01%) | Misses: 77634 (62.99%)

命中率明顯不符合預期,36%離90%相差甚遠,我們將maxmemory擴大一倍接着測試

 
# 設置最大內存20兆
config set maxmemory 20MB
#  lru-test
redis-cli --lru-test 1000000
134500 Gets/sec | Hits: 65181 (48.46%) | Misses: 69319 (51.54%)
133500 Gets/sec | Hits: 86515 (64.81%) | Misses: 46985 (35.19%)
133000 Gets/sec | Hits: 98930 (74.38%) | Misses: 34070 (25.62%)
123500 Gets/sec | Hits: 95223 (77.10%) | Misses: 28277 (22.90%)
122000 Gets/sec | Hits: 94237 (77.24%) | Misses: 27763 (22.76%)
122250 Gets/sec | Hits: 94430 (77.24%) | Misses: 27820 (22.76%)
122500 Gets/sec | Hits: 94564 (77.20%) | Misses: 27936 (22.80%)
124000 Gets/sec | Hits: 95517 (77.03%) | Misses: 28483 (22.97%)
125000 Gets/sec | Hits: 96723 (77.38%) | Misses: 28277 (22.62%)
129000 Gets/sec | Hits: 99839 (77.39%) | Misses: 29161 (22.61%)

內存增加一倍以後命中率達到了77%左右,繼續調整maxmemory直到符合預期。

redis-cli --lru-test切記不要在生產環境使用,會給服務器帶來較大壓力;

推薦閱讀

https://redis.io/docs/manual/cli/

拋磚系列之redis監控命令(一)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章