redis调优 -- 内存碎片
?最近查看了一下redis運(yùn)行狀況,發(fā)現(xiàn)公司測(cè)試服務(wù)器的redis內(nèi)存不太夠用,但是實(shí)際占用內(nèi)存的數(shù)據(jù)量其實(shí)不大,以前也沒有這種情況,之前在cache層新增了一個(gè)防刷積分任務(wù)的邏輯才會(huì)這樣,搜索一下原因,發(fā)現(xiàn)原來(lái)是產(chǎn)生了大量的內(nèi)存碎片。
首先,查看redis的內(nèi)存狀態(tài),要用info memory指令
?
圖中幾個(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ì)算公式:
ratio指數(shù)>1表明有內(nèi)存碎片,越大表明越多,<1表明正在使用虛擬內(nèi)存,虛擬內(nèi)存其實(shí)就是硬盤,性能比內(nèi)存低得多,這是應(yīng)該增強(qiáng)機(jī)器的內(nèi)存以提高性能。一般來(lái)說(shuō),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)存單元如下圖所示:
?
----------------------------------------------------- 分割線 ------------------------------------------------
產(chǎn)生原因
可以這樣認(rèn)為,redis產(chǎn)生內(nèi)存碎片有兩個(gè)原因,
 A:redis自身的內(nèi)存分配器。
 B:修改cache的值,且修改后的value與原來(lái)value的大小差異較大。
進(jìn)程需要用內(nèi)存的話,會(huì)先通過(guò)OS向device申請(qǐng),然后才能夠使用。一般進(jìn)程在不需要使用的時(shí)候,會(huì)釋放掉這部分內(nèi)存并返回給device。但是redis作者可能為了更高的性能,所以在redis中實(shí)現(xiàn)了自己的內(nèi)存分配器來(lá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改變的并且原來(lái)內(nèi)存大小不適用的時(shí)候,就需要重新分配內(nèi)存了。(但是value存比原來(lái)小不知道會(huì)不會(huì)產(chǎn)生碎片)。重新分配之后,就會(huì)有一部分內(nèi)存redis無(wú)法正常回收,一直占用著。
----------------------------------------------------- 分割線 ------------------------------------------------
知道了原因就可以解決問題了,網(wǎng)上找到了兩個(gè)解決方案:
 1、重啟redis服務(wù),簡(jiǎn)單粗暴。
 2、redis4.0以上可以使用新增指令來(lái)手動(dòng)回收內(nèi)存碎片,配置監(jiān)控使用性能更佳,具體大家可以自己去查。
這里提個(gè)問題,如果是單機(jī)redis,想要不停服務(wù)重啟redis,大家有什么好的想法?
總結(jié)
以上是生活随笔為你收集整理的redis调优 -- 内存碎片的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 对超长的文字换行处理:程序和CSS样式
- 下一篇: MySQL中information_sc
