存儲大key
如果查詢慢日志發(fā)現(xiàn)拨与,并不是復(fù)雜度較高的命令導(dǎo)致的,例如都是SET艾猜、DELETE操作出現(xiàn)在慢日志記錄中,那么你就要懷疑是否存在Redis寫入了大key的情況捻悯。
Redis在寫入數(shù)據(jù)時匆赃,需要為新的數(shù)據(jù)分配內(nèi)存,當(dāng)從Redis中刪除數(shù)據(jù)時今缚,它會釋放對應(yīng)的內(nèi)存空間算柳。
如果一個key寫入的數(shù)據(jù)非常大,Redis在分配內(nèi)存時也會比較耗時姓言。同樣的瞬项,當(dāng)刪除這個key的數(shù)據(jù)時,釋放內(nèi)存也會耗時比較久何荚。
你需要檢查你的業(yè)務(wù)代碼囱淋,是否存在寫入大key的情況,需要評估寫入數(shù)據(jù)量的大小餐塘,業(yè)務(wù)層應(yīng)該避免一個key存入過大的數(shù)據(jù)量妥衣。
那么有沒有什么辦法可以掃描現(xiàn)在Redis中是否存在大key的數(shù)據(jù)嗎?
Redis也提供了掃描大key的方法:
redis-cli -h $host -p $port --bigkeys -i 0.01
使用上面的命令就可以掃描出整個實例key大小的分布情況戒傻,它是以類型維度來展示的税手。
需要注意的是當(dāng)我們在線上實例進(jìn)行大key掃描時,Redis的QPS會突增需纳,為了降低掃描過程中對Redis的影響芦倒,我們需要控制掃描的頻率,使用-i參數(shù)控制即可不翩,它表示掃描過程中每次掃描的時間間隔兵扬,單位是秒麻裳。
使用這個命令的原理,其實就是Redis在內(nèi)部執(zhí)行scan命令周霉,遍歷所有key掂器,然后針對不同類型的key執(zhí)行strlen、llen俱箱、hlen国瓮、scard、zcard來獲取字符串的長度以及容器類型(list/dict/set/zset)的元素個數(shù)狞谱。
而對于容器類型的key乃摹,只能掃描出元素最多的key,但元素最多的key不一定占用內(nèi)存最多跟衅,這一點需要我們注意下孵睬。不過使用這個命令一般我們是可以對整個實例中key的分布情況有比較清晰的了解。
針對大key的問題伶跷,Redis官方在4.0版本推出了lazy-free的機(jī)制掰读,用于異步釋放大key的內(nèi)存,降低對Redis性能的影響叭莫。即使這樣蹈集,我們也不建議使用大key,大key在集群的遷移過程中雇初,也會影響到遷移的性能拢肆,這個后面在介紹集群相關(guān)的文章時,會再詳細(xì)介紹到靖诗。