redis進(jìn)程內(nèi)消耗主要包括:自身內(nèi)存+對(duì)象內(nèi)存+緩沖內(nèi)存+內(nèi)存碎片。
內(nèi)存。因?yàn)?a href="http://www.babyishan.com/tag/redis">redis的數(shù)據(jù)都是存儲(chǔ)在內(nèi)存當(dāng)中。內(nèi)存數(shù)據(jù)庫相比一般的關(guān)系型數(shù)據(jù)庫,讀取速度要更快,但是消耗的內(nèi)存資源會(huì)更多。
?對(duì)象內(nèi)存(推薦學(xué)習(xí):Redis視頻教程)
對(duì)象內(nèi)存是Redis內(nèi)存占用最大的一塊,存儲(chǔ)著用戶所有的數(shù)據(jù)。Redis所有數(shù)據(jù)都采用key-value數(shù)據(jù)類型,每次創(chuàng)建鍵值對(duì)時(shí),至少創(chuàng)建兩個(gè)類型對(duì)象:key對(duì)象和value對(duì)象。內(nèi)存消耗可以簡單的理解為sizeof(keys)+sizeof(values)。鍵對(duì)象都是字符串,在使用Redis時(shí)很容易忽略鍵對(duì)內(nèi)存消耗的影響,應(yīng)當(dāng)避免使用過長的鍵。value對(duì)象更復(fù)雜些,主要包括5種基本數(shù)據(jù)類型:字符串、列表、哈希、集合、有序集合。每種value對(duì)象類型根據(jù)使用規(guī)模不同,占用內(nèi)存不同。在使用時(shí)一定要合理預(yù)估并監(jiān)控value對(duì)象占用情況,避免內(nèi)存溢出。
緩沖內(nèi)存
緩沖內(nèi)存主要包括:客戶端緩沖、復(fù)制積壓緩沖區(qū)、AOF緩沖區(qū)。
客戶端緩沖指的是所有接入到Redis服務(wù)器TCP連接的輸入輸出緩沖。輸入輸出緩沖無法控制,最大空間為1G,如果超過將斷開連接。輸入緩沖通過參數(shù)client-output-buffer-limit控制:
1.普通客戶端:除了復(fù)制和訂閱的客戶端之外的所有連接,Redis的默認(rèn)配置是:client-output-buffer-limit normal 0 0 0,Redis并沒有對(duì)普通客戶端的輸出緩沖區(qū)做限制,一般普通客戶端的內(nèi)存消耗可以忽略不計(jì),但是當(dāng)有大量慢連接客戶端接入時(shí)這部分內(nèi)存消耗就不能忽略了,可以設(shè)置maxclients做限制。注意不要只用大量數(shù)據(jù)輸出的命令且數(shù)據(jù)無法及時(shí)推送給客戶端,如 monitor命令,容易造成Redis服務(wù)器內(nèi)存突然飆升。
從客戶端:主節(jié)點(diǎn)會(huì)為每個(gè)從節(jié)點(diǎn)單獨(dú)建立一條連接用于命令復(fù)制,默認(rèn)配置是:client-output-buffer-limit slave 256mb 64mb 60。當(dāng)主從節(jié)點(diǎn)之間網(wǎng)絡(luò)延遲較高或主節(jié)點(diǎn)掛載大量從節(jié)點(diǎn)時(shí)這部分內(nèi)存消耗將占用很大一部分,建議主節(jié)點(diǎn)掛載的從節(jié)點(diǎn)不要多于2個(gè),主從節(jié)點(diǎn)不要部署在較差的網(wǎng)絡(luò)環(huán)境下,如異地跨機(jī)房,防止復(fù)制客戶端連接緩慢造成溢出。
訂閱客戶端:當(dāng)使用發(fā)布訂閱功能時(shí),連接客戶端使用單獨(dú)的輸出緩沖區(qū),默認(rèn)配置為:client-output-buffer-limit pubsub 32mb 8mb 60,當(dāng)訂閱服務(wù)的消息生產(chǎn)快于消費(fèi)速度時(shí),輸出緩沖區(qū)會(huì)產(chǎn)生積壓造成輸出緩沖區(qū)空間溢出。
復(fù)制積壓緩沖區(qū):Redis在2.8版本之后提供了一個(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。
AOF緩沖區(qū):這部分空間用于在Redis重寫期間保存最近的寫入命令。
3.內(nèi)存碎片
Redis默認(rèn)的內(nèi)存分配器采用jemalloc,可選的分配器還有:glibc、tcmalloc。內(nèi)存分配器為了更好地管理和重復(fù)利用內(nèi)存,分配內(nèi)存策略一般采用固定范圍的內(nèi)存塊進(jìn)行分配。
以下場景容易出現(xiàn)高內(nèi)存碎片問題:
頻繁做更新操作,例如頻繁對(duì)已存在的鍵執(zhí)行append、setrange等更新操作。
大量過期鍵刪除,鍵對(duì)象過期刪除后,釋放的空間無法得到充分利用,導(dǎo)致碎片率上升。
更多Redis相關(guān)技術(shù)文章,請(qǐng)?jiān)L問Redis視頻教程欄目進(jìn)行學(xué)習(xí)!