一、背景
看redis監(jiān)控發(fā)現有個指標居高不下,晚上11點都維持著四五萬的hits
對redis哨兵而言,七八萬qps就是極限了,再高,就會引發(fā)redis性能的下降




需要注意的是,redis實例內存使用并不高,說明只是并發(fā)量而不是數據量問題

二、問題排查思路
有必要對其并發(fā)操作做一下分析:
- 這些 hits 都由哪些操作構成?
- 哪些是 熱key?
排查思路:
1、監(jiān)控里面會顯示各種命令的操作次數
2、可以確定命令類型后,就能知道是操作類型,然后再在增長點的時候直接開啟monitor去鏡像操作
3、高峰高達8w/s的話,然后確定不是很多key,而是部分熱key,可以修改淘汰策略,然后保證實例空間足夠,然后進行熱key遍歷



為什么要設置key生存時間?
在實際開發(fā)過程中,經常會遇到一些有實效性的數據,比如限時優(yōu)惠、緩存、驗證碼等等,過了一段時間后就應該刪除這些數據。如果用關系型數據庫,那么就需要在表中增加一個字段存儲實效時間,然后定時輪詢該字段并判斷刪除。而在redis中,可以使用expire命令給key設置有效時間來實現這個需求。
設置key的生存時間,可以用于以下使用場景:
1.在登錄網站后,將用戶session存儲在內存,設置一個過期時間,超過這個時間后,用戶必須重新登錄(例如aws控制臺的session過期時間為12個小時)。
- 使用redis隊列時,通常設置一個過期時間,這樣即使隊列的消費者應用出bug,隊列內的消息也不會積壓。
那這個問題就有突破口了:
hits高,從對 command calls 監(jiān)控看,絕大部分是 ttl 操作
什么業(yè)務會需要大量 ttl 操作 ?
這樣量的 ttl 是否合理?
如果不合理,要做業(yè)務改造;
如果合理,那么要搞清是哪些微服務工程行為,針對性做 redis拆分,用redis集群來這部分緩存
三 、找出 ttl 操作來源
redis 主節(jié)點: 192.168.1.102:6379
$ redis-cli -h 192.168.1.102 -p 6379 -a 'XXXX' client list > client_list.txt
$ grep -w ttl client_list.txt
$ grep -w ttl client_list.txt | awk '{printf "%-32s| %-16s| %-16s| %-16s| %-16s| %-16s| %s\n", $2,$5,$6,$7,$12,$16,$18}'
id=847281399 addr=10.22.193.111:59912 fd=1326 name= age=648560 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=ttl
id=854228598 addr=192.168.65.118:25991 fd=3898 name= age=247 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=ttl
id=854228609 addr=192.168.65.112:38738 fd=3930 name= age=247 idle=1 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ttl
id=854228610 addr=10.22.193.106:64575 fd=3942 name= age=247 idle=2 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ttl
id=854228613 addr=192.168.65.114:14066 fd=3948 name= age=247 idle=9 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ttl
id=847281353 addr=10.22.193.112:2629 fd=870 name= age=648561 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=ttl
id=847282211 addr=10.22.193.114:5990 fd=881 name= age=648484 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=ttl
id=854229751 addr=192.168.65.110:17349 fd=1543 name= age=136 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=ttl
id=851921182 addr=10.22.193.107:13161 fd=3056 name= age=215691 idle=1 flags=N db=5 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ttl
id=854228137 addr=192.168.65.116:16920 fd=3915 name= age=286 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=ttl
id=847281352 addr=10.22.193.121:2585 fd=1257 name= age=648562 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=ttl
根據 addr=ip:port socket信息,可以查到目標ip上哪個工程 監(jiān)聽該 port,連到 192.168.1.102:6379,發(fā)起ttl操作。
$ netstat -pantu | grep -w 2629
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.)
tcp6 0 0 10.21.193.112:2629 192.168.1.102:6380 ESTABLISHED 308616/java
tcp6 0 0 10.21.193.112:12197 172.18.36.120:2629 TIME_WAIT -
tcp6 0 0 10.21.193.112:10657 172.18.65.189:2629 TIME_WAIT -
$ ps aux | grep 308616
nobody 308616 7.3 2.3 11913984 1526956 ? Sl Jul14 799:22 /opt/jdk/bin/java -Dservicename=test -XX:+UseG1GC -Xmx1024m -Xms1024m
$ netstat -pantu | grep -w 3954
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.)
tcp6 0 92 172.18.65.130:3954 192.168.1.102:6379 ESTABLISHED 588857/java
tcp6 0 0 172.18.65.130:12869 172.18.65.106:3954 TIME_WAIT -
tcp6 0 0 172.18.65.130:12451 172.18.65.189:3954 TIME_WAIT -
$ ps aux | grep 588857
nobody 588857 18.5 2.4 11913980 1618388 ? Sl Jul14 2006:20 /opt/jdk/bin/java -Dservicename=test -XX:+UseG1GC -Xmx1024m -Xms1024m
從 選取幾個連接看,都是test工程發(fā)起的對 該redis實例 的 ttl操作。
四、 追蹤 ttl操作相關的key
redis-faina 是由Instagram 開發(fā)并開源的一個Redis 查詢分析小工具。
redis-faina通過解析redis的MONITOR命令的輸出,從而對redis實例進行性能診斷的工具。
該工具使用雖然簡單,但是功能還是很不錯,對于定位線上redis性能問題,確實是一把利器。
方法1. 通過管道從stdin讀取redis monitor 輸出,解析
# yum install git
# git clone https://github.com/facebookarchive/redis-faina.git
# cd redis-faina
# redis-cli -h xx.xx.xx.xx -p 6379 -a 'XXX' monitor | head -n 10000 | ./redis-faina.py
方法2. 將redis monitor 輸出重定向到文件,然后讀取解析
# yum install git
# git clone https://github.com/facebookarchive/redis-faina.git
# cd redis-faina
# redis-cli -h xx.xx.xx.xx -p 6379 -a 'XXX' monitor > m.log
//另開窗口,查詢輸出日志行數,到達自己目標行,就中斷掉
# wc -l m.log
# ./redis-faina.py m.log
五、參考
用prometheus+grafana+redis_exporter監(jiān)控redis
http://www.itdecent.cn/p/08f5f436cb87
REDIS CLIENT LIST
http://doc.redisfans.com/server/client_list.html
https://www.w3schools.cn/redis/server_client_list.asp
https://blog.csdn.net/chenqiushi123/article/details/116498382
https://geek-docs.com/redis-cmd/redis-client-server-cmd/redis-cmd-client-list.html
Redis MONITOR 命令
https://www.knowledgedict.com/tutorial/redis-command-monitor.html
Redis性能監(jiān)控及優(yōu)化
https://developer.aliyun.com/article/711140
Redis監(jiān)控方法 Redis監(jiān)控技巧
http://www.redisfans.com/?p=55
Redis監(jiān)視器(MONITOR命令、replicationFeedMonitors函數)
https://blog.csdn.net/m0_46405589/article/details/109689056
redis monitor
https://redis.io/commands/monitor/
redis-key的生存時間
https://www.it610.com/article/1296836575182790656.htm
redis生存時間TTL
https://blog.csdn.net/pyufftj/article/details/106954841