9個提升逼格的redis命令

keys

我把這個命令放在第一位淘捡,是因為筆者曾經(jīng)做過的項目藕各,以及一些朋友的項目,都因為使用keys這個命令焦除,導致出現(xiàn)性能毛刺激况。這個命令的時間復雜度是O(N),而且redis又是單線程執(zhí)行膘魄,在執(zhí)行keys時即使是時間復雜度只有O(1)例如SET或者GET這種簡單命令也會堵塞乌逐,從而導致這個時間點性能抖動,甚至可能出現(xiàn)timeout创葡。

強烈建議生產(chǎn)環(huán)境屏蔽keys命令(后面會介紹如何屏蔽)浙踢。

scan

既然keys命令不允許使用,那么有什么代替方案呢灿渴?有洛波!那就是scan命令。如果把keys命令比作類似select * from users where username like '%afei%'這種SQL骚露,那么scan應該是select * from users where id>? limit 10這種命令蹬挤。

官方文檔用法如下:

SCAN cursor [MATCH pattern] [COUNT count]

初始執(zhí)行scan命令例如scan 0。SCAN命令是一個基于游標的迭代器棘幸。這意味著命令每次被調用都需要使用上一次這個調用返回的游標作為該次調用的游標參數(shù)焰扳,以此來延續(xù)之前的迭代過程。當SCAN命令的游標參數(shù)被設置為0時误续,服務器將開始一次新的迭代吨悍,而當redis服務器向用戶返回值為0的游標時,表示迭代已結束蹋嵌,這是唯一迭代結束的判定方式育瓜,而不能通過返回結果集是否為空判斷迭代結束。

使用方式:

127.0.0.1:6380> scan 0
1) "22"
2)  1) "23"
    2) "20"
    3) "14"
    4) "2"
    5) "19"
    6) "9"
    7) "3"
    8) "21"
    9) "12"
   10) "25"
   11) "7"

返回結果分為兩個部分:第一部分即1)就是下一次迭代游標欣尼,第二部分即2)就是本次迭代結果集爆雹。

slowlog

上面提到不能使用keys命令停蕉,如果就有開發(fā)這么做了呢,我們如何得知钙态?與其他任意存儲系統(tǒng)例如mysql慧起,mongodb可以查看慢日志一樣,redis也可以册倒,即通過命令slowlog蚓挤。用法如下:

SLOWLOG subcommand [argument]

subcommand主要有:

  • get,用法:slowlog get [argument]驻子,獲取argument參數(shù)指定數(shù)量的慢日志灿意。
  • len,用法:slowlog len崇呵,總慢日志數(shù)量缤剧。
  • reset,用法:slowlog reset域慷,清空慢日志荒辕。

執(zhí)行結果如下:

127.0.0.1:6380> slowlog get 5
1) 1) (integer) 2
   2) (integer) 1532656201
   3) (integer) 2033
   4) 1) "flushddbb"
2) 1) (integer) 1  ----  慢日志編碼,一般不用care
   2) (integer) 1532646897  ----  導致慢日志的命令執(zhí)行的時間點犹褒,如果api有timeout抵窒,可以通過對比這個時間,判斷可能是慢日志命令執(zhí)行導致的
   3) (integer) 26424  ----  導致慢日志執(zhí)行的redis命令叠骑,通過4)可知李皇,執(zhí)行config rewrite導致慢日志,總耗時26ms+
   4) 1) "config"
      2) "rewrite"

命令耗時超過多少才會保存到slowlog中宙枷,可以通過命令config set slowlog-log-slower-than 2000配置并且不需要重啟redis掉房。注意:單位是微妙,2000微妙即2毫秒朦拖。

rename-command

為了防止把問題帶到生產(chǎn)環(huán)境圃阳,我們可以通過配置文件重命名一些危險命令厌衔,例如keys等一些高危命令璧帝。操作非常簡單,只需要在conf配置文件增加如下所示配置即可:

rename-command flushdb flushddbb
rename-command flushall flushallall
rename-command keys keysys

bigkeys

隨著項目越做越大富寿,緩存使用越來越不規(guī)范睬隶。我們如何檢查生產(chǎn)環(huán)境上一些有問題的數(shù)據(jù)。bigkeys就派上用場了页徐,用法如下:

redis-cli -p 6380 --bigkeys

執(zhí)行結果如下:

... ...
-------- summary -------

Sampled 526 keys in the keyspace!
Total key length in bytes is 1524 (avg len 2.90)

Biggest string found 'test' has 10005 bytes
Biggest   list found 'commentlist' has 13 items

524 strings with 15181 bytes (99.62% of keys, avg size 28.97)
2 lists with 19 items (00.38% of keys, avg size 9.50)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)

最后5行可知苏潜,沒有set,hash,zset幾種數(shù)據(jù)結構的數(shù)據(jù)。string類型有524個变勇,list類型有兩個恤左;通過Biggest ... ...可知贴唇,最大string結構的key是test,最大list結構的key是commentlist飞袋。

需要注意的是戳气,這個bigkeys得到的最大,不一定是最大巧鸭。說明原因前瓶您,首先說明bigkeys的原理,非常簡單纲仍,通過scan命令遍歷呀袱,各種不同數(shù)據(jù)結構的key,分別通過不同的命令得到最大的key:

  • 如果是string結構郑叠,通過strlen判斷夜赵;
  • 如果是list結構,通過llen判斷乡革;
  • 如果是hash結構油吭,通過hlen判斷;
  • 如果是set結構署拟,通過scard判斷婉宰;
  • 如果是sorted set結構,通過zcard判斷推穷。

正因為這樣的判斷方式心包,雖然string結構肯定可以正確的篩選出最占用緩存,也可以說最大的key馒铃。但是list不一定蟹腾,例如,現(xiàn)在有兩個list類型的key区宇,分別是:numberlist--[0,1,2]娃殖,stringlist--["123456789123456789"],由于通過llen判斷议谷,所以numberlist要大于stringlist炉爆。而事實上stringlist更占用內存。其他三種數(shù)據(jù)結構hash卧晓,set芬首,sorted set都會存在這個問題。使用bigkeys一定要注意這一點逼裆。

monitor

假設生產(chǎn)環(huán)境沒有屏蔽keys等一些高危命令郁稍,并且slowlog中還不斷有新的keys導致慢日志。那我們如何揪出這些命令是由誰執(zhí)行的呢胜宇?這就是monitor的用處耀怜,用法如下:

redis-cli -p 6380 monitor

如果當前redis環(huán)境OPS比較高恢着,那么建議結合linux管道命令優(yōu)化,只輸出keys命令的執(zhí)行情況:

[afei@redis ~]# redis-cli -p 6380 monitor | grep keys 
1532645266.656525 [0 10.0.0.1:43544] "keyss" "*"
1532645287.257657 [0 10.0.0.1:43544] "keyss" "44*"

執(zhí)行結果中很清楚的看到keys命名執(zhí)行來源财破。通過輸出的IP和端口信息然评,就能在目標服務器上找到執(zhí)行這條命令的進程,揪出元兇狈究,勒令整改碗淌。

info

如果說哪個命令能最全面反映當前redis運行情況,那么非info莫屬抖锥。用法如下:

INFO [section]

section可選值有:

  • Server:運行的redis實例一些信息亿眠,包括:redis版本,操作系統(tǒng)信息磅废,端口纳像,GCC版本,配置文件路徑等拯勉;
  • Clients:redis客戶端信息竟趾,包括:已連接客戶端數(shù)量,阻塞客戶端數(shù)量等宫峦;
  • Memory:使用內存岔帽,峰值內存,內存碎片率导绷,內存分配方式犀勒。這幾個參數(shù)都非常重要;
  • Persistence:AOF和RDB持久化信息妥曲;
  • Stats:一些統(tǒng)計信息贾费,最重要三個參數(shù):OPS(instantaneous_ops_per_sec),keyspace_hitskeyspace_misses兩個參數(shù)反應緩存命中率檐盟;
  • Replication:redis集群信息褂萧;
  • CPU:CPU相關信息;
  • Keyspace:redis中各個DB里key的信息葵萎;

config

config是一個非常有價值的命令导犹,主要體現(xiàn)在對redis的運維。因為生產(chǎn)環(huán)境一般是不允許隨意重啟的陌宿,不能因為需要調優(yōu)一些參數(shù)就修改conf配置文件并重啟锡足。redis作者早就想到了這一點,通過config命令能熱修改一些配置壳坪,不需要重啟redis實例,可以通過如下命令查看哪些參數(shù)可以熱修改:

config get *

熱修改就比較容易了掰烟,執(zhí)行如下命令即可:

config set 

例如:config set slowlog-max-len 100爽蝴,config set maxclients 1024

這樣修改的話沐批,如果以后由于某些原因redis實例故障需要重啟,那通過config熱修改的參數(shù)就會被配置文件中的參數(shù)覆蓋蝎亚,所以我們需要通過一個命令將config熱修改的參數(shù)刷到redis配置文件中持久化九孩,通過執(zhí)行如下命令即可:

config rewrite

執(zhí)行該命令后,我們能在config文件中看到類似這種信息:

# 如果conf中本來就有這個參數(shù)发框,通過執(zhí)行config set躺彬,那么redis直接原地修改配置文件
maxclients 1024
# 如果conf中沒有這個參數(shù),通過執(zhí)行config set梅惯,那么redis會追加在Generated by CONFIG REWRITE字樣后面
# Generated by CONFIG REWRITE
save 600 60
slowlog-max-len 100

set

set命令也能提升逼格宪拥?是的,我本不打算寫這個命令铣减,但是我見過太多人沒有完全掌握這個命令她君,官方文檔介紹的用法如下:

SET key value [EX seconds] [PX milliseconds] [NX|XX]

你可能用的比較多的就是set key value,或者SETEX key seconds value葫哗,所以很多同學用redis實現(xiàn)分布式鎖分為兩步:首先執(zhí)行SETNX key value缔刹,然后執(zhí)行EXPIRE key seconds。很明顯劣针,這種實現(xiàn)有很嚴重的問題校镐,因為兩步執(zhí)行不具備原子性,如果執(zhí)行第一個命令后出現(xiàn)某些未知異常導致無法執(zhí)行EXPIRE key seconds捺典,那么分布式鎖就會一直無法得到釋放灭翔。

通過SET命令實現(xiàn)分布式鎖的正式姿勢應該是SET key value EX seconds NX(EX和PX任選,取決于對過期時間精度要求)辣苏。另外肝箱,value也有要求,最好是一個類似UUID這種具備唯一性的字符串稀蟋。當然如果問你redis是否還有其他實現(xiàn)分布式鎖的方案煌张。你能說出redlock,那對方一定眼前一亮退客,心里對你豎起大拇指骏融,但嘴上不會說。

關于redis分布式鎖方案萌狂,強烈建議你閱讀redis官方文檔Redis分布式鎖:http://redis.cn/topics/distlock.html

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末档玻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子茫藏,更是在濱河造成了極大的恐慌误趴,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件务傲,死亡現(xiàn)場離奇詭異凉当,居然都是意外死亡枣申,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門看杭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忠藤,“玉大人,你說我怎么就攤上這事楼雹∧:ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵贮缅,是天一觀的道長榨咐。 經(jīng)常有香客問我,道長携悯,這世上最難降的妖魔是什么祭芦? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮憔鬼,結果婚禮上龟劲,老公的妹妹穿的比我還像新娘。我一直安慰自己轴或,他們只是感情好昌跌,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布宝剖。 她就那樣靜靜地躺著咸作,像睡著了一般孕暇。 火紅的嫁衣襯著肌膚如雪谒亦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天亭姥,我揣著相機與錄音瘦麸,去河邊找鬼狞换。 笑死污呼,一個胖子當著我的面吹牛裕坊,可吹牛的內容都是我干的。 我是一名探鬼主播燕酷,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼籍凝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了苗缩?” 一聲冷哼從身側響起饵蒂,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酱讶,沒想到半個月后退盯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年得问,在試婚紗的時候發(fā)現(xiàn)自己被綠了囤攀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片软免。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡宫纬,死狀恐怖,靈堂內的尸體忽然破棺而出膏萧,到底是詐尸還是另有隱情漓骚,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布榛泛,位于F島的核電站蝌蹂,受9級特大地震影響,放射性物質發(fā)生泄漏曹锨。R本人自食惡果不足惜孤个,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沛简。 院中可真熱鬧齐鲤,春花似錦、人聲如沸椒楣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捧灰。三九已至淆九,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毛俏,已是汗流浹背炭庙。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留煌寇,地道東北人焕蹄。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像唧席,于是被迫代替她去往敵國和親擦盾。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容