【redis】redis內(nèi)存管理、淘汰機(jī)制、內(nèi)存優(yōu)化
文章目錄
配置redis
最大內(nèi)存限制
查看redis內(nèi)存相關(guān)信息:INFO memory
內(nèi)存都去哪兒了?還沒(méi)好好使用,就爆了
內(nèi)存回收策略
過(guò)期鍵值
Redis如何淘汰過(guò)期的keys
內(nèi)存移除控制策略
8個(gè)解決方方案
回收進(jìn)程如何工作
近似LRU算法
內(nèi)存優(yōu)化
使用32位的redis
位級(jí)別和字級(jí)別的操作
盡可能使用散列表
配置redis
如果想要運(yùn)行一個(gè)內(nèi)存高效的 Redis 數(shù)據(jù)庫(kù),首先需要理解那些在 redis.conf 配置文件中所有內(nèi)存相關(guān)的指令。redis.conf 文件為大多數(shù)指令提供了豐富的內(nèi)聯(lián)文檔,使得一些復(fù)雜的內(nèi)存優(yōu)化選項(xiàng)易于理解、更改和測(cè)試。
傳送門:redis.conf翻譯與配置內(nèi)存管理部分
大多數(shù) Redis 配置指令可以在運(yùn)行時(shí)通過(guò) CONFIG SET 命令進(jìn)行設(shè)置。
最大內(nèi)存限制
Redis使用 maxmemory 參數(shù)限制最大可用內(nèi)存,默認(rèn)關(guān)閉。
限制內(nèi)存的目的主要 有:
用于緩存場(chǎng)景,當(dāng)超出內(nèi)存上限 maxmemory 時(shí)使用 LRU 等刪除策略釋放空間。 防止所用內(nèi)存超過(guò)服務(wù)器物理內(nèi)存。
maxmemory 限制的是Redis實(shí)際使用的內(nèi)存量,也就是 used_memory統(tǒng)計(jì)項(xiàng)對(duì)應(yīng)的內(nèi)存。由于內(nèi)存碎片率的存在,實(shí)際消耗的內(nèi)存 可能會(huì)比maxmemory設(shè)置的更大,
實(shí)際使用時(shí)要小心這部分內(nèi)存溢出
。redis.conf翻譯與配置(內(nèi)存碎片部分)
Redis默認(rèn)無(wú)限使用服務(wù)器內(nèi)存,為防止極端情況下導(dǎo)致系統(tǒng)內(nèi)存耗 盡,
建議所有的Redis進(jìn)程都要配置maxmemory
。 在保證物理內(nèi)存可用的情況下,系統(tǒng)中所有Redis實(shí)例可以調(diào)整 maxmemory參數(shù)來(lái)達(dá)到自由伸縮內(nèi)存的目的。
查看redis內(nèi)存相關(guān)信息:INFO memory
當(dāng) memfragmentationratio > 1 時(shí),說(shuō)明有部分內(nèi)存并沒(méi)有用于數(shù)據(jù)存儲(chǔ),而是被內(nèi)存碎片所消耗,如果該值很大,說(shuō)明碎片率嚴(yán)重。當(dāng) memfragmentationratio < 1 時(shí),這種情況一般出現(xiàn)在操作系統(tǒng)把 Redis 內(nèi)存交換 (swap) 到硬盤導(dǎo)致,出現(xiàn)這種情況要格外關(guān)注,由于硬盤速度遠(yuǎn)遠(yuǎn)慢于內(nèi)存,Redis 性能會(huì)變得很差,甚至僵死。
當(dāng) Redis 內(nèi)存超出可以獲得內(nèi)存時(shí),操作系統(tǒng)會(huì)進(jìn)行 swap,將舊的頁(yè)寫入硬盤。從硬盤讀寫大概比從內(nèi)存讀寫要慢5個(gè)數(shù)量級(jí)。used_memory 指標(biāo)可以幫助判斷 Redis 是否有被swap的風(fēng)險(xiǎn)或者它已經(jīng)被swap。
建議要設(shè)置和內(nèi)存一樣大小的交換區(qū),如果沒(méi)有交換區(qū),一旦 Redis 突然需要的內(nèi)存大于當(dāng)前操作系統(tǒng)可用內(nèi)存時(shí),Redis 會(huì)因?yàn)?out of memory 而被 Linix Kernel 的 OOM Killer 直接殺死。雖然當(dāng) Redis 的數(shù)據(jù)被換出 (swap out) 時(shí),Redis的性能會(huì)變差,但是總比直接被殺死的好。:建議自:https://redis.io/topics/admin
內(nèi)存都去哪兒了?還沒(méi)好好使用,就爆了
1.自身內(nèi)存:redis自身運(yùn)行所消耗的內(nèi)存,一般很小。
2.對(duì)象內(nèi)存:這是redis消耗內(nèi)存最大的一塊,存儲(chǔ)著用戶所有的數(shù)據(jù)。
3.緩沖內(nèi)存:緩沖內(nèi)存主要包括:客戶端緩沖、復(fù)制積壓緩沖區(qū)、AOF緩沖區(qū)。
客戶端緩沖:是指客戶端連接redis之后,輸入或者輸出數(shù)據(jù)的緩沖區(qū),其中輸出緩沖可以通過(guò)配置參數(shù)參數(shù)client-output-buffer-limit控制。
復(fù)制積壓緩沖區(qū):一個(gè)可重用的固定大小緩沖區(qū)用于實(shí)現(xiàn)部分復(fù)制功能,根據(jù)repl-backlog-size參數(shù)控制,默認(rèn)1MB。對(duì)于復(fù)制積壓緩沖區(qū)整個(gè)主節(jié)點(diǎn)只有一個(gè),所有的從節(jié)點(diǎn)共享此緩沖區(qū),因此可以設(shè)置較大的緩沖區(qū)空間,如100MB,這部分內(nèi)存投入是有價(jià)值的,可以有效避免全量復(fù)制。
AOF緩沖區(qū):這部分空間用于在Redis重寫期間保存最近的寫入命令,AOF緩沖區(qū)空間消耗用戶無(wú)法控制,消耗的內(nèi)存取決于AOF重寫時(shí)間和寫入命令量,這部分空間占用通常很小。
4.內(nèi)存碎片:當(dāng)然,這是所有內(nèi)存分配器無(wú)法避免的通病,但是可以優(yōu)化。
如果對(duì)這方面有想法的話:走近STL – 空間配置器,STL背后的故事
內(nèi)存回收策略
Redis 回收內(nèi)存大致有兩個(gè)機(jī)制:一是刪除到達(dá)過(guò)期時(shí)間的鍵值對(duì)象;二是當(dāng)內(nèi)存達(dá)到 maxmemory 時(shí)觸發(fā)內(nèi)存移除控制策略,強(qiáng)制刪除選擇出來(lái)的鍵值對(duì)象。
過(guò)期鍵值
Redis keys過(guò)期有兩種方式:被動(dòng)和主動(dòng)方式。
當(dāng)一些客戶端嘗試訪問(wèn)它時(shí),key會(huì)被發(fā)現(xiàn)并主動(dòng)的過(guò)期。
當(dāng)然,這樣是不夠的,因?yàn)橛行┻^(guò)期的keys,永遠(yuǎn)不會(huì)訪問(wèn)他們。 無(wú)論如何,這些keys應(yīng)該過(guò)期,所以定時(shí)隨機(jī)測(cè)試設(shè)置keys的過(guò)期時(shí)間。所有這些過(guò)期的keys將會(huì)從密鑰空間刪除。
具體就是Redis每秒10次做的事情:
測(cè)試隨機(jī)的20個(gè)keys進(jìn)行相關(guān)過(guò)期檢測(cè)。 刪除所有已經(jīng)過(guò)期的keys。 如果有多于25%的keys過(guò)期,重復(fù)步奏1.
為了獲得正確的行為而不犧牲一致性,當(dāng)一個(gè)key過(guò)期,DEL將會(huì)隨著AOF文字一起合成到所有附加的slaves。在master實(shí)例中,這種方法是集中的,并且不存在一致性錯(cuò)誤的機(jī)會(huì)。
然而,當(dāng)slaves連接到master時(shí),不會(huì)獨(dú)立過(guò)期keys(會(huì)等到master執(zhí)行DEL命令),他們?nèi)稳粫?huì)在數(shù)據(jù)集里面存在,所以當(dāng)slave當(dāng)選為master時(shí)淘汰keys會(huì)獨(dú)立執(zhí)行,然后成為master。
內(nèi)存移除控制策略
8個(gè)解決方方案
當(dāng)maxmemory限制達(dá)到的時(shí)候Redis會(huì)使用的行為由 Redis的maxmemory-policy配置指令來(lái)進(jìn)行配置。
在redis.conf中提出了8個(gè)解決方法。
volatile-lru ->退出使用近似的LRU,僅使用設(shè)置了過(guò)期值的鍵。 allkeys-lru ->使用近似的LRU驅(qū)逐任何密鑰。 volatile-lfu ->使用近似的LFU逐出,僅使用具有過(guò)期集的鍵。 allkeys-lfu ->使用近似的LFU驅(qū)逐任何密鑰。 volatile-random ->刪除一個(gè)具有過(guò)期設(shè)置的隨機(jī)鍵。 allkeys-random ->刪除一個(gè)隨機(jī)鍵,任意鍵。 volatile-ttl ->刪除最近過(guò)期時(shí)間的密鑰(較小的TTL) noeviction ->不驅(qū)逐任何東西,只是在寫操作時(shí)返回一個(gè)錯(cuò)誤。
LRU表示最近最少使用
LFU表示使用頻率最低
LRU、LFU和volatile-ttl都是使用近似隨機(jī)算法實(shí)現(xiàn)的。
注意:使用上述任何策略,當(dāng)沒(méi)有合適的鍵用于驅(qū)逐時(shí),Redis會(huì)在寫操作時(shí)返回一個(gè)錯(cuò)誤。
一般的經(jīng)驗(yàn)規(guī)則:
使用allkeys-lru策略:當(dāng)你希望你的請(qǐng)求符合一個(gè)冪定律分布,也就是說(shuō),你希望部分的子集元素將比其它其它元素被訪問(wèn)的更多。如果你不確定選擇什么,這是個(gè)很好的選擇。. 使用allkeys-random:如果你是循環(huán)訪問(wèn),所有的鍵被連續(xù)的掃描,或者你希望請(qǐng)求分布正常(所有元素被訪問(wèn)的概率都差不多)。 使用volatile-ttl:如果你想要通過(guò)創(chuàng)建緩存對(duì)象時(shí)設(shè)置TTL值,來(lái)決定哪些對(duì)象應(yīng)該被過(guò)期。
allkeys-lru 和 volatile-random策略對(duì)于當(dāng)你想要單一的實(shí)例實(shí)現(xiàn)緩存及持久化一些鍵時(shí)很有用。不過(guò)一般運(yùn)行兩個(gè)實(shí)例是解決這個(gè)問(wèn)題的更好方法。
為了鍵設(shè)置過(guò)期時(shí)間也是需要消耗內(nèi)存的,所以使用allkeys-lru這種策略更加高效。
回收進(jìn)程如何工作
理解回收進(jìn)程如何工作是非常重要的:
一個(gè)客戶端運(yùn)行了新的命令,添加了新的數(shù)據(jù)。 Redis檢查內(nèi)存使用情況,如果大于maxmemory的限制, 則根據(jù)設(shè)定好的策略進(jìn)行回收。 一個(gè)新的命令被執(zhí)行,等等。 所以我們不斷地穿越內(nèi)存限制的邊界,通過(guò)不斷達(dá)到邊界然后不斷地回收回到邊界以下。
近似LRU算法
Redis的LRU算法并非完整的實(shí)現(xiàn)。
Redis為什么不使用真實(shí)的LRU實(shí)現(xiàn)是因?yàn)檫@需要太多的內(nèi)存。
內(nèi)存優(yōu)化
使用32位的redis
使用32位的redis,對(duì)于每一個(gè)key,將使用更少的內(nèi)存,因?yàn)?2位程序,指針占用的字節(jié)數(shù)更少。但是32的redis整個(gè)實(shí)例使用的內(nèi)存將被限制在4G以下。
使用make 32bit命令編譯生成32位的redis。RDB和AOF文件是不區(qū)分32位和64位的(包括字節(jié)順序),所以你可以使用64位的reidis恢復(fù)32位的RDB備份文件,相反亦然。
位級(jí)別和字級(jí)別的操作
Redis 2.2引入了位級(jí)別和字級(jí)別的操作: GETRANGE, SETRANGE, GETBIT 和 SETBIT.使用這些命令。
對(duì)位操作不熟的話,可以看一下這兩篇:
位運(yùn)算 - 初見(jiàn)
位圖 - 海量數(shù)據(jù)處理
盡可能使用散列表
小散列表(是說(shuō)散列表里面存儲(chǔ)的數(shù)少)使用的內(nèi)存非常小,所以你應(yīng)該盡可能的將你的數(shù)據(jù)模型抽象到一個(gè)散列表里面。
先到這兒吧,也該去吃飯了。
Redis
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。