91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis持久化時內存不足怎么處理

發布時間:2021-06-29 14:39:28 來源:億速云 閱讀:1153 作者:chen 欄目:編程語言

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

問題描述

# 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持久化過程中出現問題,Redis不允許用戶進行任何更新操作;即:stop-writes-on-bgsave-error yes

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

問題分析

Redis數據回寫機制

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

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

  • Redis的數據回寫機制分同步和異步兩種,

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

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

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

系統內存分配策略

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

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

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

OOM killer會選擇殺死一些進程,以便釋放內存。當發生OOM killer時,會記錄在系統日志中/var/log/messages

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

  • Linux下有個vm內核參數:CommitLimit用于限制系統應用使用的內存資源;執行grep -i commit /proc/meminfo,看到CommitLimitCommitted_As參數。

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

    • Committed_As是已經分配的內存大小(應用程序要申請的內存 + 系統已經分配的內存)。

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

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

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

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

解決方案

修改系統內存分配策略

我們可以通過設置overcommit_memory=1的優化,減少操作系統內存,提高Redisfork成功率,因為fork后的進程和父進程共享一個數據空間,持久化要新增的內存空間都會小于父進程已經使用的空間,具體有三種方式修改內核參數,但要有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子進程后,占用內存大小和父進程等同,由于Linux在寫時有copy-on-write機制,父子進程共享相同的物理內存頁,當父進程處理寫請求的時候會把要修改的頁創建副本,而子進程在fork過程中共享整個父進程的內存快照。如果我們要減少創建的副本的大小,就涉及操作系統的另外一個概念Huge Pages(大頁)。

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

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

  • 參考文章:

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

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

到此,相信大家對“Redis持久化時內存不足怎么處理”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南召县| 阿尔山市| 龙川县| 泾源县| 内丘县| 兴隆县| 台北市| 江永县| 依安县| 波密县| 沈丘县| 大同市| 江油市| 固安县| 博爱县| 榆林市| 大丰市| 高州市| 永吉县| 宁波市| 平果县| 油尖旺区| 阿拉善左旗| 海南省| 上林县| 皋兰县| 香河县| 嘉兴市| 庆云县| 六安市| 胶南市| 金沙县| 荥阳市| 卢湾区| 涿州市| 西乡县| 齐河县| 陇南市| 沾化县| 图木舒克市| 台州市|