成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Redis持久化時內(nèi)存不足怎么處理

本篇內(nèi)容主要講解“redis持久化時內(nèi)存不足怎么處理”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Redis持久化時內(nèi)存不足怎么處理”吧!

超過10余年行業(yè)經(jīng)驗,技術領先,服務至上的經(jīng)營模式,全靠網(wǎng)絡和口碑獲得客戶,為自己降低成本,也就是為客戶降低成本。到目前業(yè)務范圍包括了:成都網(wǎng)站制作、成都網(wǎng)站建設,成都網(wǎng)站推廣,成都網(wǎng)站優(yōu)化,整體網(wǎng)絡托管,重慶小程序開發(fā),微信開發(fā),app軟件開發(fā),同時也可以讓客戶的網(wǎng)站和網(wǎng)絡營銷和我們一樣獲得訂單和生意!

問題描述

# Java錯誤日志:
redis.clients.jedis.exceptions.JedisDataException: MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.

# Redis錯誤日志:
Can't save in background: fork: Resource temporaily unavailable
# 或
Can’t save in background: fork: Cannot allocate memory

Redis在個默認情況下,如果在RDB snapshots持久化過程中出現(xiàn)問題,Redis不允許用戶進行任何更新操作;即:stop-writes-on-bgsave-error yes

臨時解決方案是通過命令:config set stop-writes-on-bgsave-error no 設置這個選項為false,讓程序忽略了這個異常,使得程序能夠繼續(xù)往下運行,但寫硬盤仍然是失敗的!

問題分析

Redis數(shù)據(jù)回寫機制

Redis在進行持久化的時候,有的時候可以在日志中看到fork進程失敗的提示,一般是系統(tǒng)可用的內(nèi)存空間不夠導致,這需要我們對fork原理明白,才能更好的進行參數(shù)調整。

一般來說Redis在進行RDB的時候,會fork出一個子進程,子進程和父進程會共享一個地址空間,在fork子進程的時候,會檢查當前機器可用的內(nèi)存是否滿足fork出一個子進程的要求,一般由操作系統(tǒng)overcommit_memory(系統(tǒng)內(nèi)存分配策略)決定。

  • Redis的數(shù)據(jù)回寫機制分同步和異步兩種,

    • 同步回寫即SAVE命令,主進程直接向磁盤回寫數(shù)據(jù)。在數(shù)據(jù)大的情況下會導致系統(tǒng)假死很長時間,所以一般不是推薦的。

    • 異步回寫即BGSAVE命令,主進程fork后,復制自身并通過這個新的進程回寫磁盤,回寫結束后新進程自行關閉。由于這樣做不需要主進程阻塞,系統(tǒng)不會假死,一般默認會采用這個方法。

Redis默認采用異步回寫,所以如果我們要將數(shù)據(jù)刷到硬盤上,這時Redis分配內(nèi)存不能太大,否則很容易發(fā)生內(nèi)存不夠用無法fork的問題; 設置一個合理的寫磁盤策略,否則寫頻繁的應用,也會導致頻繁的fork操作,對于占用了大內(nèi)存的Redis來說,fork消耗資源的代價是很大的;

系統(tǒng)內(nèi)存分配策略

Linux對大部分申請內(nèi)存的請求都回復yes,以便能跑更多更大的程序。

因為申請內(nèi)存后,并不會馬上使用內(nèi)存,將這些不會使用的空閑內(nèi)存分配給其它程序使用,以提高內(nèi)存利用率,這種技術叫做Overcommit

一般情況下,當所有程序都不會用到自己申請的所有內(nèi)存時,系統(tǒng)不會出問題,但是如果程序隨著運行,需要的內(nèi)存越來越大,在自己申請的大小范圍內(nèi),不斷占用更多內(nèi)存,直到超出物理內(nèi)存,當Linux發(fā)現(xiàn)內(nèi)存不足時,會發(fā)生OOM killer(OOM=out-of-memory)。

OOM killer會選擇殺死一些進程,以便釋放內(nèi)存。當發(fā)生OOM killer時,會記錄在系統(tǒng)日志中/var/log/messages

用戶態(tài)進程,非內(nèi)核線程,占用內(nèi)存越多和運行時間越短的進程越有可能被殺掉。

  • Linux下有個vm內(nèi)核參數(shù):CommitLimit用于限制系統(tǒng)應用使用的內(nèi)存資源;執(zhí)行grep -i commit /proc/meminfo,看到CommitLimitCommitted_As參數(shù)。

    • CommitLimit是一個內(nèi)存分配上限,CommitLimit = 物理內(nèi)存 * overcommit_ratio(/proc/sys/vm/overcmmit_ratio,默認50,即50%) + swap大小

    • Committed_As是已經(jīng)分配的內(nèi)存大小(應用程序要申請的內(nèi)存 + 系統(tǒng)已經(jīng)分配的內(nèi)存)。

  • vm.overcommit_memory文件指定了內(nèi)核針對內(nèi)存分配的策略,其值可以是0、1、2。

    • 0:啟發(fā)策略(默認);表示內(nèi)核將檢查是否有足夠的可用內(nèi)存供應用進程使用;如果有足夠的可用內(nèi)存,內(nèi)存申請允許;否則,內(nèi)存申請失敗,并把錯誤返回給應用進程。系統(tǒng)在為應用進程分配虛擬地址空間時,會判斷當前申請的虛擬地址空間大小是否超過剩余內(nèi)存大小,如果超過,則虛擬地址空間分配失敗。因此,也就是如果進程本身占用的虛擬地址空間比較大或者剩余內(nèi)存比較小時,fork、malloc等調用可能會失敗。 0即是啟發(fā)式的overcommitting handle,會盡量減少swap交換分區(qū)的使用,root可以分配比一般用戶略多的內(nèi)存。

    • 1:允許overcommit;表示內(nèi)核允許分配所有的物理內(nèi)存,而不管當前的內(nèi)存狀態(tài)如何,允許超過CommitLimit,這種情況下,避免了fork可能產(chǎn)生的失敗,但由于malloc是先分配虛擬地址空間,而后通過異常陷入內(nèi)核分配真正的物理內(nèi)存,在內(nèi)存不足的情況下,這相當于完全屏蔽了應用進程對系統(tǒng)內(nèi)存狀態(tài)的感知,即malloc總是能成功,一旦內(nèi)存不足,會引起系統(tǒng)OOM殺進程,應用程序對于這種后果是無法預測的。 直至內(nèi)存用完為止。在數(shù)據(jù)庫服務器上不建議設置為1,從而盡量避免使用swap交換分區(qū)。

    • 2:禁止overcommit;表示不允許超過CommitLimit值。由于很多情況下,進程的虛擬地址空間占用遠大于其實際占用的物理內(nèi)存,這樣一旦內(nèi)存使用量上去以后,對于一些動態(tài)產(chǎn)生的進程(需要復制父進程地址空間)則很容易創(chuàng)建失敗,如果業(yè)務過程沒有過多的這種動態(tài)申請內(nèi)存或者創(chuàng)建子進程,則影響不大,否則會產(chǎn)生比較大的影響 。這種情況下系統(tǒng)所能分配的內(nèi)存不會超過上面提到的CommitLimit大小,如果這么多資源已經(jīng)用光,那么后面任何嘗試申請內(nèi)存的行為都會返回錯誤,這通常意味著此時沒法運行任何新程序。

解決方案

修改系統(tǒng)內(nèi)存分配策略

我們可以通過設置overcommit_memory=1的優(yōu)化,減少操作系統(tǒng)內(nèi)存,提高Redisfork成功率,因為fork后的進程和父進程共享一個數(shù)據(jù)空間,持久化要新增的內(nèi)存空間都會小于父進程已經(jīng)使用的空間,具體有三種方式修改內(nèi)核參數(shù),但要有root權限:

  1. 編輯/etc/sysctl.conf ,改vm.overcommit_memory=1,然后sysctl -p使配置文件生效;

  2. 命令:sysctl vm.overcommit_memory=1 ;

  3. 命令:echo 1 > /proc/sys/vm/overcommit_memory

關閉THP(Transparent Huge Pages)

Redis持久化fork子進程后,占用內(nèi)存大小和父進程等同,由于Linux在寫時有copy-on-write機制,父子進程共享相同的物理內(nèi)存頁,當父進程處理寫請求的時候會把要修改的頁創(chuàng)建副本,而子進程在fork過程中共享整個父進程的內(nèi)存快照。如果我們要減少創(chuàng)建的副本的大小,就涉及操作系統(tǒng)的另外一個概念Huge Pages(大頁)。

Redhat Linux中,內(nèi)存都是以頁的形式劃分的,默認情況下每頁是4K,這就意味著如果物理內(nèi)存很大,則映射表的條目將會非常多,會影響CPU的檢索效率。因為內(nèi)存大小是固定的,為了減少映射表的條目,可采取的辦法只有增加頁的尺寸。Linux Kernel2.6.38內(nèi)核中增加了THP(Transparent Huge Pages)的特性,支持大內(nèi)存頁(2MB)分配,默認開啟。當開啟后可以加快fork子進程的速度,但fork操作之后,每個內(nèi)存頁從原來的4KB變成了2MB,會大幅增加重寫期間父進程內(nèi)存消耗,同時每次寫命令引起的復制內(nèi)存頁單位放大了512倍,會拖慢寫操作的執(zhí)行時間,因此在使用Redis的時候Redis建議關閉THP,方法為:echo never > /sys/kernel/mm/transparent_hugepage/enabled。為了讓機器重啟該參數(shù)仍然生效,建議在/etc/rc.local中追加echo never > /sys/kernel/mm/transparent_hugepage/enabled,避免失效。當大頁被關閉后,可以看到同等操作下,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)存為Redis2倍,但是在vm.overcommit_memory=1大頁關閉的情況下,可以根據(jù)實際使用,降低操作系統(tǒng)的整個內(nèi)存大小 。

  • 參考文章:

    • https://www.jianshu.com/p/785ee3bea266

    • https://www.cnblogs.com/wjoyxt/p/3777042.html

到此,相信大家對“Redis持久化時內(nèi)存不足怎么處理”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關內(nèi)容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

網(wǎng)頁名稱:Redis持久化時內(nèi)存不足怎么處理
網(wǎng)頁鏈接:http://jinyejixie.com/article16/ggsddg.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供虛擬主機、全網(wǎng)營銷推廣、網(wǎng)站制作App開發(fā)、電子商務、軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設計
三明市| 神农架林区| 井陉县| 进贤县| 秦皇岛市| 凤冈县| 邵阳县| 宁武县| 武定县| 维西| 思南县| 云梦县| 潮安县| 奉新县| 平顶山市| 巍山| 金门县| 沧州市| 兴义市| 阜新| 吉首市| 丁青县| 葵青区| 濉溪县| 龙川县| 英德市| 防城港市| 安宁市| 循化| 博野县| 巩义市| 南昌市| 土默特右旗| 南华县| 灵璧县| 石狮市| 康乐县| 景东| 河南省| 南郑县| 巫山县|