Redis 持久化內(nèi)存不足分析

? ? ? ?在最近的工作中,碰到很多Redis的問題贬丛,項目組將Redis當做黑盒子使用撩银,這是一件很危險的事情,導致很多意想不到的事情發(fā)生豺憔,在使用Redis的時候额获,我們必須理解redis.conf中常用參數(shù)的意義,例如maxmemory最大內(nèi)存恭应,默認是操作系統(tǒng)可用的最大內(nèi)存抄邀,這個明顯在生產(chǎn)上是必須配置具體值,但是很遺憾暮屡,項目組在使用中沒有調(diào)整撤摸。今天我要講的是redis的內(nèi)存使用,redis的內(nèi)存其實有數(shù)據(jù)內(nèi)存褒纲,進程內(nèi)存准夷,輸入緩存區(qū)大小,輸出連接動態(tài)內(nèi)存等不同的概念莺掠,這里我們只針對RDB和AOF持久化的時候衫嵌,fork進程需要的內(nèi)存大小進行講解,從而理解一臺虛擬機內(nèi)存和Redis內(nèi)存的配置關系彻秆。

1楔绞、fork 的原理

? ? ? ? 在redis在進行持久化的時候,有的時候可以在日志中看到fork進程失敗的提示唇兑,一般是系統(tǒng)可用的內(nèi)存空間不夠導致酒朵,這需要我們對fork原理明白,才能更好的進行參數(shù)調(diào)整扎附。一般來說Redis在進行RDB的時候蔫耽,會fork出一個子進程,子進程和父進程會共享一個地址空間留夜,在fork子進程的時候匙铡,會檢查當前機器可用的內(nèi)存是否滿足fork出一個子進程的要求图甜,一般由操作系統(tǒng)?overcommit_memory決定。

overcommit_memory參數(shù)說明: 設置內(nèi)存分配策略(可選鳖眼,根據(jù)服務器的實際情況進行設置) /proc/sys/vm/overcommit_memory 可選值:

?0黑毅, 表示內(nèi)核將檢查是否有足夠的可用內(nèi)存供應用進程使用;如果有足夠的可用內(nèi)存钦讳,內(nèi)存申請允許矿瘦;否則,內(nèi)存申請失敗蜂厅,并把錯誤返回給應用進程匪凡。 操作系統(tǒng)默認參數(shù),如果redis進程使用了9G空間掘猿,fork需要9G內(nèi)存,但是整個操作系統(tǒng)內(nèi)存16G唇跨,9+9>16稠通,那么fork會失敗。

1买猖, 表示內(nèi)核允許分配所有的物理內(nèi)存改橘,而不管當前的內(nèi)存狀態(tài)如何,實際在fork出子進程真正執(zhí)行的時候玉控,需要的內(nèi)存并不會有父進程那么大飞主,如果redis進程使用了9G,整個內(nèi)存16G高诺,這個時候只要有剩余內(nèi)存碌识,就會fork成功,而且子進程在RDB的時候虱而,整個需要的內(nèi)存空間并不需要9G筏餐,因為父子進程共享數(shù)據(jù)空間,需要新增的的內(nèi)存空間是RDB備份過程中 copy-on-writer變化的數(shù)據(jù)空間牡拇,取決于數(shù)據(jù)變化和頁空間魁瞪,一般都不會特別大。

2惠呼, 表示內(nèi)核允許分配超過所有物理內(nèi)存和交換空間總和的內(nèi)存导俘,根據(jù)vm.overcommit_ratio定義的值,允許分配超出物理內(nèi)存加上交換內(nèi)存的請求剔蹋。vm.overcommit_ratio參數(shù)是一個百分比旅薄,加上內(nèi)存量決定內(nèi)存可以超量分配多少內(nèi)存。例如滩租,vm.overcommit_ratio值為50赋秀,而內(nèi)存有16GB利朵,那么這意味著在內(nèi)存分配請求失敗前,加上交換內(nèi)存4G猎莲,內(nèi)存將允許高達16*.0.5+4=12GB的內(nèi)存分配請求

? ? ? 通過上面的分析绍弟,我們可以看到,針對Redis的持久化著洼,尤其是在一臺機器上部署多個節(jié)點的時候樟遣,我們可以通過設置overcommit_memory=1的優(yōu)化,減少操作系統(tǒng)內(nèi)存身笤,提高redis的fork成功率豹悬,因為fork后的進程和父進程共享一個數(shù)據(jù)空間,持久化要新增的內(nèi)存空間都會小于父進程已經(jīng)使用的空間液荸,具體設置為:

echo “vm.overcommit_memory=1” >> /etc/sysctl.conf

sysctl vm.overcommit_memory=1

2瞻佛、減少fork時父進程變化內(nèi)存

? ? ? 上面講到,當redis持久化fork子進程后娇钱,占用內(nèi)存大小和父進程等同伤柄,由于Linux在寫時有copy-on-write機制,父子進程共享相同的物理內(nèi)存頁文搂,當父進程處理寫請求的時候會把要修改的頁創(chuàng)建副本适刀,而子進程在fork過程中共享整個父進程的內(nèi)存快照,在RDB重寫時煤蹭,Redis的日志輸出 RDB: 657 MB of memory used by copy-on-write笔喉。代表重寫過程中有內(nèi)存頁被修改,父進程創(chuàng)建了副本硝皂,這部分的內(nèi)存空間是657MB的大小常挚。如果我們要減少創(chuàng)建的副本的大小,就涉及操作系統(tǒng)的另外一個概念 Huge Pages 大頁吧彪。

? ? ? ?在Redhat Linux中待侵,內(nèi)存都是以頁的形式劃分的,默認情況下每頁是4K姨裸,這就意味著如果物理內(nèi)存很大秧倾,則映射表的條目將會非常多,會影響CPU的檢索效率傀缩。因為內(nèi)存大小是固定的那先,為了減少映射表的條目,可采取的辦法只有增加頁的尺寸赡艰。Linux Kernel在2.6.38內(nèi)核中增加了THP的特性售淡,支持大內(nèi)存頁(2MB)分配,默認開啟。當開啟后可以加快fork子進程的速度揖闸,但fork操作之后揍堕,每個內(nèi)存頁從原來的4KB變成了2MB,會大幅增加重寫期間父進程內(nèi)存消耗汤纸,同時每次寫命令引起的復制內(nèi)存頁單位放大了512倍衩茸,會拖慢寫操作的執(zhí)行時間,因此在Redis的時候日志建議是對此特性進行禁用贮泞,方法為: echo never > /sys/kernel/mm/transparent_hugepage/enabled楞慈。為了讓機器重啟該參數(shù)仍然生效,建議在/etc/rc.local中追加啃擦,避免失效囊蓝。當大頁被關閉后,可以看到同等操作下令蛉,RDB備份時候的copy-on-write變化內(nèi)存空間會減少聚霜。

? ? ?綜上分析,我們可以操作系統(tǒng)物理內(nèi)存和Redis內(nèi)存之間的一些關系珠叔,尤其Redis在持久化的時候fork進程會隨操作系統(tǒng)的參數(shù)不同俯萎,需要的內(nèi)存也有所不同,為了加快fork子進程的速度以及主備之間的文件傳輸同步运杭,一般我們建議一個Redis節(jié)點的最大內(nèi)存在10G-15G左右,操作系統(tǒng)的內(nèi)存適當冗余函卒,盡量控制同一臺機器的多個Redis節(jié)點在同一個時間點進行RDB備份(可以通過緩存中心定時備份)辆憔,導致內(nèi)存同一時刻增加避免內(nèi)存空間不足導致的fork失敗,最安全保險的情況是內(nèi)存為Redis的2倍报嵌,但是在vm.overcommit_memory=1和大頁管關閉的情況下虱咧,可以根據(jù)實際使用,降低操作系統(tǒng)的整個內(nèi)存大小 锚国。

? ? ? 對于使用人員來說腕巡,一定要清楚原理,重點評估Redis的總節(jié)點數(shù)和操作系統(tǒng)內(nèi)存的關系血筑,避免持久化和高可用性帶來的內(nèi)存不足問題绘沉。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市豺总,隨后出現(xiàn)的幾起案子车伞,更是在濱河造成了極大的恐慌,老刑警劉巖喻喳,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件另玖,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機谦去,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門慷丽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鳄哭,你說我怎么就攤上這事要糊。” “怎么了窃诉?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵杨耙,是天一觀的道長。 經(jīng)常有香客問我飘痛,道長珊膜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任宣脉,我火速辦了婚禮车柠,結果婚禮上,老公的妹妹穿的比我還像新娘塑猖。我一直安慰自己竹祷,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布羊苟。 她就那樣靜靜地躺著塑陵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蜡励。 梳的紋絲不亂的頭發(fā)上令花,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音凉倚,去河邊找鬼兼都。 笑死,一個胖子當著我的面吹牛稽寒,可吹牛的內(nèi)容都是我干的扮碧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼杏糙,長吁一口氣:“原來是場噩夢啊……” “哼慎王!你這毒婦竟也來了?” 一聲冷哼從身側響起搔啊,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤柬祠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后负芋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漫蛔,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡嗜愈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了莽龟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蠕嫁。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖毯盈,靈堂內(nèi)的尸體忽然破棺而出剃毒,到底是詐尸還是另有隱情,我是刑警寧澤搂赋,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布赘阀,位于F島的核電站,受9級特大地震影響脑奠,放射性物質(zhì)發(fā)生泄漏基公。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一宋欺、第九天 我趴在偏房一處隱蔽的房頂上張望轰豆。 院中可真熱鬧,春花似錦齿诞、人聲如沸酸休。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斑司。三九已至,卻和暖如春但汞,著一層夾襖步出監(jiān)牢的瞬間陡厘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工特占, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人云茸。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓是目,卻偏偏與公主長得像,于是被迫代替她去往敵國和親标捺。 傳聞我的和親對象是個殘疾皇子懊纳,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容