Redis BGSAVE 內(nèi)存不足異常完美解決方案
Redis BGSAVE 內(nèi)存不足異常完整解決方案
一、問題背景與核心報錯解析
項目無法正常登錄,核心報錯日志如下:
Handling error: RedisPipelineException, Pipeline contained one or more invalid commands; nested exception is io.lettuce.core.RedisCommandExecutionException: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error
Redis 側(cè)補充日志:
WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add ‘vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command ‘sysctl vm.overcommit_memory=1' for this to take effect.
錯誤本質(zhì):
Redis 執(zhí)行 BGSAVE(后臺生成 RDB 快照)時,需要 fork 子進程來處理持久化,但操作系統(tǒng)因內(nèi)存分配策略限制,無法為子進程分配足夠內(nèi)存,導(dǎo)致 RDB 持久化失敗。而 Redis 默認開啟 stop-writes-on-bgsave-error yes,會直接禁用所有寫操作,最終引發(fā)業(yè)務(wù)訪問異常。
二、分階段解決方案
1. 緊急恢復(fù)(治標):臨時解除寫操作限制
適用于生產(chǎn)環(huán)境需快速恢復(fù)業(yè)務(wù)的場景,無需重啟 Redis,但僅解決當(dāng)前訪問問題,未修復(fù)根本原因。
# 進入 Redis 客戶端 redis-cli # 臨時關(guān)閉寫操作限制(重啟 Redis 后失效) 127.0.0.1:6379> config set stop-writes-on-bgsave-error no # 驗證配置生效 127.0.0.1:6379> config get stop-writes-on-bgsave-error
2. 根本修復(fù)(治本):調(diào)整系統(tǒng)內(nèi)存分配策略
修改 vm.overcommit_memory 參數(shù),解決 Redis fork 子進程內(nèi)存分配失敗問題:
# 1. 編輯系統(tǒng)內(nèi)核參數(shù)配置文件 vim /etc/sysctl.conf # 2. 添加/修改如下配置(建議放在文件末尾) vm.overcommit_memory=1 # 3. 使配置立即生效(無需重啟服務(wù)器) sysctl -p # 4. 驗證配置生效 sysctl vm.overcommit_memory # 預(yù)期輸出:vm.overcommit_memory = 1
三、關(guān)鍵參數(shù)深度解析
1. vm.overcommit_memory 三種取值對比
| 取值 | 策略名稱 | 核心邏輯 | 適用場景 | 風(fēng)險點 |
|---|---|---|---|---|
| 0 | 啟發(fā)式策略(默認) | 分配內(nèi)存時,對比「申請的虛擬內(nèi)存」與「空閑物理內(nèi)存+swap」,不足則拒絕 | 普通服務(wù)器、內(nèi)存充足場景 | Redis fork 子進程易失敗,觸發(fā) RDB 持久化報錯 |
| 1 | 允許內(nèi)存超分配 | 直接放行所有內(nèi)存申請,不做校驗 | Redis 服務(wù)器、數(shù)據(jù)庫服務(wù)器 | 極端內(nèi)存不足時觸發(fā)系統(tǒng) OOM 殺進程 |
| 2 | 禁止內(nèi)存超分配 | 內(nèi)存分配上限 = 物理內(nèi)存 × overcommit_ratio(默認50%)+ swap | 對穩(wěn)定性要求極高的核心服務(wù)器 | 動態(tài)創(chuàng)建子進程/申請內(nèi)存易失敗 |
2. Redis stop-writes-on-bgsave-error 參數(shù)
| 取值 | 行為 | 適用場景 |
|---|---|---|
| yes(默認) | RDB 持久化失敗時,禁用所有寫操作 | 數(shù)據(jù)一致性優(yōu)先的場景(如金融、核心業(yè)務(wù)) |
| no | RDB 持久化失敗時,仍允許寫操作 | 可用性優(yōu)先的場景(臨時恢復(fù)) |
四、擴展優(yōu)化建議
- 調(diào)整 Redis 持久化策略
- 若 RDB 頻繁失敗,可降低快照頻率(修改
save參數(shù)),或結(jié)合 AOF 持久化:
- 若 RDB 頻繁失敗,可降低快照頻率(修改
# 示例:關(guān)閉自動 RDB 快照(僅保留手動 BGSAVE) 127.0.0.1:6379> config set save "" # 開啟 AOF 持久化(可靠性更高) 127.0.0.1:6379> config set appendonly yes
- 注意:AOF 需配置合理的刷盤策略(如
appendfsync everysec),平衡性能與可靠性。 - 優(yōu)化 Redis
fork性能fork耗時與 Redis 內(nèi)存使用量正相關(guān),建議限制 Redis 最大內(nèi)存(maxmemory),避免內(nèi)存占用過高:
127.0.0.1:6379> config set maxmemory 4GB 127.0.0.1:6379> config set maxmemory-policy allkeys-lru
開啟 transparent_hugepage 禁用(THP 會增加 fork 耗時):
echo never > /sys/kernel/mm/transparent_hugepage/enabled # 永久生效:添加到 /etc/rc.local
- 監(jiān)控 Redis 持久化狀態(tài)
- 定期檢查 RDB/AOF 持久化狀態(tài),避免問題復(fù)發(fā):
# 查看最后一次 BGSAVE 狀態(tài) 127.0.0.1:6379> info persistence # 關(guān)鍵指標:rdb_last_bgsave_status(成功為 ok)、aof_last_write_status
- 服務(wù)器內(nèi)存規(guī)劃
- Redis
fork子進程時,理論上需要與父進程相同的內(nèi)存空間(實際用寫時復(fù)制),建議服務(wù)器物理內(nèi)存預(yù)留 20% 以上空閑,或配置足夠的 swap 空間。
- Redis
總結(jié)
- 緊急恢復(fù):通過
config set stop-writes-on-bgsave-error no臨時解除 Redis 寫限制,快速恢復(fù)業(yè)務(wù)訪問; - 根本修復(fù):修改系統(tǒng)內(nèi)核參數(shù)
vm.overcommit_memory=1,解決fork子進程內(nèi)存分配失敗問題; - 長期優(yōu)化:結(jié)合調(diào)整 Redis 持久化策略、限制最大內(nèi)存、監(jiān)控持久化狀態(tài),避免問題復(fù)發(fā)。
到此這篇關(guān)于Redis BGSAVE 內(nèi)存不足異常完整解決方案的文章就介紹到這了,更多相關(guān)redis bgsave內(nèi)存不足異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redisson分布式限流器RRateLimiter的使用及原理小結(jié)
本文主要介紹了Redisson分布式限流器RRateLimiter的使用及原理小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06
redis持久化AOF和RDB的區(qū)別及解決各個場景問題示例
這篇文章主要為大家介紹了redis持久化AOF和RDB的區(qū)別及解決各個場景問題示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
關(guān)于Redis數(shù)據(jù)庫三種持久化方案介紹
大家好,本篇文章主要講的是關(guān)于Redis數(shù)據(jù)庫三種持久化方案介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-01-01
Redis設(shè)置密碼以及設(shè)置后不生效的解決過程
這段描述主要講解了如何修改Redis配置文件以設(shè)置自定義密碼,并強調(diào)了在啟動Redis時需使用配置文件的重要性,通過修改`redis.windows.conf`中的`requirepass`參數(shù)并重啟Redis服務(wù),可以實現(xiàn)自定義密碼設(shè)置2026-05-05
利用Redis統(tǒng)計網(wǎng)站在線活躍用戶的方法
Redis支持對String類型的value進行基于二進制位的置位操作。通過將一個用戶的id對應(yīng)value上的一位,通過對活躍用戶對應(yīng)的位進行置位,就能夠用一個value記錄所有活躍用戶的信息。下面這篇文章主要介紹了利用Redis統(tǒng)計網(wǎng)站在線活躍用戶的方法,需要的朋友可以參考。2017-01-01

