2023-06-21:redis中什么是BigKey?該如何解決?
答案2023-06-21:
什么是bigkey
bigkey是指存儲在Key-Value數(shù)據(jù)庫中的鍵對應(yīng)的值所占用的內(nèi)存空間較大。舉個例子,如果值是字符串類型,它可以達到最大512MB的存儲空間;如果值是列表類型,最多可以存儲 2^32 - 1 個元素,即 4294967295 個元素。
根據(jù)數(shù)據(jù)結(jié)構(gòu)的不同,我們可以將bigkey進一步分為字符串類型的bigkey和非字符串類型的bigkey。
字符串類型的bigkey:這種bigkey指的是在Key-Value數(shù)據(jù)庫中,鍵對應(yīng)的字符串值所占用的內(nèi)存空間較大。一般來說,當(dāng)一個值超過10KB時,就可以被認為是字符串類型的bigkey。但需要注意的是,這個閾值可以根據(jù)具體的業(yè)務(wù)需求和系統(tǒng)的OPS(每秒操作次數(shù))進行調(diào)整,不同的環(huán)境可能會有不同的定義。
非字符串類型的bigkey:這種bigkey指的是鍵對應(yīng)的值是其他非字符串類型(例如哈希、列表、集合、有序集合等),而這些數(shù)據(jù)結(jié)構(gòu)中的元素數(shù)量多到足以被認為是bigkey。例如,當(dāng)一個哈希表、列表、集合或有序集合中的元素數(shù)量超過較大的閾值時,可以被視為非字符串類型的bigkey。
bigkey在Redis中具有不友好的空間復(fù)雜度和時間復(fù)雜度,以下是它的危害。
bigkey的危害
bigkey的危害體現(xiàn)在三個方面:
1、內(nèi)存空間不均勻(平衡):特別是在Redis Cluster中,bigkey可能導(dǎo)致節(jié)點的內(nèi)存空間使用不均勻。當(dāng)某個節(jié)點存儲了大量的bigkey時,該節(jié)點的內(nèi)存占用會增加,并且可能超出其他節(jié)點的內(nèi)存使用量。這樣就破壞了集群的負載均衡,導(dǎo)致一些節(jié)點承受了過多的負載,而其他節(jié)點卻相對空閑。
2、超時阻塞:由于Redis的單線程特性,操作bigkey可能會耗費較長的時間,這也意味著Redis被阻塞的可能性增大。
3、網(wǎng)絡(luò)擁塞:獲取bigkey時產(chǎn)生的網(wǎng)絡(luò)流量較大,可能引起網(wǎng)絡(luò)擁塞問題。
假設(shè)一個bigkey的大小為1MB,每秒訪問量為1000個請求,那么每秒產(chǎn)生的流量將達到1000MB。對于普通的千兆網(wǎng)卡(以字節(jié)計算約為128MB/s)的服務(wù)器來說,這將帶來巨大的網(wǎng)絡(luò)負載,甚至可能導(dǎo)致災(zāi)難性的影響。尤其是在采用單機多實例的方式部署服務(wù)器時,一個大型bigkey的影響最終會波及到其他實例上,后果不堪設(shè)想。
bigkey的存在并非完全致命:
如果一個bigkey存在但幾乎不被頻繁訪問,那么主要的問題可能是內(nèi)存空間的不均衡分布,相對于其他問題來說,這個問題的重要性和緊急性可能較低。然而,如果這個bigkey是一個熱點key(頻繁被訪問),那么它所帶來的危害就不容忽視。當(dāng)一個熱點bigkey的訪問量特別大時,它可能會對Redis服務(wù)器和其他實例產(chǎn)生嚴重的性能影響。
因此,在實際的開發(fā)和運維過程中,密切關(guān)注bigkey的存在是非常重要的。特別是對于熱點bigkey,需要采取相應(yīng)的策略來應(yīng)對,例如數(shù)據(jù)分片、緩存或其他優(yōu)化措施,以確保系統(tǒng)的高性能和穩(wěn)定運行。及時監(jiān)控和處理bigkey問題,有助于維護整體的系統(tǒng)性能和用戶體驗。
發(fā)現(xiàn)bigkey
使用命令redis-cli --bigkeys可以統(tǒng)計和查看bigkey的分布情況。
在生產(chǎn)環(huán)境中,開發(fā)和運維人員通常希望能夠自定義bigkey的大小,并且找到真正的bigkey,以便能夠定位、解決和優(yōu)化相關(guān)問題。
為了判斷一個key是否為bigkey,可以執(zhí)行DEBUG OBJECT key命令并查看serializedlength屬性,它表示key對應(yīng)的value序列化后的字節(jié)數(shù)。通過檢查這個屬性,我們可以確定一個key是否為bigkey。
當(dāng)需要遍歷多個key時,應(yīng)避免使用keys命令,而是采用SCAN命令來減輕Redis服務(wù)器的壓力。
scan
自Redis 2.8版本以后,引入了SCAN
命令來高效地解決KEYS
命令存在的問題。不同于KEYS
命令一次性遍歷所有鍵的方式,SCAN
采用漸進式遍歷的方式,以解決可能引起阻塞的問題。要完全實現(xiàn)KEYS
命令的功能,需要執(zhí)行多次SCAN
命令??梢詫⑵湎胂鬄橹鸩綊呙枳值渲械囊徊糠宙I,直到所有鍵都遍歷完成。
SCAN
命令使用方法如下:
SCAN cursor [MATCH pattern] [COUNT number]
-
cursor
是必需的參數(shù),實際上是一個游標(biāo)。第一次遍歷時,游標(biāo)值為0,每次執(zhí)行完SCAN
命令后,會返回當(dāng)前游標(biāo)的值,直到游標(biāo)值為0,表示遍歷已結(jié)束。 -
MATCH pattern
是可選參數(shù),用于指定鍵名的模式匹配,類似于KEYS
命令的模式匹配功能。 -
COUNT number
是可選參數(shù),用于指定每次要遍歷的鍵的數(shù)量,其默認值為10,如果需要可以適當(dāng)增大此參數(shù)。
可以觀察到,使用SCAN 0
命令的第一次執(zhí)行結(jié)果包含兩部分:
第一部分是下一次執(zhí)行SCAN
命令所需的游標(biāo)值(通常是一個整數(shù))。
第二部分是返回的10個鍵。
接下來可以繼續(xù)執(zhí)行SCAN
命令,并使用上一次返回的游標(biāo)值作為參數(shù),直到游標(biāo)值變?yōu)?,表示所有鍵都已經(jīng)遍歷完畢。
除了SCAN
命令,Redis還提供了針對哈希類型、集合類型和有序集合類型的掃描遍歷命令,分別是HSCAN
、SSCAN
和ZSCAN
。它們的作用是解決類似于HGETALL
、SMEMBERS
、ZRANGE
等可能導(dǎo)致阻塞的操作。這些命令的用法類似于SCAN
命令,請參考Redis官方文檔獲取更多信息。
漸進式遍歷確實可以有效解決KEYS命令可能產(chǎn)生的阻塞問題,但并非完美無瑕。在使用SCAN命令進行遍歷過程中,如果鍵空間有變化(增加、刪除、修改),可能會遇到以下問題:新增的鍵可能沒有被遍歷到,或者遍歷結(jié)果中可能包含重復(fù)的鍵。因此,在開發(fā)過程中需要考慮這些潛在的情況。
當(dāng)鍵值個數(shù)較多時,使用SCAN命令結(jié)合DEBUG OBJECT執(zhí)行速度可能較慢,此時可以考慮利用Redis的Pipeline機制來提高性能。對于元素個數(shù)較多的數(shù)據(jù)結(jié)構(gòu),DEBUG OBJECT命令執(zhí)行速度較慢,并且可能導(dǎo)致Redis阻塞。因此,如果存在從節(jié)點,可以考慮在從節(jié)點上執(zhí)行這些操作。
解決bigkey
解決大鍵(bigkey)的主要思路是拆分,將存儲在大鍵中的數(shù)據(jù)(大值)進行拆分,分成多個小的值(value1,value2…valueN)進行存儲。
例如,如果大值是一個大的JSON對象,可以通過使用MSET
命令將該鍵的內(nèi)容拆分存儲到各個實例中,或者使用哈希表(hash),其中每個字段代表一個具體屬性??梢允褂?code>HGET、HMGET
命令來獲取部分值,使用HSET
、HMSET
命令來更新部分屬性。
同樣地,如果大值是一個大的列表(list),可以將其拆分為多個小的列表(list_1,list_2,list_3…list_N)進行存儲。
對于其他數(shù)據(jù)類型也可以采用類似的拆分策略。文章來源:http://www.zghlxwxcb.cn/news/detail-496207.html
通過拆分大鍵,可以將大的值分割為小的部分,這樣可以更好地利用Redis的內(nèi)存和性能。這種拆分策略可以根據(jù)實際情況進行調(diào)整,以滿足存儲和訪問的需求。文章來源地址http://www.zghlxwxcb.cn/news/detail-496207.html
到了這里,關(guān)于2023-06-21:redis中什么是BigKey?該如何解決?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!