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

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

