一. 什么是大key遵湖?
通常指數(shù)據(jù)內(nèi)存使用量非常大的數(shù)據(jù),比如set里放了相當多的數(shù)據(jù)
ps:比如我們用set存儲了單個用戶的文章點贊數(shù)據(jù)粘昨,有個小伙伴天天無聊就在那給文章點贊疗认,點了幾百萬蜓氨,那set里就有了幾百萬數(shù)據(jù)只搁,這個可能就是一個大key
備注:大key操作通常可見于集群慢日志妖滔,同期會伴隨緩存調(diào)用的高延遲隧哮,甚至節(jié)點完全阻塞造成的不可用。
-
參考:根據(jù)測試結(jié)果座舍,value在超過
1KB后性能開始下降沮翔,超過10KB后性能下降明顯,出現(xiàn)拐點
曲秉。
二. 數(shù)據(jù)層面的解釋--避免大key操作
業(yè)務(wù)方應(yīng)盡量避免進行大key操作采蚀,如 hgetall 一次獲取非常大的hash數(shù)據(jù),用 hmset 一次設(shè)置非常多的value承二,用 lrange 一次取一個非常大的 list 或非常多的元素榆鼠,如果客戶端需要用到這些操作對應(yīng)的API,一次操作的返回結(jié)果大小必須是在合理可控的范圍內(nèi)亥鸠,防止導(dǎo)致節(jié)點通信超時妆够、網(wǎng)絡(luò)堵塞等嚴重后果。
三. 結(jié)構(gòu)層面的大key問題解釋
- 1.資源使用不均(該大key可能會使用該實例相當多的內(nèi)存负蚊,浪費相當大的Cpu神妹,)
- 2.帶寬使用極大(比如假如我們有個功能展示上面例子中點贊的所有文章,一下查出來全部盖桥,肯定會使用非常大的帶寬)
- 3.影響該實例其他key的操作(基于redis的單線程處理機制灾螃,大家都在排隊,前面的慢揩徊,自然影響其他數(shù)據(jù)的操作)
四. 大key如何發(fā)現(xiàn)腰鬼?
- bigkeys命令
bigkeys命令以遍歷的方式
分析Redis實例中的所有Key,并返回整體統(tǒng)計信息與每個數(shù)據(jù)類型中Top1的大Key
- redis-rdb-tools
使用redis-rdb-tools離線分析
工具來掃描RDB持久化文件塑荒,雖然實時性略
差熄赡,但是完全離線對性能無影響
。 - Redis 4.0 以后的版本:支持 了 memory 命令查看 key 的大小
預(yù)估值齿税,不太準確(采用的是多次抽樣分析彼硫,預(yù)估全部數(shù)據(jù)的量)
五. 如何解決大key問題?
- 1.數(shù)據(jù)結(jié)構(gòu)拆分凌箕,比如我們這里有個活動數(shù)據(jù)拧篮,活動有活動商品數(shù)據(jù),這倆就進行了拆分牵舱,并沒有放一起
- 2.數(shù)據(jù)分片串绩,比如后面加序號,進行多實例的拆分
六. 大key的刪除問題
6.1 Redis 4.0以前大key刪除
4.0 以前 string芜壁,list礁凡,set高氮,hash 不同數(shù)據(jù)類型的大 key,刪除方式有所不同顷牌。一般有兩種情況:del 命令刪除單個很大的 key 和 del 批量刪除 大 key剪芍。直接 del 命令粗暴的刪大 key 容易造成 redis 線程阻塞。4.0 以前要優(yōu)雅的刪除就是針對不同的類型 寫腳本窟蓝,拆分鏈表罪裹,hash 表,分批刪除疗锐。
6.2 Redis 4.0 以后優(yōu)雅的刪除大 key
-
主動刪除
UNLINK xxxkey
unlink 命令是 del 的異步版本坊谁,由 Lazyfree 機制實現(xiàn)。Lazyfree 機制的原理是在刪除的時候只進行邏輯刪除滑臊,把 key 釋放操作放在 bio (Background I/O)單獨的子線程
中惰性處理口芍,減少刪除大 key 對 redis 主線程的阻塞,有效地避免因刪除大key帶來的性能問題雇卷。unlink 即使在批量刪除 大 key 時鬓椭,也不會對阻塞造成阻塞。 -
被動刪除
被動刪除是指 Redis 自身的 key 清除策略关划,一個 大 key 過期或者被淘汰時小染,如何被清除,會不會導(dǎo)致阻塞贮折?4.0 以前自動清除是有可能阻塞主線程的裤翩。
4.0 以后的版本,被動刪除策略是可選的配置參數(shù)调榄,允許以 Lazyfree 的方式清除踊赠。但是參數(shù)默認是關(guān)閉的
,可配置如下參數(shù)開啟每庆。
lazyfree-lazy-expire on # 過期惰性刪除
lazyfree-lazy-eviction on # 超過最大內(nèi)存惰性刪除
lazyfree-lazy-server-del on # 服務(wù)端被動惰性刪除