redis調(diào)優(yōu) -- 內(nèi)存碎片

最近查看了一下redis運(yùn)行狀況,發(fā)現(xiàn)公司測(cè)試服務(wù)器的redis內(nèi)存不太夠用,但是實(shí)際占用內(nèi)存的數(shù)據(jù)量其實(shí)不大,以前也沒有這種情況,之前在cache層新增了一個(gè)防刷積分任務(wù)的邏輯才會(huì)這樣,搜索一下原因,發(fā)現(xiàn)原來是產(chǎn)生了大量的內(nèi)存碎片。

首先,查看redis的內(nèi)存狀態(tài),要用info memory指令


2018-06-01_110028.png

ps:(這個(gè)是我flushdb后的結(jié)果,反面教材來的。。。)
圖中幾個(gè)參數(shù)的意義:

1、used_memory:

已經(jīng)使用了的內(nèi)存大小,包括redis進(jìn)程內(nèi)部開銷和你的cache的數(shù)據(jù)所占用的內(nèi)存,單位byte。

2、used_memory_human:

用戶數(shù)據(jù)所占用的內(nèi)存,就是你緩存的數(shù)據(jù)的大小。

3、used_memory_rss:(rss for Resident Set Size)

表示redis物理內(nèi)存的大小,即向OS申請(qǐng)了多少內(nèi)存使用與used_memory的區(qū)別在后面解釋。

4、used_memory_peak:

redis內(nèi)存使用的峰值。

5、used_memory_peak_human:

用戶cache數(shù)據(jù)的峰值大小。

6、used_memory_lua:

執(zhí)行l(wèi)ua腳本所占用的內(nèi)存。

7、mem_fragmentation_ratio:

內(nèi)存碎片率,計(jì)算公式:
190138549569988.png

ratio指數(shù)>1表明有內(nèi)存碎片,越大表明越多,<1表明正在使用虛擬內(nèi)存,虛擬內(nèi)存其實(shí)就是硬盤,性能比內(nèi)存低得多,這是應(yīng)該增強(qiáng)機(jī)器的內(nèi)存以提高性能。一般來說,mem_fragmentation_ratio的數(shù)值在1 ~ 1.5之間是比較健康的。

8、mem_allocator:

在編譯時(shí)指定的Redis使用的內(nèi)存分配器,可以是libc、jemalloc、tcmalloc,默認(rèn)是jemalloc。jemalloc在64位系統(tǒng)中,將內(nèi)存空間劃分為小、大、巨大三個(gè)范圍;每個(gè)范圍內(nèi)又劃分了許多小的內(nèi)存塊單位;存儲(chǔ)數(shù)據(jù)的時(shí)候,會(huì)選擇大小最合適的內(nèi)存塊進(jìn)行存儲(chǔ)。
jemalloc劃分的內(nèi)存單元如下圖所示:


1174710-20180327001126509-2023165562.png

(圖侵刪)

----------------------------------------------------- 分割線 ------------------------------------------------

產(chǎn)生原因

可以這樣認(rèn)為,redis產(chǎn)生內(nèi)存碎片有兩個(gè)原因,
A:redis自身的內(nèi)存分配器。
B:修改cache的值,且修改后的value與原來value的大小差異較大。

進(jìn)程需要用內(nèi)存的話,會(huì)先通過OS向device申請(qǐng),然后才能夠使用。一般進(jìn)程在不需要使用的時(shí)候,會(huì)釋放掉這部分內(nèi)存并返回給device。但是redis作者可能為了更高的性能,所以在redis中實(shí)現(xiàn)了自己的內(nèi)存分配器來管理內(nèi)存,不會(huì)馬上返還內(nèi)存,不用每次都向OS申請(qǐng)了,從而實(shí)現(xiàn)高性能。

但是,在內(nèi)存分配器的那張圖片我們知道,redis的每個(gè)k-v對(duì)初始化的內(nèi)存大小是最適合的,當(dāng)這個(gè)value改變的并且原來內(nèi)存大小不適用的時(shí)候,就需要重新分配內(nèi)存了。(但是value存比原來小不知道會(huì)不會(huì)產(chǎn)生碎片)。重新分配之后,就會(huì)有一部分內(nèi)存redis無法正?;厥?,一直占用著。

----------------------------------------------------- 分割線 ------------------------------------------------

知道了原因就可以解決問題了,網(wǎng)上找到了兩個(gè)解決方案:
1、重啟redis服務(wù),簡(jiǎn)單粗暴。
2、redis4.0以上可以使用新增指令來手動(dòng)回收內(nèi)存碎片,配置監(jiān)控使用性能更佳,具體大家可以自己去查。

這里提個(gè)問題,如果是單機(jī)redis,想要不停服務(wù)重啟redis,大家有什么好的想法?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容