redis內存持久化機制和淘汰策略使用詳解
1.為什么需要持久化和淘汰策略
在日常使用redis的過程中,數據安全與內存管理是必須重點考慮的問題。
redis是基于內存的數據庫,內存斷電即失,所以需要持久化保證數據安全。
- 持久化:
解決數據斷電丟失的問題;
redis內存有限,但數據超出閾值時,需要淘汰策略來決定哪些數據被清理。
- 淘汰策略:
解決內存不足時如何存放新數據的問題。
2.持久化機制
redis作為內存數據庫,如果不做持久化,宕機后數據會全部丟失,為此redistribution提供了三種持久化方案。
2.1RDB(快照持久化)
原理:周期性將內存數據快照寫入磁盤,生成dump.rdb文件。
觸發(fā)方式
- 配置觸發(fā):
save 900 1 # 900 秒內有 1 次寫操作則觸發(fā) save 300 10 # 300 秒內有 10 次寫操作則觸發(fā) save 60 10000 # 60 秒內有 10000 次寫操作則觸發(fā)
- 手動觸發(fā):
SAVE # 阻塞 Redis,生成快照 BGSAVE # 后臺 fork 子進程生成快照(推薦)
底層實現細節(jié)
BGSAVE 流程
- 主進程執(zhí)行 fork,生成子進程;
- 子進程負責將快照寫入磁盤文件;
- 主進程繼續(xù)處理客戶端請求。
寫時復制(Copy-On-Write, COW)
fork后,父子進程共享內存頁;
如果有寫請求修改數據,操作系統會復制出新內存頁:
- 子進程使用舊數據頁生成 RDB;
- 主進程在新數據頁上繼續(xù)服務。
- 保證了快照的一致性,同時不會阻塞主進程。
緩沖區(qū)機制
- 在快照生成過程中,新的寫操作會寫入 Redis 的正常數據結構;
- 子進程只寫fork時刻的內存數據,不包含之后的新寫入;
- 因此,RDB 只反映快照時刻的數據,可能丟失最近一次快照之后的數據。
優(yōu)點:文件體積小,恢復速度快,適合做全量備份。
缺點:最后一次快照之后的數據可能會丟失。
2.2AOF(追加日志)
原理:記錄每條寫命令,追加到日志文件 appendonly.aof,Redis 重啟時重放日志恢復數據。
AOF重寫:
文件過大時,redis會進行AOF重寫:壓縮日志,值保留恢復當前數據集的必要命令。
BGREWRITEAOF
使用方式:
- 開啟方式
appendonly yes appendfilename "appendonly.aof"
刷盤策略:
always:每次寫操作立即寫盤(最安全,最慢)。everysec:每秒寫一次盤(推薦)。no:完全交由操作系統(可能丟幾秒數據)。
2.3混合持久化(RDB+AOF)
- 原理:Redis 4.0 引入,將 RDB 快照與增量 AOF 結合。
- 優(yōu)點:RDB提供基線數據,恢復快;AOF記錄快照之后的寫操作,減少數據丟失。
配置:
aof-use-rdb-preamble yes
推薦:生產環(huán)境普遍采用混合持久化。
3.淘汰策略
1. 配置方式
maxmemory 512mb maxmemory-policy allkeys-lru
2. 淘汰策略分類
不淘汰:noeviction,直接拒絕寫入(默認)
僅淘汰過期鍵:
volatile-lru:淘汰最近最少使用的過期鍵。volatile-ttl:淘汰即將過期的鍵。volatile-random:隨機淘汰過期鍵。volatile-lfu:淘汰訪問頻率最低的鍵。
淘汰所有鍵:
allkeys-lru:淘汰最近最少使用的鍵。allkeys-random:隨機淘汰一個鍵。allkeys-lfu:淘汰訪問頻率最低的鍵。
3. LRU 與 LFU
- LRU:最近最少使用,適合熱點數據場景。
- LFU:最少使用頻率,適合長尾訪問場景。
LRU 并不是全局精確淘汰,而是近似算法:
- Redis 不會掃描所有 key,而是每次 隨機取出一部分 key(默認 5 個,可配置);
- 在采樣的這批 key 中,選擇 最久未使用的一個 淘汰;
- 如果內存還是不足,就繼續(xù)隨機采樣,直到釋放出足夠的內存。
# 默認采樣 5 個 key maxmemory-samples 5 # 可以調大,比如 20,提高淘汰的準確度,但 CPU 開銷也會增加 maxmemory-samples 20
LFU 需要記錄每個 key 的訪問頻率,Redis 使用的是 對數遞增計數器(log counter),避免計數無限增長。淘汰機制類似LRU。
# 訪問頻率遞減的時間因子(越大,計數越快衰減) lfu-decay-time 1
總結
持久化
RDB:快照,全量備份,快速恢復,但可能丟數據;AOF:日志,數據更安全,但文件更大;- 混合:結合兩者優(yōu)點,推薦生產使用。
淘汰策略
noeviction:安全,但可能拒絕服務;LRU / LFU:常用,適合緩存業(yè)務;- 選擇合適的策略,避免 OOM。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

