Redis之大key熱點(diǎn)key的問題及處理
大key(Large Key)通常指的是一個(gè)key對(duì)應(yīng)的value很大,例如一個(gè)string類型的value大小達(dá)到10KB,或者一個(gè)list、hash、set、zset等集合類型的元素?cái)?shù)量過多(比如超過10000個(gè))。
大key的危害包括:
- 網(wǎng)絡(luò)阻塞:讀取大key會(huì)消耗大量帶寬,可能導(dǎo)致網(wǎng)絡(luò)阻塞。
- 內(nèi)存占用高:導(dǎo)致內(nèi)存使用不均,可能引發(fā)內(nèi)存不足。
- 阻塞操作:對(duì)于Redis,刪除大key可能導(dǎo)致服務(wù)阻塞(因?yàn)镽edis是單線程)。
使用Redis自帶的命令:redis-cli --bigkeys、有一些開源工具可以分析RDB文件,例如redis-rdb-tools,通過分析RDB文件來找出大key。
- 拆分大key:對(duì)于string類型的大key,可以嘗試將value拆分成多個(gè)部分、對(duì)于集合類型,可以按照某種規(guī)則(例如哈希取模)將一個(gè)大集合拆分成多個(gè)小集合
- 刪除大key:刪除大key時(shí),要避免阻塞Redis。對(duì)于集合類型,可以使用漸進(jìn)式刪除
- 設(shè)置過期時(shí)間:對(duì)于有時(shí)效性的大key,可以設(shè)置過期時(shí)間,讓其自動(dòng)過期
熱點(diǎn)key(Hot Key)指的是被頻繁訪問的key。熱點(diǎn)key的危害包括:
- 流量集中:可能導(dǎo)致某個(gè)Redis實(shí)例的流量過大,成為瓶頸(尤其是在集群模式下)。
- 服務(wù)不可用:如果熱點(diǎn)key的訪問量超過Redis的處理能力,可能導(dǎo)致服務(wù)崩潰。
使用Redis自帶的命令:redis-cli --hotkeys
- 使用本地緩存
- 拆分熱點(diǎn)key:如果熱點(diǎn)key是一個(gè)集合,可以拆分成多個(gè)key,分散到不同的節(jié)點(diǎn)、對(duì)于只讀的熱點(diǎn)key,可以復(fù)制多份,比如key_1, key_2,后面追加隨機(jī)數(shù)。
- 使用讀寫分離:通過Redis的讀寫分離,將讀請(qǐng)求分散到多個(gè)從節(jié)點(diǎn),降低主節(jié)點(diǎn)的壓力
- 使用Redis集群:將熱點(diǎn)key分散到不同的Redis實(shí)例上,避免單個(gè)實(shí)例成為瓶頸。
一、big key
大Key通常都會(huì)以數(shù)據(jù)大小與成員數(shù)量來判定:
- 一個(gè)STRING類型的Key,它的值為5MB(數(shù)據(jù)過大)
- 一個(gè)LIST類型的Key,它的列表數(shù)量為20000個(gè)(列表數(shù)量過多)
- 一個(gè)ZSET類型的Key,它的成員數(shù)量為10000個(gè)(成員數(shù)量過多)
- 一個(gè)HASH格式的Key,它的成員數(shù)量雖然只有1000個(gè)但這些成員的value總大小為100MB(成員體積過大)
1、大key引發(fā)的問題
- 存儲(chǔ)引發(fā)OOM:Redis內(nèi)存不斷變大引發(fā)OOM
- 存儲(chǔ):分布不均衡:Redis Cluster中的某個(gè)node內(nèi)存遠(yuǎn)超其余node,無法將node上的內(nèi)存均衡化
- 查詢占帶寬:大Key上的讀請(qǐng)求使Redis占用服務(wù)器全部帶寬
- 刪除時(shí)阻塞:刪除一個(gè)大Key造成主庫較長(zhǎng)時(shí)間的阻塞?
2、找出大key
- 通過Redis官方客戶端redis-cli的big keys參數(shù)發(fā)現(xiàn)大Key
- Memory Usage:命令來幫助分析Key的內(nèi)存占用,相對(duì)debug object命令,它的執(zhí)行代價(jià)更低仍有阻塞風(fēng)險(xiǎn)。
- Redis對(duì)于不同的數(shù)據(jù)結(jié)構(gòu)提供了不同的命令來返回其長(zhǎng)度或成員數(shù)量,如下圖
- redis-rdb-tools工具以定制化方式找出大Key?

3、解決方案
- 存-對(duì)大Key進(jìn)行拆分:HASH Key拆分為多個(gè)HASH Key,確保每個(gè)Key的成員數(shù)量在合理范圍
- 刪-對(duì)大Key進(jìn)行清理:Redis自4.0起提供了unlink命令,該命令能夠以非阻塞的方式緩慢逐步的清理傳入的Key,通過UNLINK,你可以安全的刪除大Key甚至特大Key。
- 監(jiān)控Redis的內(nèi)存水位:通過[監(jiān)控系統(tǒng)],比如普羅米修斯,并設(shè)置合理的Redis內(nèi)存報(bào)警閾值來提醒我們此時(shí)可能有大Key正在產(chǎn)生,如:Redis內(nèi)存使用率超過70%,Redis內(nèi)存1小時(shí)內(nèi)增長(zhǎng)率超過20%等。
二、hotkey
熱Key則以其接收到的請(qǐng)求頻率,請(qǐng)求次數(shù)來判定,比如:Redis實(shí)例的每秒總訪問量為10000,而其中一個(gè)Key的每秒訪問量達(dá)到了7000
1、帶來的問題
- 查詢-占用CPU:熱Key占用大量的Redis CPU時(shí)間使其性能變差
- 查詢-節(jié)點(diǎn)請(qǐng)求不均衡:Redis Cluster中Node流量不均衡造成Redis Cluster的分布式優(yōu)勢(shì)無法被Client利用
2、找出HotKey
- 通過Redis官方客戶端redis-cli的hot keys參數(shù)發(fā)現(xiàn)熱Key
- 通過業(yè)務(wù)層定位熱Key
- 使用monitor命令:在緊急情況時(shí)找出熱Key,能夠打印真實(shí)的請(qǐng)求,缺點(diǎn)就是Redis的CPU、內(nèi)存、網(wǎng)絡(luò)資源均有一定的占用?
3、處理方式
- 存儲(chǔ)-多節(jié)點(diǎn)復(fù)制:在Redis Cluster結(jié)構(gòu)中對(duì)熱Key進(jìn)行復(fù)制,因?yàn)榉植嫉臅r(shí)候是通過Hash key來得到節(jié)點(diǎn),所以通過修改Key的值,來改變value的分布。
- 查詢-使用讀寫分離架構(gòu):在使用讀寫分離架構(gòu)時(shí)可以通過不斷的【增加從節(jié)點(diǎn)】來降低每個(gè)Redis實(shí)例中的讀請(qǐng)求壓力
三、Tair
大key
- 刪-使用阿里云的Tair(Redis企業(yè)版)服務(wù)避開失效數(shù)據(jù)的清理工作
hotkey
- 使用阿里云Tair的QueryCache特性,其實(shí)就是類似于二級(jí)緩存,把緩存放在redis proxy層。
?1、介紹
- Tair(Tair緩存框架)是阿里巴巴開發(fā)的分布式緩存系統(tǒng),它并不是直接基于Redis實(shí)現(xiàn)的。相反,Tair是一個(gè)獨(dú)立的分布式緩存解決方案,具有自己的架構(gòu)和特性。
- 雖然Tair和Redis都是分布式緩存系統(tǒng),但它們是由不同的團(tuán)隊(duì)開發(fā),采用了不同的設(shè)計(jì)和實(shí)現(xiàn)。Tair在設(shè)計(jì)上考慮了阿里巴巴業(yè)務(wù)的特點(diǎn)和需求,提供了一些針對(duì)大規(guī)模分布式環(huán)境的優(yōu)化和功能。
2、過期算法:
TairHash使用高效的【Active Expire】算法,實(shí)現(xiàn)了在對(duì)響應(yīng)時(shí)間幾乎無影響的前提下,高效完成對(duì)field過期判斷和刪除的功能。此類高級(jí)功能的合理使用能夠解放大量Redis的運(yùn)維、故障處理工作并降低業(yè)務(wù)的代碼復(fù)雜度,讓運(yùn)維將精力投入到其它更有價(jià)值的工作中,讓研發(fā)有更多的時(shí)間來寫更有價(jià)值的代碼。
3、QueryCache是阿里云Tair(Redis企業(yè)版)服務(wù)的企業(yè)級(jí)特性之一
Tair QueryCache原理
- 阿里云數(shù)據(jù)庫Redis會(huì)根據(jù)高效的排序和統(tǒng)計(jì)算法識(shí)別出實(shí)例中存在的熱點(diǎn)Key,開啟該功能后,Proxy點(diǎn)會(huì)根據(jù)設(shè)定的規(guī)則【緩存】熱點(diǎn)Key的請(qǐng)求和查詢結(jié)果(僅緩存熱點(diǎn)Key的查詢結(jié)果,無需緩存整個(gè)Key),當(dāng)在緩存有效時(shí)間內(nèi)收到相同的請(qǐng)求時(shí)【Proxy會(huì)直接返回結(jié)果至客戶端】,無需和后端的Redis分片執(zhí)行交互。
- 在提升讀取速度的同時(shí),降低了熱點(diǎn)Key對(duì)數(shù)據(jù)分片的性能影響,避免發(fā)生請(qǐng)求傾斜。
至此,來自客戶端的同樣的請(qǐng)求無需再與Proxy后端的Redis進(jìn)行交互而由Proxy直接返回?cái)?shù)據(jù),指向熱Key的請(qǐng)求由一個(gè)Redis節(jié)點(diǎn)承擔(dān)轉(zhuǎn)為多個(gè)Proxy共同承擔(dān),能夠大幅度降低Redis節(jié)點(diǎn)的熱Key壓力,同時(shí)Tair的QueryCache功能還提供了大量的命令來方便用戶查看、管理,如通過querycache keys命令查看所有被緩存熱Key,通過querycache listall獲取所有已緩存的所有命令等。
Tair QueryCache智能化的熱Key判定與緩存聯(lián)動(dòng)功同樣能夠降低運(yùn)維及研發(fā)的工作負(fù)擔(dān)。與傳統(tǒng)的Redis同步中間件相比,阿里云Redis全球分布式緩存具有高可靠性、高吞吐低延遲、同步正確性高等特點(diǎn)。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis實(shí)現(xiàn)延遲任務(wù)的三種方法詳解
延遲任務(wù)(Delayed Task)是指在未來的某個(gè)時(shí)間點(diǎn),執(zhí)行相應(yīng)的任務(wù),本文為大家整理了三種常見的實(shí)現(xiàn)方法,感興趣的小伙伴可以參考一下2025-04-04
基于Redis過期事件實(shí)現(xiàn)訂單超時(shí)取消
這篇文章主要介紹了基于Redis過期事件實(shí)現(xiàn)訂單超時(shí)取消,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
Redis 哨兵機(jī)制及配置實(shí)現(xiàn)
本文主要介紹了Redis 哨兵機(jī)制及配置實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
利用Redis統(tǒng)計(jì)網(wǎng)站在線活躍用戶的方法
Redis支持對(duì)String類型的value進(jìn)行基于二進(jìn)制位的置位操作。通過將一個(gè)用戶的id對(duì)應(yīng)value上的一位,通過對(duì)活躍用戶對(duì)應(yīng)的位進(jìn)行置位,就能夠用一個(gè)value記錄所有活躍用戶的信息。下面這篇文章主要介紹了利用Redis統(tǒng)計(jì)網(wǎng)站在線活躍用戶的方法,需要的朋友可以參考。2017-01-01
全網(wǎng)最完整的Redis新手入門指導(dǎo)教程
這篇文章主要給大家介紹了Redis新手入門的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
基于Redis實(shí)現(xiàn)短信驗(yàn)證碼登錄項(xiàng)目示例(附源碼)
手機(jī)登錄驗(yàn)證在很多網(wǎng)頁上都得到使用,本文主要介紹了基于Redis實(shí)現(xiàn)短信驗(yàn)證碼登錄項(xiàng)目示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

