溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Redis中key過期如何解決

發(fā)布時間:2021-08-13 11:19:58 來源:億速云 閱讀:210 作者:Leah 欄目:數(shù)據(jù)庫

這篇文章給大家介紹Redis中key過期如何解決,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。


初步調(diào)查

受影響的團隊和緩存團隊開始進行初步的調(diào)查。我們發(fā)現(xiàn)延遲增加與現(xiàn)在正在發(fā)生的key清除有關(guān)。當(dāng)Redis收到寫入請求但沒有內(nèi)存來保存寫入時,它將停止正在執(zhí)行的操作,清除key然后保存新key。但是,我們?nèi)匀恍枰页鰧?dǎo)致這些新清除的內(nèi)存使用量增加的原因。

我們懷疑內(nèi)存中充滿了過期但尚未刪除的key。有人建議使用掃描,掃描的方法會讀取所有的key,并且讓過期的key被刪除。

在Redis中,key有兩種過期方式,主動過期和被動過期。掃描將觸發(fā)key的被動過期,當(dāng)讀取key時, TTL將會被檢查,如果TTL已過期,TTL會被刪除并且不返回任何內(nèi)容。Redis文檔中描述了版本3.2中的key的主動過期。key的主動過期以一個名為activeExpireCycle的函數(shù)開始。它以每秒運行幾次的頻率,運行在一個稱為cron的內(nèi)部計時器上。activeExpireCycle函數(shù)的作用是遍歷每個密鑰空間,檢查具有TTL集的隨機kry,如果滿足過期kry的百分比閾值,則重復(fù)此過程直到滿足時間限制。

這種掃描所有kry的方法是有效的,當(dāng)掃描完成時,內(nèi)存使用量也下降了。似乎Redis不再有效地使key過期了。但是,當(dāng)時的解決方案是增加集群的大小和更多的硬件,這樣key就會分布得更多,就會有更多的可用內(nèi)存。這是令人失望的,因為前面提到的升級Redis的項目通過提高集群的效率降低了運行這些集群的規(guī)模和成本。

Redis版本:有什么改變?

Redis版本2.4和3.2之間,activeExpireCycle的實現(xiàn)發(fā)生了變化。在Redis 2.4中,每次運行時都會檢查每個數(shù)據(jù)庫,在Redis3.2中,可以檢查的數(shù)據(jù)庫數(shù)量達到了最大值。版本3.2還引入了檢查數(shù)據(jù)庫的快速選項?!癝low”在計時器上運行,“fast” 運行在檢查事件循環(huán)上的事件之前??焖俚狡谥芷趯⒃谀承l件下提前返回,并且它還具有較低的超時和退出功能閾值。時間限制也會被更頻繁地檢查??偣灿?00行代碼被添加到此函數(shù)中。


進一步調(diào)查

最近我們有時間回過頭來重新審視這個內(nèi)存使用問題。我們想探索為什么會出現(xiàn)regression,然后看看我們?nèi)绾尾拍芨玫貙崿F(xiàn)key expiration。我們的第一個想法是,在Redis中有很多的key,只采樣20是遠(yuǎn)遠(yuǎn)不夠的。我們想研究的另一件事是Redi 3.2中引入數(shù)據(jù)庫限制的影響。

縮放和處理shard的方式使得在Twitter上運行Redis是獨一無二的。我們有包含數(shù)百萬個key的key空間。這對于Redis用戶來說并不常見。shard由key空間表示,因此Redis的每個實例都可以有多個shard。我們Redis的實例有很多key空間。Sharding與Twitter的規(guī)模相結(jié)合,創(chuàng)建了具有大量key和數(shù)據(jù)庫的密集后端。

過期測試的改進

每個循環(huán)上采樣的數(shù)字由變量

ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP

配置。我決定測試三個值,并在其中一個有問題的集群中運行這三個值,然后進行掃描,并測量內(nèi)存使用前后的差異。如果內(nèi)存使用前后的差異較大,表明有大量過期數(shù)據(jù)等待收集。這項測試最初在記憶使用方面有積極的結(jié)果。

該測試有一個控件和三個測試實例,可以對更多key進行采樣。500和200是任意的。值300是基于統(tǒng)計樣本大小的計算器的輸出,其中總key數(shù)是總體大小。在上面的圖表中,即使只看測試實例的初始數(shù)量,也可以清楚地看出它們的性能更好。這個與運行掃描的百分比的差異表明,過期key的開銷約為25%。

Redis中key過期如何解決

雖然對更多key進行采樣有助于我們找到更多過期key,但負(fù)延遲效應(yīng)超出了我們的承受能力。

Redis中key過期如何解決

上圖顯示了99.9%的延遲(以毫秒為單位)。這表明延遲與采樣的key的增加相關(guān)。橙色代表值500,綠色代表300,藍色代表200,控制為黃色。這些線條與上表中的顏色相匹配。

在看到延遲受到樣本大小影響后,我想知道是否可以根據(jù)有多少key過期來自動調(diào)整樣本大小。當(dāng)有更多的key過期時,延遲會受到影響,但是當(dāng)沒有更多的工作要做時,我們會掃描更少的key并更快地執(zhí)行。

這個想法基本上是可行的,我們可以看到內(nèi)存使用更低,延遲沒有受到影響,一個度量跟蹤樣本量顯示它隨著時間的推移在增加和減少。但是,我們沒有采用這種解決方案。這種解決方案引入了一些在我們的控件實例中沒有出現(xiàn)的延遲峰值。代碼也有點復(fù)雜,難以解釋,也不直觀。我們還必須針對每個不理想的群集進行調(diào)整,因為我們希望避免增加操作復(fù)雜性。


調(diào)查版本之間的擬合

我們還想調(diào)查Redis版本之間的變化。Redis新版本引入了一個名為CRON_DBS_PER_CALL的變量。這個變量設(shè)置了每次運行此cron時要檢查的最大數(shù)據(jù)庫數(shù)量。為了測試這種變量的影響,我們簡單地注釋掉了這些行。


//if (dbs_per_call > server.dbnum || timelimit_exit)
dbs_per_call = server.dbnum;

這會比較每次運行時具有限制的,和沒有限制的檢查所有數(shù)據(jù)庫兩個方法之間的效果。我們的基準(zhǔn)測試結(jié)果十分令人興奮。但是,我們的測試實例只有一個數(shù)據(jù)庫,從邏輯上講,這行代碼在修改版本和未修改版本之間沒有什么區(qū)別。變量始終都會被設(shè)置。

Redis中key過期如何解決

99.9%的以微秒為單位。未修改的Redis在上面,修改的Redis在下面。

我們開始研究為什么注釋掉這一行會產(chǎn)生如此巨大的差異。由于這是一個if語句,我們首先懷疑的是分支預(yù)測。我們利用

gcc’s__builtin_expect

來改變代碼的編譯方式。但是,這對性能沒有任何影響。

接下來,我們查看生成的程序集,以了解究竟發(fā)生了什么。

我們將if語句編譯成三個重要指令mov、cmp和jg。Mov將加載一些內(nèi)存到寄存器中,cmp將比較兩個寄存器并根據(jù)結(jié)果設(shè)置另一個寄存器,jg將根據(jù)另一個寄存器的值執(zhí)行條件跳轉(zhuǎn)。跳轉(zhuǎn)到的代碼將是if塊或else塊中的代碼。我取出if語句并將編譯后的程序集放入Redis中。然后我通過注釋不同的行來測試每條指令的效果。我測試了mov指令,看看是否存在加載內(nèi)存或cpu緩存方面的性能問題,但沒有發(fā)現(xiàn)區(qū)別。我測試了cmp指令也沒有發(fā)現(xiàn)區(qū)別。當(dāng)我使用包含的jg指令運行測試時,延遲會回升到未修改的級別。在找到這個之后,我測試了它是否只是一個跳轉(zhuǎn),或者是一個特定的jg指令。我添加了非條件跳轉(zhuǎn)指令jmp,跳轉(zhuǎn)然后跳回到代碼運行,期間沒有出現(xiàn)性能損失。

我們花了一些時間查看不同的性能指標(biāo),并嘗試了cpu手冊中列出的一些自定義指標(biāo)。關(guān)于為什么一條指令會導(dǎo)致這樣的性能問題,我們沒有任何結(jié)論。當(dāng)執(zhí)行跳轉(zhuǎn)時,我們有一些與指令緩存緩沖區(qū)和cpu行為相關(guān)的想法,但是時間不夠了,可能的話,我們會在將來再回到這一點。


解析度

既然我們已經(jīng)很好地理解了問題的原因,那么我們需要選擇一個解決這個問題的方法。我們的決定是進行簡單的修改,以便能夠在啟動選項中配置穩(wěn)定的樣本量。這樣,我們就能夠在延遲和內(nèi)存使用之間找到一個很好的平衡點。即使刪除if語句引起了如此大幅度的改進,如果我們不能解釋清楚其原因,我們也很難做出改變。

Redis中key過期如何解決


關(guān)于Redis中key過期如何解決就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI