9個提升逼格的redis命令
keys
我把這個命令放在第一位,是因為筆者曾經做過的項目,以及一些朋友的項目,都因為使用這個命令,導致出現性能毛刺。這個命令的時間複雜度是O(N),而且redis又是單線程執行,在執行keys時即使是時間複雜度只有O(1)例如SET或者GET這種簡單命令也會堵塞,從而導致這個時間點性能抖動,甚至可能出現timeout。
強烈建議生產環境屏蔽keys命令(後面會介紹如何屏蔽)。
scan
既然keys命令不允許使用,那麼有什麼代替方案呢?有!那就是命令。如果把keys命令比作類似這種SQL,那麼scan應該是這種命令。
官方文檔用法如下:
初始執行scan命令例如。SCAN命令是一個基於游標的迭代器。這意味著命令每次被調用都需要使用上一次這個調用返回的游標作為該次調用的游標參數,以此來延續之前的迭代過程。當SCAN命令的游標參數被設置為0時,伺服器將開始一次新的迭代,而當redis伺服器向用戶返回值為0的游標時,表示迭代已結束,這是唯一迭代結束的判定方式,而不能通過返回結果集是否為空判斷迭代結束。
使用方式:
返回結果分為兩個部分:第一部分即1)就是下一次迭代游標,第二部分即2)就是本次迭代結果集。
slowlog
上面提到不能使用keys命令,如果就有開發這麼做了呢,我們如何得知?與其他任意存儲系統例如mysql,mongodb可以查看慢日誌一樣,redis也可以,即通過命令。用法如下:
subcommand主要有:
get,用法:slowlog get [argument],獲取argument參數指定數量的慢日誌。
len,用法:slowlog len,總慢日誌數量。
reset,用法:slowlog reset,清空慢日誌。
執行結果如下:
命令耗時超過多少才會保存到slowlog中,可以通過命令配置並且不需要重啟redis。注意:單位是微妙,2000微妙即2毫秒。
rename-command
為了防止把問題帶到生產環境,我們可以通過配置文件重命名一些危險命令,例如等一些高危命令。操作非常簡單,只需要在conf配置文件增加如下所示配置即可:
bigkeys
隨著項目越做越大,緩存使用越來越不規範。我們如何檢查生產環境上一些有問題的數據。就派上用場了,用法如下:
執行結果如下:
最後5行可知,沒有set,hash,zset幾種數據結構的數據。string類型有524個,list類型有兩個;通過可知,最大string結構的key是,最大list結構的key是。
需要注意的是,這個bigkeys得到的最大,不一定是最大。說明原因前,首先說明的原理,非常簡單,通過scan命令遍歷,各種不同數據結構的key,分別通過不同的命令得到最大的key:
如果是string結構,通過判斷;
如果是list結構,通過判斷;
如果是hash結構,通過判斷;
如果是set結構,通過判斷;
如果是sorted set結構,通過判斷。
正因為這樣的判斷方式,雖然string結構肯定可以正確的篩選出最佔用緩存,也可以說最大的key。但是list不一定,例如,現在有兩個list類型的key,分別是:numberlist--[0,1,2],stringlist--["123456789123456789"],由於通過llen判斷,所以numberlist要大於stringlist。而事實上stringlist更佔用內存。其他三種數據結構hash,set,sorted set都會存在這個問題。使用bigkeys一定要注意這一點。
monitor
假設生產環境沒有屏蔽keys等一些高危命令,並且slowlog中還不斷有新的keys導致慢日誌。那我們如何揪出這些命令是由誰執行的呢?這就是的用處,用法如下:
如果當前redis環境OPS比較高,那麼建議結合linux管道命令優化,只輸出keys命令的執行情況:
執行結果中很清楚的看到keys命名執行來源。通過輸出的IP和埠信息,就能在目標伺服器上找到執行這條命令的進程,揪出元兇,勒令整改。
info
如果說哪個命令能最全面反映當前redis運行情況,那麼非info莫屬。用法如下:
section可選值有:
Server:運行的redis實例一些信息,包括:redis版本,操作系統信息,埠,GCC版本,配置文件路徑等;
Clients:redis客戶端信息,包括:已連接客戶端數量,阻塞客戶端數量等;
Memory:使用內存,峰值內存,內存碎片率,內存分配方式。這幾個參數都非常重要;
Persistence:AOF和RDB持久化信息;
Stats:一些統計信息,最重要三個參數:OPS(),和兩個參數反應緩存命中率;
Replication:redis集群信息;
CPU:CPU相關信息;
Keyspace:redis中各個DB里key的信息;
config
config是一個非常有價值的命令,主要體現在對redis的運維。因為生產環境一般是不允許隨意重啟的,不能因為需要調優一些參數就修改conf配置文件並重啟。redis作者早就想到了這一點,通過config命令能熱修改一些配置,不需要重啟redis實例,可以通過如下命令查看哪些參數可以熱修改:
熱修改就比較容易了,執行如下命令即可:
例如:,
這樣修改的話,如果以後由於某些原因redis實例故障需要重啟,那通過config熱修改的參數就會被配置文件中的參數覆蓋,所以我們需要通過一個命令將config熱修改的參數刷到redis配置文件中持久化,通過執行如下命令即可:
執行該命令後,我們能在config文件中看到類似這種信息:
set
set命令也能提升逼格?是的,我本不打算寫這個命令,但是我見過太多人沒有完全掌握這個命令,官方文檔介紹的用法如下:
你可能用的比較多的就是,或者,所以很多同學用redis實現分散式鎖分為兩步:首先執行,然後執行。很明顯,這種實現有很嚴重的問題,因為兩步執行不具備原子性,如果執行第一個命令後出現某些未知異常導致無法執行,那麼分散式鎖就會一直無法得到釋放。
通過命令實現分散式鎖的正式姿勢應該是(EX和PX任選,取決於對過期時間精度要求)。另外,value也有要求,最好是一個類似UUID這種具備唯一性的字元串。當然如果問你redis是否還有其他實現分散式鎖的方案。你能說出redlock,那對方一定眼前一亮,心裡對你豎起大拇指,但嘴上不會說。
關於redis分散式鎖方案,強烈建議你閱讀redis官方文檔Redis分散式鎖:http://redis.cn/topics/distlock.html
TAG:阿飛Javaer |