自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Redis 的 BigKey、HotKey 又引發(fā)了線上事故!

數(shù)據(jù)庫(kù) Redis
當(dāng)一個(gè)較大的key存在時(shí),持續(xù)新增,key所占內(nèi)存會(huì)越來(lái)越大,嚴(yán)重時(shí)會(huì)導(dǎo)致內(nèi)存數(shù)據(jù)溢出;當(dāng)key過期需要?jiǎng)h除時(shí),由于數(shù)據(jù)量過大,可能發(fā)生主庫(kù)較響應(yīng)時(shí)間過長(zhǎng),主從數(shù)據(jù)同步異常(刪除掉的數(shù)據(jù),從庫(kù)還在使用)。


問題的嚴(yán)重性

首先,要申明一下,問題的嚴(yán)重性。

BigKey(大key)和HotKey(熱key)的問題是較常見。

這類問題不止會(huì)使服務(wù)的性能下降,還會(huì)影響用戶正常使用功能,

甚至?xí)斐纱蠓秶姆?wù)故障,故障有時(shí)還會(huì)發(fā)生連環(huán)效應(yīng),導(dǎo)致更加嚴(yán)重的后果,發(fā)生系統(tǒng)的雪崩,造成巨大的經(jīng)濟(jì)損失,巨大的品牌損傷。

所以,在 Redis 運(yùn)維過程中,由于 Bigkey 的存在,DBA 也一直和業(yè)務(wù)開發(fā)方強(qiáng)調(diào) Bigkey 的規(guī)避方法以及危害。

在開發(fā)的過程中,開發(fā)同學(xué),也需要十分重視和預(yù)防這個(gè)問題。

一、什么是BigKey、HotKey?

什么是BigKey

俗稱“大key”,是指redis在日常生產(chǎn)的過程中,某些key所占內(nèi)存空間過大。

通俗來(lái)說,redis是key-value的存儲(chǔ)方式,當(dāng)一個(gè)key所對(duì)應(yīng)的存儲(chǔ)數(shù)值達(dá)到一定程度,就會(huì)出現(xiàn)大key的情況。

redis里有多種數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),如String、List、Hash等,每種存儲(chǔ)結(jié)構(gòu)都有能夠承載的數(shù)據(jù)限值。當(dāng)一個(gè)key包含的內(nèi)容接近限制,或者高于平均值,大key就產(chǎn)生了。關(guān)注公眾號(hào):碼猿技術(shù)專欄,回復(fù)關(guān)鍵詞:1111 獲取阿里內(nèi)部Java性能調(diào)優(yōu)手冊(cè)

在 Redis 中,一個(gè)字符串類型最大可以到 512MB,一個(gè)二級(jí)數(shù)據(jù)結(jié)構(gòu)(比如 hash、list、set、zset 等)可以存儲(chǔ)大約 40 億個(gè)(2^32-1)個(gè)元素,

但實(shí)際上不會(huì)達(dá)到這么大的值,一般情況下如果達(dá)到下面的情況,就可以認(rèn)為它是 Bigkey 了。

  • 【字符串類型】:?jiǎn)蝹€(gè) string 類型的 value 值超過 1MB,就可以認(rèn)為是 Bigkey。
  • 【非字符串類型】:哈希、列表、集合、有序集合等, 它們的元素個(gè)數(shù)超過 2000 個(gè),就可以認(rèn)為是 Bigkey。

什么是HotKey

俗稱“熱key”,一個(gè)key對(duì)應(yīng)在一個(gè)redis分片上,當(dāng)短時(shí)間內(nèi)大量的請(qǐng)求打到該分片上,key被頻繁訪問,該key就是熱key。

當(dāng)大量的請(qǐng)求,經(jīng)過分發(fā)和計(jì)算,最終集中于同一個(gè)redis實(shí)例下的某個(gè)key時(shí),該key由于被請(qǐng)求頻率過高,而占用掉了大量資源。

而其他分片,由于key的不合理分配導(dǎo)致請(qǐng)求量較少。

整個(gè)redis集群呈現(xiàn)出了資源使用不均衡的現(xiàn)象。

舉個(gè)例子:一線女明星官宣領(lǐng)證結(jié)婚,短時(shí)間內(nèi)該女星微博賬號(hào)被訪問量激增(假設(shè)該賬號(hào)內(nèi)容被同步在緩存,賬號(hào)id作為key),微博服務(wù)癱瘓(不具備任何實(shí)時(shí)參考性,僅作為虛擬的例子)。

在該場(chǎng)景下,上述key被大量訪問,造成熱key。

總之,在某個(gè)Key接收到的訪問次數(shù)、顯著高于其它Key時(shí),我們可以將其稱之為HotKey,

從訪問量上來(lái)說,常見的HotKey如:

  • 某Redis實(shí)例的每秒總訪問量為10000,而其中一個(gè)Key的每秒訪問量達(dá)到了7000(訪問次數(shù)顯著高于其它Key)
  • 對(duì)一個(gè)擁有上千個(gè)成員且總大小為1MB的HASH Key每秒發(fā)送大量的HGETALL(帶寬占用顯著高于其它Key)
  • 對(duì)一個(gè)擁有數(shù)萬(wàn)個(gè)成員的ZSET Key每秒發(fā)送大量的ZRANGE(CPU時(shí)間占用顯著高于其它Key)

二、服務(wù)中的bigkey和hotkey

會(huì)導(dǎo)致什么問題

我們可以通過上述兩種key的特性,來(lái)簡(jiǎn)單分析可能出現(xiàn)的幾種問題。

第1:bigkey的問題

主要的問題是一個(gè)key所占空間太大,內(nèi)存空間分配不均衡(小tips:redis是內(nèi)存型key-value數(shù)據(jù)庫(kù))。那就可能引發(fā)以下問題:

1.數(shù)據(jù)請(qǐng)求大量超時(shí):

redis是單線程的,當(dāng)一個(gè)key數(shù)據(jù)響應(yīng)的久一點(diǎn),就會(huì)造成后續(xù)請(qǐng)求頻繁超時(shí)。如果服務(wù)容災(zāi)措施考慮得不夠,會(huì)引發(fā)更大的問題。

2.侵占帶寬網(wǎng)絡(luò)擁堵:

當(dāng)一個(gè)key所占空間過大,多次請(qǐng)求就會(huì)占用較大的帶寬,直接影響服務(wù)的正常運(yùn)行。

3.內(nèi)存溢出或處理阻塞:

當(dāng)一個(gè)較大的key存在時(shí),持續(xù)新增,key所占內(nèi)存會(huì)越來(lái)越大,嚴(yán)重時(shí)會(huì)導(dǎo)致內(nèi)存數(shù)據(jù)溢出;當(dāng)key過期需要?jiǎng)h除時(shí),由于數(shù)據(jù)量過大,可能發(fā)生主庫(kù)較響應(yīng)時(shí)間過長(zhǎng),主從數(shù)據(jù)同步異常(刪除掉的數(shù)據(jù),從庫(kù)還在使用)。

第2:hotkey的問題

熱key,熱key的問題是單點(diǎn)訪問頻率過高。那就可能引發(fā)以下問題:

1.分片服務(wù)癱瘓:

redis集群會(huì)分很多個(gè)分片,每個(gè)分片有其要處理的數(shù)據(jù)范圍。當(dāng)某一個(gè)分片被頻繁請(qǐng)求,該分片服務(wù)就可能會(huì)癱瘓。

2.Redis 分布式集群優(yōu)勢(shì)弱化:

如果請(qǐng)求不夠均衡,過于單點(diǎn),那么redis分布式集群的優(yōu)勢(shì)也必然被弱化。

3.可能造成資損:

在極端場(chǎng)景下,容易發(fā)生邊界數(shù)據(jù)處理不及時(shí),在訂單等場(chǎng)景下,可能造成資損。

4.引發(fā)緩存擊穿:

我們都知道,當(dāng)緩存請(qǐng)求不到,就會(huì)去請(qǐng)求數(shù)據(jù)庫(kù)。如果請(qǐng)求過于集中,redis承載不了,就會(huì)有大量請(qǐng)求打到數(shù)據(jù)庫(kù)。此時(shí),可能引發(fā)數(shù)據(jù)庫(kù)服務(wù)癱瘓。進(jìn)而引發(fā)系統(tǒng)雪崩。

5.cpu占用高,影響其他服務(wù):

單個(gè)分片cpu占用率過高,其他分片無(wú)法擁有cpu資源,從而被影響。

三、如何發(fā)現(xiàn)bigkey和hotkey

1.業(yè)務(wù)分析結(jié)合技術(shù)方案:

通常需要對(duì)業(yè)務(wù)場(chǎng)景做分析,結(jié)合技術(shù)方案去判斷是否會(huì)出現(xiàn)大key、熱key的問題。

比如說:

(1)購(gòu)物車場(chǎng)景,當(dāng)一個(gè)購(gòu)物車的key設(shè)計(jì),沒有上限,沒有其他隨機(jī)值約束,僅使用了mid。這個(gè)時(shí)候就要注意,如果有個(gè)購(gòu)物狂,一次加購(gòu)5w件商品怎么辦?

(2)活動(dòng)資格列表場(chǎng)景,當(dāng)一個(gè)活動(dòng)的資格查詢list被放入一個(gè)key,活動(dòng)期間頻繁的查詢和操作。這個(gè)時(shí)候就要注意,list的數(shù)據(jù)量有多少?查詢資格的操作是否集中?如果集中,qps是多少?

2.借助redis命令來(lái)發(fā)現(xiàn):

Redis4.0 及以上版本提供了--Bigkeys, --hotkeys 命令,可以分析出實(shí)例中每種數(shù)據(jù)結(jié)構(gòu)的 top 1 的 Bigkey,同時(shí)給出了每種數(shù)據(jù)類型的鍵值個(gè)數(shù)以及平均大小。

查看bigkey:redis-cli -a 登錄密碼 --bigkeys

查看hotkey:redis-cli -a 登錄密碼 --hotkeys

--bigkey 的使用示例

圖片

3.借助工具:

(1)可使用redis可視化工具進(jìn)行查看(例如:another redis desktop manager)

圖片

可視化的工具可以明確給出redis集群當(dāng)下的信息,經(jīng)過簡(jiǎn)要數(shù)據(jù)分析,便可觀測(cè)異常。

(2)借助市面上的開源工具(本文暫不對(duì)此深入探討)

redis-rdb-tools(附:https://github.com/sripathikrishnan/redis-rdb-tools)

(3)借助公司的自研工具

如果 vivo內(nèi)部的 DaaS(數(shù)據(jù)即服務(wù))平臺(tái)。

4.RDB 文件分析法

通過 RDB 文件,分析 big key

四、如何解決bigkey和hotkey問題

解決方案

bigkey的解決方案

主要的方法:對(duì) big key 進(jìn)行拆分

對(duì) big key 存儲(chǔ)的數(shù)據(jù) (big value)進(jìn)行拆分,變成value1,value2… valueN,

如果big value 是個(gè)大json 通過 mset 的方式,將這個(gè) key 的內(nèi)容打散到各個(gè)實(shí)例中,減小big key 對(duì)數(shù)據(jù)量?jī)A斜造成的影響。關(guān)注公眾號(hào):碼猿技術(shù)專欄,回復(fù)關(guān)鍵詞:1111 獲取阿里內(nèi)部Java性能調(diào)優(yōu)手冊(cè)

如果big value 是個(gè)大list,可以拆成將list拆成。= list_1, list_2, list3, listN

其他數(shù)據(jù)類型同理

hotkey的解決方案

主要的方法:使用本地緩存

在 client 端使用本地緩存,從而降低了redis集群對(duì)hot key的訪問量,

但是本地緩存 ,帶來(lái)兩個(gè)問題:1、如果對(duì)可能成為 hot key 的 key 都進(jìn)行本地緩存,那么本地緩存是否會(huì)過大,從而影響應(yīng)用程序本身所需的緩存開銷。

2、如何保證本地緩存和redis集群數(shù)據(jù)的有效期的一致性。

以上兩個(gè)問題,具體看:聊聊 Redis+Caffeine 兩級(jí)緩存

五、生產(chǎn)實(shí)例:

以下是vivo團(tuán)隊(duì)Bigkey問題的解決方案

此生產(chǎn)實(shí)例,非常寶貴,是珍貴的一線工業(yè)級(jí)實(shí)操案例,來(lái)源于 vivo 互聯(lián)網(wǎng)數(shù)據(jù)庫(kù)團(tuán)隊(duì)- Du Ting

陳某僅僅是將其結(jié)構(gòu),做進(jìn)一步的梳理,方便大家學(xué)習(xí)。

vivo 團(tuán)隊(duì)運(yùn)維的Redis集群的介紹

全網(wǎng) Redis 集群有 2200 個(gè)以上,實(shí)例數(shù)量達(dá)到 4.5 萬(wàn)以上,

進(jìn)行一次全網(wǎng) Bigkey 檢查,估計(jì)需要以年為時(shí)間單位,非常耗時(shí)。

Bigkey的來(lái)源

Bigkey 一般都是由于程序設(shè)計(jì)不當(dāng)、或者對(duì)于數(shù)據(jù)規(guī)模 預(yù)估 失策,比如以下的情況。

  • 【統(tǒng)計(jì)】場(chǎng)景遇到一個(gè)統(tǒng)計(jì)類 key 記錄訪問用戶的 IP,隨著網(wǎng)站訪問的用戶越來(lái)越多,這個(gè) key 的元素會(huì)越來(lái)越大,形成 Bigkey。
  • 【緩存】場(chǎng)景CacheAside 模式,業(yè)務(wù)程序 將數(shù)據(jù)從數(shù)據(jù)庫(kù)查詢出來(lái)序列化放到 Redis 里,就會(huì)查詢數(shù)據(jù)庫(kù)并將查詢到的數(shù)據(jù)追加到 Redis 緩存中,短時(shí)間內(nèi)會(huì)緩存大量的數(shù)據(jù)到 Redis 的 key 中,形成 Bigkey。
  • 【隊(duì)列】場(chǎng)景把 Redis 當(dāng)做隊(duì)列使用場(chǎng)景,如果消費(fèi)不及時(shí),將導(dǎo)致隊(duì)列越來(lái)越大,出現(xiàn) Bigkey。

問題1:內(nèi)存空間不均勻

內(nèi)存空間不均勻會(huì)不利于集群對(duì)內(nèi)存的統(tǒng)一管理,有數(shù)據(jù)丟失風(fēng)險(xiǎn)。

下圖中的三個(gè)節(jié)點(diǎn)是同屬于一個(gè)集群,它們的 key 的數(shù)量比較接近,但內(nèi)存容量相差比較多,存在 Bigkey 的實(shí)例占用的內(nèi)存多了 4G 以上了。

圖片

可以使用 Daas 平臺(tái)“工具集-操作項(xiàng)管理”,選擇對(duì)應(yīng)的 slave 實(shí)例執(zhí)行分析,找出具體的 Bigkey。

問題2:超時(shí)阻塞

Redis 是單線程工作的,通俗點(diǎn)講就是同一時(shí)間只能處理一個(gè) Redis 的訪問命令,

操作 Bigkey 的命令通常比較耗時(shí),這段時(shí)間 Redis 不能處理其他命令,其他命令只能阻塞等待,這樣會(huì)造成客戶端阻塞,導(dǎo)致客戶端訪問超時(shí),更嚴(yán)重的會(huì)造成 master-slave 的故障切換。

當(dāng)然,造成阻塞的操作不僅僅是業(yè)務(wù)程序的訪問,還有 key 的自動(dòng)過期的刪除、del 刪除命令,對(duì)于 Bigkey,這些操作也需要謹(jǐn)慎使用。

來(lái)一個(gè)生產(chǎn)上的超時(shí)阻塞案例

我們遇到一個(gè)這樣超時(shí)阻塞的案例,業(yè)務(wù)方反映:程序訪問 Redis 集群出現(xiàn)超時(shí)現(xiàn)象,hkeys 訪問 Redis 的平均響應(yīng)時(shí)間在 200 毫秒左右,最大響應(yīng)時(shí)間達(dá)到了 500 毫秒以上,如下圖。

圖片

hkeys 是獲取所有哈希表中的字段的命令,分析應(yīng)該是集群中某些實(shí)例存在 hash 類型的 Bigkey,導(dǎo)致 hkeys 命令執(zhí)行時(shí)間過長(zhǎng),發(fā)生了阻塞現(xiàn)象。

1.使用 Daas 平臺(tái)“服務(wù)監(jiān)控-數(shù)據(jù)庫(kù)實(shí)例監(jiān)控”,選擇 master 節(jié)點(diǎn),選擇 Redis 響應(yīng)時(shí)間監(jiān)控指標(biāo)“redis.instance.latency.max”,如下圖所示,從監(jiān)控圖中我們可以看到

(1)正常情況下,該實(shí)例的響應(yīng)時(shí)間在 0.1 毫秒左右。

(2)監(jiān)控指標(biāo)上面有很多突刺,該實(shí)例的響應(yīng)時(shí)間到了 70 毫秒左右,最大到了 100 毫秒左右,這種情況就是該實(shí)例會(huì)有 100 毫秒都在處理 Bigkey 的訪問命令,不能處理其他命令。

通過查看監(jiān)控指標(biāo),驗(yàn)證了我們分析是正確的,是這些監(jiān)控指標(biāo)的突刺造成了 hkeys 命令的響應(yīng)時(shí)間比較大,我們找到了具體的 master 實(shí)例,然后使用 master 實(shí)例的 slave 去分析下 Bigkey 情況。

圖片

圖片

2.使用 Daas 平臺(tái)“工具集-操作項(xiàng)管理”,選擇 slave 實(shí)例執(zhí)行分析,分析結(jié)果如下圖,有一個(gè) hash 類型 key 有 12102218 個(gè) fields。

圖片

  1. 和業(yè)務(wù)溝通,進(jìn)行Bigkey 拆分這個(gè) Bigkey 是連續(xù)存放了 30 天的業(yè)務(wù)數(shù)據(jù)了,建議根據(jù)二次 hash 方式拆分成多個(gè) key,也可把 30 天的數(shù)據(jù)根據(jù)分鐘級(jí)別拆分成多個(gè) key,把每個(gè) key 的元素?cái)?shù)量控制在 5000 以內(nèi)。優(yōu)化后,監(jiān)控指標(biāo)的響應(yīng)時(shí)間的突刺就會(huì)消失了。

問題3:網(wǎng)絡(luò)阻塞

Bigkey 的 value 比較大,也意味著每次獲取要產(chǎn)生的網(wǎng)絡(luò)流量較大,假設(shè)一個(gè) Bigkey 為 10MB,客戶端每秒訪問量為 100,那么每秒產(chǎn)生 1000MB 的流量,對(duì)于普通的千兆網(wǎng)卡(按照字節(jié)算是 128MB/s)的服務(wù)器來(lái)說簡(jiǎn)直是滅頂之災(zāi)。

而且我們現(xiàn)在的 Redis 服務(wù)器是采用單機(jī)多實(shí)例的方式來(lái)部署 Redis 實(shí)例的,也就是說一個(gè) Bigkey 可能會(huì)對(duì)同一個(gè)服務(wù)器上的其他 Redis 集群實(shí)例造成影響,影響到其他的業(yè)務(wù)。

問題4:遷移困難

我們?cè)谶\(yùn)維中經(jīng)常做的變更操作是水平擴(kuò)容,就是增加 Redis 集群的節(jié)點(diǎn)數(shù)量來(lái)達(dá)到擴(kuò)容的目的,這個(gè)水平擴(kuò)容操作就會(huì)涉及到 key 的遷移,把原實(shí)例上的 key 遷移到新擴(kuò)容的實(shí)例上。

當(dāng)要對(duì) key 進(jìn)行遷移時(shí),是通過 migrate 命令來(lái)完成的,migrate 實(shí)際上是通過 dump + restore + del 三個(gè)命令組合成原子命令完成,它在執(zhí)行的時(shí)候會(huì)阻塞進(jìn)行遷移的兩個(gè)實(shí)例,直到以下任意結(jié)果發(fā)生才會(huì)釋放:遷移成功,遷移失敗,等待超時(shí)。

如果 key 的遷移過程中遇到 Bigkey,會(huì)長(zhǎng)時(shí)間阻塞進(jìn)行遷移的兩個(gè)實(shí)例,可能造成客戶端阻塞,導(dǎo)致客戶端訪問超時(shí);也可能遷移時(shí)間太長(zhǎng),造成遷移超時(shí)導(dǎo)致遷移失敗,水平擴(kuò)容失敗。

來(lái)一個(gè)生產(chǎn)上的遷移失敗案例

我們也遇到過一些因?yàn)?Bigkey 擴(kuò)容遷移失敗的案例,如下圖所示,

這是一個(gè) Redis 集群水平擴(kuò)容的工單,需要進(jìn)行 key 的遷移,當(dāng)工單執(zhí)行到 60%的時(shí)候,遷移失敗了。

如何解決呢?

大概的解決流程,如下:

  1. 進(jìn)入工單找到失敗的實(shí)例,使用失敗實(shí)例的 slave 節(jié)點(diǎn),在 Daas 平臺(tái)的“工具集-操作項(xiàng)管理”進(jìn)行 Bigkey 分析。

圖片

  1. 經(jīng)過分析找出了 hash 類型的 Bigkey 有 8421874 個(gè) fields,正是這個(gè) Bigkey 導(dǎo)致遷移時(shí)間太長(zhǎng),超過了遷移時(shí)間限制,導(dǎo)致工單失敗了。

圖片

3.和業(yè)務(wù)溝通,這些 key 是記錄用戶訪問系統(tǒng)的某個(gè)功能模塊的 ip 地址的,訪問該功能模塊的所有 ip 都會(huì)記錄到給 key 里面,隨著時(shí)間的積累,這個(gè) key 變的越來(lái)越大。同樣是采用拆分的方式進(jìn)行優(yōu)化,可以考慮按照時(shí)間日期維度來(lái)拆分,就是一段時(shí)間段的訪問 ip 記錄到一個(gè) key 中。

4.Bigkey 優(yōu)化后,擴(kuò)容的工單可以重試,完成集群擴(kuò)容操作。

生產(chǎn)上如何進(jìn)行Bigkey 的發(fā)現(xiàn)

  • 首先需要重源頭治理,防止 Bigkey 的產(chǎn)生;
  • 其次是需要能夠及時(shí)的發(fā)現(xiàn),發(fā)現(xiàn)后及時(shí)處理。

分析 Bigkey 的方法不少,這里介紹兩種比較常用的方法,也是 Daas 平臺(tái)分析 Bigkey 使用的兩種方式,分別是 Bigkeys 命令分析法、RDB 文件分析法。

1.Bigkeys 命令分析

Redis4.0 及以上版本提供了--Bigkeys 命令,可以分析出實(shí)例中每種數(shù)據(jù)結(jié)構(gòu)的 top 1 的 Bigkey,同時(shí)給出了每種數(shù)據(jù)類型的鍵值個(gè)數(shù)以及平均大小。

執(zhí)行--Bigkeys 命令時(shí)候需要注意以下幾點(diǎn):

  • 建議在 slave 節(jié)點(diǎn)執(zhí)行,因?yàn)?-Bigkeys 也是通過 scan 完成的,可能會(huì)對(duì)節(jié)點(diǎn)造成阻塞。
  • 建議在節(jié)點(diǎn)本機(jī)執(zhí)行,這樣可以減少網(wǎng)絡(luò)開銷。
  • 如果沒有從節(jié)點(diǎn),可以使用--i 參數(shù),例如(--i 0.1 代表 100 毫秒執(zhí)行一次)。
  • --Bigkeys 只能計(jì)算每種數(shù)據(jù)結(jié)構(gòu)的 top1,如果有些數(shù)據(jù)結(jié)構(gòu)有比較多的 Bigkey,是查找不出來(lái)的。

Daas 平臺(tái)集成了基于原生--Bigkeys 代碼實(shí)現(xiàn)的查詢 Bigkey 的方式,這個(gè)方式的缺點(diǎn)是只能計(jì)算每種數(shù)據(jù)結(jié)構(gòu)的 top1,如果有些數(shù)據(jù)結(jié)構(gòu)有比較多的 Bigkey,是查找不出來(lái)的。該方式相對(duì)比較安全,已經(jīng)開放出來(lái)給業(yè)務(wù)開發(fā)同學(xué)使用。

2. RDB 文件分析

借助開源的工具,比如 rdb-tools,分析 Redis 實(shí)例的 RDB 文件,找出其中的 Bigkey,這種方式需要生成 RDB 文件,需要注意以下幾點(diǎn):

  • 建議在 slave 節(jié)點(diǎn)執(zhí)行,因?yàn)樯?RDB 文件會(huì)影響節(jié)點(diǎn)性能。
  • 需要生成 RDB 文件,會(huì)影響節(jié)點(diǎn)性能,雖然在 slave 節(jié)點(diǎn)執(zhí)行,但是也是有可能造成主從中斷,進(jìn)而影響到 master 節(jié)點(diǎn)。

Daas 平臺(tái)集成了基于 RDB 文件分析代碼實(shí)現(xiàn)的查詢 Bigkey 的方式,可以根據(jù)實(shí)際需求自定義填寫 N,分析的 top N 個(gè) Bigkey。該方式相對(duì)有一定風(fēng)險(xiǎn),只有 DBA 有權(quán)限執(zhí)行分析。

3.Bigkey 巡檢

通過巡檢,可以暴露出隱患,提前解決,避免故障的發(fā)生,進(jìn)行全網(wǎng) Bigkey 的巡檢,是避免 Bigkey 故障的比較好的方法。

由于全網(wǎng) Redis 實(shí)例數(shù)量非常大,分析的速度比較慢,使用當(dāng)前的分析方法很難完成。

為了解決這個(gè)問題,存儲(chǔ)研發(fā)組分布式數(shù)據(jù)庫(kù)同學(xué)計(jì)劃開發(fā)一個(gè)高效的 RDB 解析工具,然后通過大規(guī)模解析 RDB 文件來(lái)分析 Bigkey,可以提高分析速度,實(shí)現(xiàn) Bigkey 的巡檢。

生產(chǎn)上 Bigkey 處理優(yōu)化

1. Bigkey 拆分

優(yōu)化 Bigkey 的原則就是 string 減少字符串長(zhǎng)度,list、hash、set、zset 等減少元素?cái)?shù)量。當(dāng)我們知道哪些 key 是 Bigkey 時(shí),可以把單個(gè) key 拆分成多個(gè) key,比如以下拆分方式可以參考。

  • big list:list1、list2、...listN
  • big hash:可以做二次的 hash,例如 hash%100
  • 按照日期拆分多個(gè):key20220310、key20220311、key202203212

2. Bigkey 分析工具優(yōu)化

我們?nèi)W(wǎng) Redis 集群有 2200 以上,實(shí)例數(shù)量達(dá)到 4.5 萬(wàn)以上,有的比較大的集群的實(shí)例數(shù)量達(dá)到了 1000 以上,前面提到的兩種 Bigkey 分析工具還都是實(shí)例維度分析,對(duì)于實(shí)例數(shù)量比較大的集群,進(jìn)行全集群分析也是比較耗時(shí)的,為了提高分析效率,從以下幾個(gè)方面進(jìn)行優(yōu)化:

  • 可以從集群維度選擇全部 slave 進(jìn)行分析。
  • 同一個(gè)集群的相同服務(wù)器 slave 實(shí)例串行分析,不同服務(wù)器的 slave 實(shí)例并行分析,最大并發(fā)度默認(rèn) 10,同時(shí)可以分析 10 個(gè)實(shí)例,并且可以自定義輸入執(zhí)行分析的并發(fā)度。
  • 分析出符合 Bigkey 規(guī)定標(biāo)準(zhǔn)的所有 key 信息:大于 1MB 的 string 類型的所有 key,如果不存在就列出最大的 50 個(gè) key;hash、list、set、zset 等類型元素個(gè)數(shù)大于 2000 的所有 key,如不存在就給出每種類型最大的 50 個(gè) key。
  • 增加暫停、重新開始、結(jié)束功能,暫停分析后可以重新開始。

水平擴(kuò)容遷移優(yōu)化

目前情況,我們有一些 Bigkey 的發(fā)現(xiàn)是被動(dòng)的,一些是在水平擴(kuò)容時(shí)候發(fā)現(xiàn)的,由于 Bigkey 的存在導(dǎo)致擴(kuò)容失敗了,嚴(yán)重的還觸發(fā)了 master-slave 的故障切換,這個(gè)時(shí)候可能已經(jīng)造成業(yè)務(wù)程序訪問超時(shí),導(dǎo)致了可用性下降。

我們分析了 Daas 平臺(tái)的水平擴(kuò)容時(shí)遷移 key 的過程及影響參數(shù),內(nèi)容如下:

(1)【cluster-node-timeout】:控制集群的節(jié)點(diǎn)切換參數(shù),

master 堵塞超過 cluster-node-timeout/2 這個(gè)時(shí)間,就會(huì)主觀判定該節(jié)點(diǎn)下線 pfail 狀態(tài),如果遷移 Bigkey 阻塞時(shí)間超過 cluster-node-timeout/2,就可能會(huì)導(dǎo)致 master-slave 發(fā)生切換。

(2)【migrate timeout】:控制遷移 io 的超時(shí)時(shí)間

超過這個(gè)時(shí)間遷移沒有完成,遷移就會(huì)中斷。

(3)【遷移重試周期】:遷移的重試周期是由水平擴(kuò)容的節(jié)點(diǎn)數(shù)決定的,

比如一個(gè)集群擴(kuò)容 10 個(gè)節(jié)點(diǎn),遷移失敗后的重試周期就是 10 次。

(4)【一個(gè)遷移重試周期內(nèi)的重試次數(shù)】:在一個(gè)起遷移重試周期內(nèi),會(huì)有 3 次重試遷移,

每一次的 migrate timeout 的時(shí)間分別是 10 秒、20 秒、30 秒,每次重試之間無(wú)間隔。

比如一個(gè)集群擴(kuò)容 10 個(gè)節(jié)點(diǎn),遷移時(shí)候遇到一個(gè) Bigkey,第一次遷移的 migrate timeout 是 10 秒,10 秒后沒有完成遷移,就會(huì)設(shè)置 migrate timeout 為 20 秒重試,如果再次失敗,會(huì)設(shè)置 migrate timeout 為 30 秒重試,

如果還是失敗,程序會(huì)遷移其他新 9 個(gè)的節(jié)點(diǎn),但是每次在遷移其他新的節(jié)點(diǎn)之前還會(huì)分別設(shè)置 migrate timeout 為 10 秒、20 秒、30 秒重試遷移那個(gè)遷移失敗的 Bigkey。

這個(gè)重試過程,每個(gè)重試周期阻塞(10+20+30)秒,會(huì)重試 10 個(gè)周期,共阻塞 600 秒。其實(shí)后面的 9 個(gè)重試周期都是無(wú)用的,每次重試之間沒有間隔,會(huì)連續(xù)阻塞了 Redis 實(shí)例。

(5)【遷移失敗日志】:日志的缺失

遷移失敗后,記錄的日志沒有包括遷移節(jié)點(diǎn)、solt、key 信息,不能根據(jù)日志立即定位到問題 key。

我們對(duì)這個(gè)遷移過程做了優(yōu)化,具體如下:

(1)【cluster-node-timeout】:延長(zhǎng)超時(shí)時(shí)間

默認(rèn)是 60 秒,在遷移之前設(shè)置為 15 分鐘,防止由于遷移 Bigkey 阻塞導(dǎo)致 master-slave 故障切換。

(2)【migrate timeout】:減少阻塞時(shí)間

為了最大限度減少實(shí)例阻塞時(shí)間,每次重試的超時(shí)時(shí)間都是 10 秒,3 次重試之間間隔 30 秒,這樣最多只會(huì)連續(xù)阻塞 Redis 實(shí)例 10 秒。

(3)【重試次數(shù)】:去掉了其他節(jié)點(diǎn)遷移的重試

遷移失敗后,只重試 3 次(重試是為了避免網(wǎng)絡(luò)抖動(dòng)等原因造成的遷移失?。?,每次重試間隔 30 秒,重試 3 次后都失敗了,會(huì)暫停遷移,日志記錄下 Bigkey,去掉了其他節(jié)點(diǎn)遷移的重試。

(4)【優(yōu)化日志記錄】:日志記錄

遷移失敗日志記錄遷移節(jié)點(diǎn)、solt、key 信息,可以立即定位到問題節(jié)點(diǎn)及 key。

關(guān)于BigKey、Hotkey的總結(jié)

首先是需要從源頭治理,防止 Bigkey 、Hotkey形成,加強(qiáng)對(duì)業(yè)務(wù)開發(fā)同學(xué) bigkey 相關(guān)問題的宣導(dǎo);

其次,提升及時(shí)發(fā)現(xiàn)的能力,實(shí)現(xiàn) Bigkey 、Hotkey 及時(shí)探測(cè)能力。

參考資料:

Github:rdb-tools:https://github.com/sripathikrishnan/redis-rdb-tools

(1) redis命令:Redis 命令參考 — Redis 命令參考

(2) Github: https://github.com/sripathikrishnan/redis-rdb-tools

(3) another redis desktop manager下載地址AnotherRedisDesktopManager 發(fā)行版:https://gitee.com/qishibo/AnotherRedisDesktopManager/releases

責(zé)任編輯:武曉燕 來(lái)源: 碼猿技術(shù)專欄
相關(guān)推薦

2020-04-02 07:31:53

RPC超時(shí)服務(wù)端

2020-05-07 11:00:24

Go亂碼框架

2021-08-30 10:07:12

Redis BigKeyHotKey

2023-12-31 12:06:51

2025-01-28 00:00:00

OOMSpringCglib

2023-09-07 08:05:32

三元表達(dá)式自動(dòng)

2020-04-21 08:24:09

IO機(jī)器代碼

2015-10-14 10:29:43

容器混搭Redis線上故障

2024-05-15 07:26:50

RedisBigKey優(yōu)化

2021-01-20 10:16:26

高并發(fā)數(shù)據(jù)服務(wù)

2021-10-08 08:55:23

FacebookBGP工具

2020-12-09 08:59:59

MongoDB復(fù)合索事故

2022-10-25 18:00:00

Redis事務(wù)生產(chǎn)事故

2021-09-07 10:57:30

物聯(lián)網(wǎng)安全物聯(lián)網(wǎng)IOT

2022-04-08 08:48:16

線上事故日志訂閱者

2021-12-01 17:28:31

加密貨幣能源網(wǎng)絡(luò)

2024-04-16 13:32:57

2024-08-20 21:27:04

docker部署容器

2022-03-16 07:58:02

OOMdubbo內(nèi)存

2023-03-10 08:24:27

OOMdump線程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)