這一章書(shū)本上的內(nèi)容有:
- 慢查詢分析:通過(guò)慢查詢分析,找到有問(wèn)題的命令進(jìn)行優(yōu)化。
- Redis Shell:功能強(qiáng)大的Redis Shell會(huì)有意想不到的實(shí)用功能。
- Pipeline:通過(guò)Pipeline(管道或者流水線)機(jī)制有效提高客戶端性能。
- 事務(wù)與Lua:制作自己的專屬原子命令。
- Bitmaps:通過(guò)在字符串?dāng)?shù)據(jù)結(jié)構(gòu)上使用位操作,有效節(jié)省內(nèi)存,為開(kāi)發(fā)提供新的思路。
- HyperLogLog:一種基于概率的新算法,難以想象地節(jié)省內(nèi)存空間。
- 發(fā)布訂閱:基于發(fā)布訂閱模式的消息通信機(jī)制。
- GEO:Redis3.2提供了基于地理位置信息的功能。
這里我只會(huì)記錄其中的慢查詢分析、Redis Shel、Pipeline和發(fā)布訂閱。
3.1 慢查詢分析
許多存儲(chǔ)系統(tǒng)(例如MySQL)提供慢查詢?nèi)罩編椭_(kāi)發(fā)和運(yùn)維人員定位系統(tǒng)存在的慢操作。所謂慢查詢?nèi)罩揪褪窍到y(tǒng)在命令執(zhí)行前后計(jì)算每條命令的執(zhí)行時(shí)間,當(dāng)超過(guò)預(yù)設(shè)閥值,就將這條命令的相關(guān)信息(例如:發(fā)生時(shí)間,耗時(shí),命令的詳細(xì)信息)記錄下來(lái),Redis也提供了類似的功能。
如圖3-1所示,Redis客戶端執(zhí)行一條命令分為如下4個(gè)部分:

一條客戶端命令的生命周期
需要注意,慢查詢只統(tǒng)計(jì)步驟3)的時(shí)間,所以沒(méi)有慢查詢并不代表客戶端沒(méi)有超時(shí)問(wèn)題。
3.1.1 慢查詢的兩個(gè)配置參數(shù)
對(duì)于慢查詢功能,需要明確兩件事:
- 預(yù)設(shè)閥值怎么設(shè)置?
- 慢查詢記錄存放在哪?
Redis提供了slowlog-log-slower-than和slowlog-max-len配置來(lái)解決這兩個(gè)問(wèn)題。從字面意思就可以看出,slowlog-log-slower-than就是那個(gè)預(yù)設(shè)閥值,它的單位是微秒(1秒=1000毫秒=1000000微秒),默認(rèn)值是10000,假如執(zhí)行了一條“很慢”的命令(例如keys*),如果它的執(zhí)行時(shí)間超過(guò)了10000微秒,那么它將被記錄在慢查詢?nèi)罩局小?br> 如果slowlog-log-slower-than=0會(huì)記錄所有的命令,slowlog-log-slowerthan<0對(duì)于任何命令都不會(huì)進(jìn)行記錄。
從字面意思看,slowlog-max-len只是說(shuō)明了慢查詢?nèi)罩咀疃啻鎯?chǔ)多少條,并沒(méi)有說(shuō)明存放在哪里?實(shí)際上Redis使用了一個(gè)列表來(lái)存儲(chǔ)慢查詢?nèi)罩?,slowlog-max-len就是列表的最大長(zhǎng)度。一個(gè)新的命令滿足慢查詢條件時(shí)被插入到這個(gè)列表中,當(dāng)慢查詢?nèi)罩玖斜硪烟幱谄渥畲箝L(zhǎng)度時(shí),最早插入的一個(gè)命令將從列表中移出,例如slowlog-max-len設(shè)置為5,當(dāng)有第6條慢查詢插入的話,那么隊(duì)頭的第一條數(shù)據(jù)就出列,第6條慢查詢就會(huì)入列。
在Redis中有兩種修改配置的方法,一種是修改配置文件,另一種是使用config set命令動(dòng)態(tài)修改。例如下面使用config set命令將slowlog-log-slowerthan設(shè)置為20000微秒,slowlog-max-len設(shè)置為1000:
config set slowlog-log-slower-than 20000
config set slowlog-max-len 1000
config rewrite
如果要Redis將配置持久化到本地配置文件,需要執(zhí)行config rewrite命令
雖然慢查詢?nèi)罩臼谴娣旁赗edis內(nèi)存列表中的,但是Redis并沒(méi)有暴露這個(gè)列表的鍵,而是通過(guò)一組命令來(lái)實(shí)現(xiàn)對(duì)慢查詢?nèi)罩镜脑L問(wèn)和管理。下面介紹這幾個(gè)命令。
- 獲取慢查詢?nèi)罩?/li>
slowlog get [n]
操作返回當(dāng)前Redis的慢查詢,參數(shù)n可以指定條數(shù).慢查詢?nèi)罩纠锩娴膮?shù)這里不做介紹。
- 獲取慢查詢?nèi)罩玖斜懋?dāng)前的長(zhǎng)度
slowlog len
- 慢查詢?nèi)罩局刂?/li>
slowlog reset
3.1.2 最佳實(shí)踐
慢查詢功能可以有效地幫助我們找到Redis可能存在的瓶頸,但在實(shí)際使用過(guò)程中要注意以下幾點(diǎn):
- max-len配置建議:線上建議調(diào)大慢查詢列表,記錄慢查詢時(shí)Redis會(huì)對(duì)長(zhǎng)命令做截?cái)嗖僮?,并不?huì)占用大量?jī)?nèi)存。增大慢查詢列表可以減緩慢查詢被剔除的可能,例如線上可設(shè)置為1000以上。
- slowlog-log-slower-than配置建議:默認(rèn)值超過(guò)10毫秒判定為慢查詢,需要根據(jù)Redis并發(fā)量調(diào)整該值。由于Redis采用單線程響應(yīng)命令,對(duì)于高流量的場(chǎng)景,如果命令執(zhí)行時(shí)間在1毫秒以上,那么Redis最多可支撐OPS不到1000。因此對(duì)于高OPS場(chǎng)景的Redis建議設(shè)置為1毫秒。
- 慢查詢只記錄命令執(zhí)行時(shí)間,并不包括命令排隊(duì)和網(wǎng)絡(luò)傳輸時(shí)間。因此客戶端執(zhí)行命令的時(shí)間會(huì)大于命令實(shí)際執(zhí)行時(shí)間。因?yàn)槊顖?zhí)行排隊(duì)機(jī)制,慢查詢會(huì)導(dǎo)致其他命令級(jí)聯(lián)阻塞,因此當(dāng)客戶端出現(xiàn)請(qǐng)求超時(shí),需要檢查該時(shí)間點(diǎn)是否有對(duì)應(yīng)的慢查詢,從而分析出是否為慢查詢導(dǎo)致的命令級(jí)聯(lián)阻塞。
- 由于慢查詢?nèi)罩臼且粋€(gè)先進(jìn)先出的隊(duì)列,也就是說(shuō)如果慢查詢比較多的情況下,可能會(huì)丟失部分慢查詢命令,為了防止這種情況發(fā)生,可以定期執(zhí)行slow get命令將慢查詢?nèi)罩境志没狡渌鎯?chǔ)中(例如MySQL),然后可以制作可視化界面進(jìn)行查詢.