真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Redis中key過期如何解決

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

我們提供的服務(wù)有:網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、勃利ssl等。為成百上千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的勃利網(wǎng)站制作公司

初步調(diào)查

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

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

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

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

Redis版本:有什么改變?

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

進(jìn)一步調(diào)查

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

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

過期測試的改進(jìn)

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

ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP

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

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

Redis中key過期如何解決

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

Redis中key過期如何解決

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

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

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

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

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

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

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

Redis中key過期如何解決

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

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

gcc’s__builtin_expect

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

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

我們將if語句編譯成三個(gè)重要指令mov、cmp和jg。Mov將加載一些內(nèi)存到寄存器中,cmp將比較兩個(gè)寄存器并根據(jù)結(jié)果設(shè)置另一個(gè)寄存器,jg將根據(jù)另一個(gè)寄存器的值執(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指令運(yùn)行測試時(shí),延遲會回升到未修改的級別。在找到這個(gè)之后,我測試了它是否只是一個(gè)跳轉(zhuǎn),或者是一個(gè)特定的jg指令。我添加了非條件跳轉(zhuǎn)指令jmp,跳轉(zhuǎn)然后跳回到代碼運(yùn)行,期間沒有出現(xiàn)性能損失。

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

解析度

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

Redis中key過期如何解決

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


網(wǎng)頁標(biāo)題:Redis中key過期如何解決
網(wǎng)站地址:http://weahome.cn/article/jhigoj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部