一個 randomkey 命令致使的 Redis 事故

最近在公司對redis作一些二次開發時,發現一個randomkey命令可能致使整個redis實例長時間阻塞的問題,redis版本爲3.2.9,以此記錄。redis

問題

因爲咱們公司使用的是redis集羣版Codis,Codis內置的redis版本比較低,爲3.2.9版本。dom

咱們近期在作Codis雙機房時,須要對redis增長一些功能以此支持雙機房,在開發和測試中發現,執行randomkey命令有可能致使整個redis長時間阻塞的問題。測試

randomkey主要功能是在redis中隨機返回一個key出來,它隨機選取key的代碼以下。spa

一個 randomkey 命令致使的 Redis 事故

從上面代碼能夠看出來,若是當前是個slave,而且整個實例中存在大量已通過期的key(key已過時,但redis還將來得及刪除key),執行randomkey命令時,因爲找不到不過時的key,那麼這個邏輯就會陷入死循環,阻塞住整個實例,整個實例不可用。blog

若是當前是master,執行randomkey命令時,redis會一直隨機選擇key,直到找到一個不過時的key,同時會把已通過期的key從整個實例中刪除。開發

也就是說,在這種場景下,雖然不會長時間阻塞整個實例,但也會比執行一個普通的命令耗時要久。若是你在一個大量已過時的實例上執行randomkey命令,那可能會致使業務訪問redis變慢。rem

解決

咱們對比了官方最新版的redis,已經針對此問題進行了修復。it

一個 randomkey 命令致使的 Redis 事故

解決方案就是增長一個最大重試次數,若是整個實例都是過時key,那麼最多尋找maxtries次就返回,避免阻塞整個實例。ast

注意點

但要注意的是,若是達到了maxtries,那麼返回的key是已通過期的key,你雖然在randomkey中看到了這個key,但對這個key執行其餘命令時,仍是拿不到這個key的。class

這個方案只針對slave上執行這個命令進行了修復,也就是不會再讓redis陷入死循環。

但在master上執行這個命令仍是會發生上述的變慢問題,若是你在使用redis時,常常使用這個命令,同時實例中存在大量已通過期的key,那麼redis變慢頗有多是這個問題致使的。

相關文章
相關標籤/搜索