Redis中什么是Big Key(大key)問題? 如何解決Big Key問題?

大key并不是指key的值很大,而是key對(duì)應(yīng)的value很大,下面這篇文章主要給大家介紹了Redis中什么是Big?Key(大key)問題?如何解決Big?Key問題的相關(guān)資料,需要的朋友可以參考下

文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

一、什么是Big Key?

通俗易懂的講,Big Key就是某個(gè)key對(duì)應(yīng)的value很大,占用的redis空間很大,本質(zhì)上是大value問題。key往往是程序可以自行設(shè)置的,value往往不受程序控制,因此可能導(dǎo)致value很大。文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

redis中這些Big Key對(duì)應(yīng)的value值很大,在序列化/反序列化過程中花費(fèi)的時(shí)間很大,因此當(dāng)我們操作Big Key時(shí),通常比較耗時(shí),這就可能導(dǎo)致redis發(fā)生阻塞,從而降低redis性能。文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

用幾個(gè)實(shí)際的例子對(duì)大Key的特征進(jìn)行描述:文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

● 一個(gè)String類型的Key,它的值為5MB(數(shù)據(jù)過大);文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

● 一個(gè)List類型的Key,它的列表數(shù)量為20000個(gè)(列表數(shù)量過多);文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

● 一個(gè)ZSet類型的Key,它的成員數(shù)量為10000個(gè)(成員數(shù)量過多);文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

● 一個(gè)Hash格式的Key,它的成員數(shù)量雖然只有1000個(gè)但這些成員的value總大小為100MB(成員體積過大);文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

在實(shí)際業(yè)務(wù)中,大Key的判定仍然需要根據(jù)Redis的實(shí)際使用場(chǎng)景、業(yè)務(wù)場(chǎng)景來進(jìn)行綜合判斷。通常都會(huì)以數(shù)據(jù)大小與成員數(shù)量來判定。文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

二、Big Key產(chǎn)生的場(chǎng)景?

1、redis數(shù)據(jù)結(jié)構(gòu)使用不恰當(dāng)文章源自四五設(shè)計(jì)網(wǎng)-http://www.wasochina.com/46050.html

將Redis用在并不適合其能力的場(chǎng)景,造成Key的value過大,如使用String類型的Key存放大體積二進(jìn)制文件型數(shù)據(jù)。

2、未及時(shí)清理垃圾數(shù)據(jù)

沒有對(duì)無效數(shù)據(jù)進(jìn)行定期清理,造成如HASH類型Key中的成員持續(xù)不斷的增加。即一直往value塞數(shù)據(jù),卻沒有刪除機(jī)制,value只會(huì)越來越大。

3、對(duì)業(yè)務(wù)預(yù)估不準(zhǔn)確

業(yè)務(wù)上線前規(guī)劃設(shè)計(jì)考慮不足沒有對(duì)Key中的成員進(jìn)行合理的拆分,造成個(gè)別Key中的成員數(shù)量過多。

4、明星、網(wǎng)紅的粉絲列表、某條熱點(diǎn)新聞的評(píng)論列表

假設(shè)我們使用List數(shù)據(jù)結(jié)構(gòu)保存某個(gè)明星/網(wǎng)紅的粉絲,或者保存熱點(diǎn)新聞的評(píng)論列表,因?yàn)榉劢z數(shù)量巨大,熱點(diǎn)新聞因?yàn)辄c(diǎn)擊率、評(píng)論數(shù)會(huì)很多,這樣List集合中存放的元素就會(huì)很多,可能導(dǎo)致value過大,進(jìn)而產(chǎn)生Big Key問題。

三、Big Key的危害?

1、阻塞請(qǐng)求

Big Key對(duì)應(yīng)的value較大,我們對(duì)其進(jìn)行讀寫的時(shí)候,需要耗費(fèi)較長(zhǎng)的時(shí)間,這樣就可能阻塞后續(xù)的請(qǐng)求處理。Redis的核心線程是單線程,單線程中請(qǐng)求任務(wù)的處理是串行的,前面的任務(wù)完不成,后面的任務(wù)就處理不了。

2、內(nèi)存增大

讀取Big Key耗費(fèi)的內(nèi)存比正常Key會(huì)有所增大,如果不斷變大,可能會(huì)引發(fā)OOM(內(nèi)存溢出),或達(dá)到redis的最大內(nèi)存maxmemory設(shè)置值引發(fā)寫阻塞或重要Key被逐出。

3、阻塞網(wǎng)絡(luò)

讀取單value較大時(shí)會(huì)占用服務(wù)器網(wǎng)卡較多帶寬,自身變慢的同時(shí)可能會(huì)影響該服務(wù)器上的其他Redis實(shí)例或者應(yīng)用。

4、影響主從同步、主從切換

刪除一個(gè)大Key造成主庫(kù)較長(zhǎng)時(shí)間的阻塞并引發(fā)同步中斷或主從切換。

四、如何識(shí)別Big Key?

1、使用redis自帶的命令識(shí)別

例如可以使用Redis官方客戶端redis-cli加上--bigkeys參數(shù),可以找到某個(gè)實(shí)例5種數(shù)據(jù)類型(String、hash、list、set、zset)的最大key。
優(yōu)點(diǎn)是可以在線掃描,不阻塞服務(wù);缺點(diǎn)是信息較少,內(nèi)容不夠精確。

2、使用debUG object key命令

根據(jù)傳入的對(duì)象(Key的名稱)來對(duì)Key進(jìn)行分析并返回大量數(shù)據(jù),其中serializedlength的值為該Key的序列化長(zhǎng)度,需要注意的是,Key的序列化長(zhǎng)度并不等同于它在內(nèi)存空間中的真實(shí)長(zhǎng)度,此外,debug object屬于調(diào)試命令,運(yùn)行代價(jià)較大,并且在其運(yùn)行時(shí),進(jìn)入Redis的其余請(qǐng)求將會(huì)被阻塞直到其執(zhí)行完畢。并且每次只能查找單個(gè)key的信息,官方不推薦使用。

3、redis-rdb-tools開源工具

這種方式是在redis實(shí)例上執(zhí)行bgsave,bgsave會(huì)觸發(fā)redis的快照備份,生成rdb持久化文件,然后對(duì)dump出來的rdb文件進(jìn)行分析,找到其中的大key。

優(yōu)點(diǎn)在于獲取的key信息詳細(xì)、可選參數(shù)多、支持定制化需求,結(jié)果信息可選擇json或csv格式,后續(xù)處理方便,其缺點(diǎn)是需要離線操作,獲取結(jié)果時(shí)間較長(zhǎng)。

五、如何解決Big Key問題?

要解決Big Key問題,無非就是減小key對(duì)應(yīng)的value值的大小,也就是對(duì)于String數(shù)據(jù)結(jié)構(gòu)的話,減少存儲(chǔ)的字符串的長(zhǎng)度;對(duì)于List、Hash、Set、ZSet數(shù)據(jù)結(jié)構(gòu)則是減少集合中元素的個(gè)數(shù)。

1、對(duì)大Key進(jìn)行拆分

將一個(gè)Big Key拆分為多個(gè)key-value這樣的小Key,并確保每個(gè)key的成員數(shù)量或者大小在合理范圍內(nèi),然后再進(jìn)行存儲(chǔ),通過get不同的key或者使用mget批量獲取。

2、對(duì)大Key進(jìn)行清理

對(duì)Redis中的大Key進(jìn)行清理,從Redis中刪除此類數(shù)據(jù)。Redis自4.0起提供了UNLINK命令,該命令能夠以非阻塞的方式緩慢逐步的清理傳入的Key,通過UNLINK,你可以安全的刪除大Key甚至特大Key。

3、監(jiān)控Redis的內(nèi)存、網(wǎng)絡(luò)帶寬、超時(shí)等指標(biāo)

通過監(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%等。

4、定期清理失效數(shù)據(jù)

如果某個(gè)Key有業(yè)務(wù)不斷以增量方式寫入大量的數(shù)據(jù),并且忽略了其時(shí)效性,這樣會(huì)導(dǎo)致大量的失效數(shù)據(jù)堆積。可以通過定時(shí)任務(wù)的方式,對(duì)失效數(shù)據(jù)進(jìn)行清理。

5、壓縮value

使用序列化、壓縮算法將key的大小控制在合理范圍內(nèi),但是需要注意序列化、反序列化都會(huì)帶來一定的消耗。如果壓縮后,value還是很大,那么可以進(jìn)一步對(duì)key進(jìn)行拆分。

補(bǔ)充知識(shí):key設(shè)計(jì)

(1)【建議】: 可讀性和可管理性

以業(yè)務(wù)名(或數(shù)據(jù)庫(kù)名)為前綴(防止key沖突),用冒號(hào)分隔,比如業(yè)務(wù)名:表名:id
o2o:order:1

(2)【建議】:簡(jiǎn)潔性

保證語(yǔ)義的前提下,控制key的長(zhǎng)度,當(dāng)key較多時(shí),內(nèi)存占用也不容忽視,例如:
user:{uid}:friends:messages:{mid} 簡(jiǎn)化為 u:{uid}m:{mid}

(3)【強(qiáng)制】:不要包含特殊字符

反例:包含空格、換行、單雙引號(hào)以及其他轉(zhuǎn)義字符

繼續(xù)閱讀
我的微信
微信掃一掃
weinxin
我的微信
惠生活福利社
微信掃一掃
weinxin
我的公眾號(hào)
 

發(fā)表評(píng)論

匿名網(wǎng)友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

拖動(dòng)滑塊以完成驗(yàn)證