redis內(nèi)存持久化機(jī)制和淘汰策略使用詳解
1.為什么需要持久化和淘汰策略
在日常使用redis的過(guò)程中,數(shù)據(jù)安全與內(nèi)存管理是必須重點(diǎn)考慮的問(wèn)題。
redis是基于內(nèi)存的數(shù)據(jù)庫(kù),內(nèi)存斷電即失,所以需要持久化保證數(shù)據(jù)安全。
- 持久化:
解決數(shù)據(jù)斷電丟失的問(wèn)題;
redis內(nèi)存有限,但數(shù)據(jù)超出閾值時(shí),需要淘汰策略來(lái)決定哪些數(shù)據(jù)被清理。
- 淘汰策略:
解決內(nèi)存不足時(shí)如何存放新數(shù)據(jù)的問(wèn)題。
2.持久化機(jī)制
redis作為內(nèi)存數(shù)據(jù)庫(kù),如果不做持久化,宕機(jī)后數(shù)據(jù)會(huì)全部丟失,為此redistribution提供了三種持久化方案。
2.1RDB(快照持久化)
原理:周期性將內(nèi)存數(shù)據(jù)快照寫(xiě)入磁盤(pán),生成dump.rdb文件。
觸發(fā)方式
- 配置觸發(fā):
save 900 1 # 900 秒內(nèi)有 1 次寫(xiě)操作則觸發(fā) save 300 10 # 300 秒內(nèi)有 10 次寫(xiě)操作則觸發(fā) save 60 10000 # 60 秒內(nèi)有 10000 次寫(xiě)操作則觸發(fā)
- 手動(dòng)觸發(fā):
SAVE # 阻塞 Redis,生成快照 BGSAVE # 后臺(tái) fork 子進(jìn)程生成快照(推薦)
底層實(shí)現(xiàn)細(xì)節(jié)
BGSAVE 流程
- 主進(jìn)程執(zhí)行 fork,生成子進(jìn)程;
- 子進(jìn)程負(fù)責(zé)將快照寫(xiě)入磁盤(pán)文件;
- 主進(jìn)程繼續(xù)處理客戶(hù)端請(qǐng)求。
寫(xiě)時(shí)復(fù)制(Copy-On-Write, COW)
fork后,父子進(jìn)程共享內(nèi)存頁(yè);
如果有寫(xiě)請(qǐng)求修改數(shù)據(jù),操作系統(tǒng)會(huì)復(fù)制出新內(nèi)存頁(yè):
- 子進(jìn)程使用舊數(shù)據(jù)頁(yè)生成 RDB;
- 主進(jìn)程在新數(shù)據(jù)頁(yè)上繼續(xù)服務(wù)。
- 保證了快照的一致性,同時(shí)不會(huì)阻塞主進(jìn)程。
緩沖區(qū)機(jī)制
- 在快照生成過(guò)程中,新的寫(xiě)操作會(huì)寫(xiě)入 Redis 的正常數(shù)據(jù)結(jié)構(gòu);
- 子進(jìn)程只寫(xiě)fork時(shí)刻的內(nèi)存數(shù)據(jù),不包含之后的新寫(xiě)入;
- 因此,RDB 只反映快照時(shí)刻的數(shù)據(jù),可能丟失最近一次快照之后的數(shù)據(jù)。
優(yōu)點(diǎn):文件體積小,恢復(fù)速度快,適合做全量備份。
缺點(diǎn):最后一次快照之后的數(shù)據(jù)可能會(huì)丟失。
2.2AOF(追加日志)
原理:記錄每條寫(xiě)命令,追加到日志文件 appendonly.aof,Redis 重啟時(shí)重放日志恢復(fù)數(shù)據(jù)。
AOF重寫(xiě):
文件過(guò)大時(shí),redis會(huì)進(jìn)行AOF重寫(xiě):壓縮日志,值保留恢復(fù)當(dāng)前數(shù)據(jù)集的必要命令。
BGREWRITEAOF
使用方式:
- 開(kāi)啟方式
appendonly yes appendfilename "appendonly.aof"
刷盤(pán)策略:
always:每次寫(xiě)操作立即寫(xiě)盤(pán)(最安全,最慢)。everysec:每秒寫(xiě)一次盤(pán)(推薦)。no:完全交由操作系統(tǒng)(可能丟幾秒數(shù)據(jù))。
2.3混合持久化(RDB+AOF)
- 原理:Redis 4.0 引入,將 RDB 快照與增量 AOF 結(jié)合。
- 優(yōu)點(diǎn):RDB提供基線(xiàn)數(shù)據(jù),恢復(fù)快;AOF記錄快照之后的寫(xiě)操作,減少數(shù)據(jù)丟失。
配置:
aof-use-rdb-preamble yes
推薦:生產(chǎn)環(huán)境普遍采用混合持久化。
3.淘汰策略
1. 配置方式
maxmemory 512mb maxmemory-policy allkeys-lru
2. 淘汰策略分類(lèi)
不淘汰:noeviction,直接拒絕寫(xiě)入(默認(rèn))
僅淘汰過(guò)期鍵:
volatile-lru:淘汰最近最少使用的過(guò)期鍵。volatile-ttl:淘汰即將過(guò)期的鍵。volatile-random:隨機(jī)淘汰過(guò)期鍵。volatile-lfu:淘汰訪(fǎng)問(wèn)頻率最低的鍵。
淘汰所有鍵:
allkeys-lru:淘汰最近最少使用的鍵。allkeys-random:隨機(jī)淘汰一個(gè)鍵。allkeys-lfu:淘汰訪(fǎng)問(wèn)頻率最低的鍵。
3. LRU 與 LFU
- LRU:最近最少使用,適合熱點(diǎn)數(shù)據(jù)場(chǎng)景。
- LFU:最少使用頻率,適合長(zhǎng)尾訪(fǎng)問(wèn)場(chǎng)景。
LRU 并不是全局精確淘汰,而是近似算法:
- Redis 不會(huì)掃描所有 key,而是每次 隨機(jī)取出一部分 key(默認(rèn) 5 個(gè),可配置);
- 在采樣的這批 key 中,選擇 最久未使用的一個(gè) 淘汰;
- 如果內(nèi)存還是不足,就繼續(xù)隨機(jī)采樣,直到釋放出足夠的內(nèi)存。
# 默認(rèn)采樣 5 個(gè) key maxmemory-samples 5 # 可以調(diào)大,比如 20,提高淘汰的準(zhǔn)確度,但 CPU 開(kāi)銷(xiāo)也會(huì)增加 maxmemory-samples 20
LFU 需要記錄每個(gè) key 的訪(fǎng)問(wèn)頻率,Redis 使用的是 對(duì)數(shù)遞增計(jì)數(shù)器(log counter),避免計(jì)數(shù)無(wú)限增長(zhǎng)。淘汰機(jī)制類(lèi)似LRU。
# 訪(fǎng)問(wèn)頻率遞減的時(shí)間因子(越大,計(jì)數(shù)越快衰減) lfu-decay-time 1
總結(jié)
持久化
RDB:快照,全量備份,快速恢復(fù),但可能丟數(shù)據(jù);AOF:日志,數(shù)據(jù)更安全,但文件更大;- 混合:結(jié)合兩者優(yōu)點(diǎn),推薦生產(chǎn)使用。
淘汰策略
noeviction:安全,但可能拒絕服務(wù);LRU / LFU:常用,適合緩存業(yè)務(wù);- 選擇合適的策略,避免 OOM。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis模糊查詢(xún)的幾種實(shí)現(xiàn)方法
本文主要介紹了Redis模糊查詢(xún)的幾種實(shí)現(xiàn)方法,包括兩種方法KEYS , SCAN,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02
如何使用redis的stream數(shù)據(jù)類(lèi)型做消息隊(duì)列
Redis 5.0引入Stream數(shù)據(jù)類(lèi)型,支持消費(fèi)者組、分片消費(fèi)和持久化,替代舊版pub/sub實(shí)現(xiàn)更可靠的消息隊(duì)列,適用于訂單處理、日志收集等場(chǎng)景,但需注意內(nèi)存管理和消息補(bǔ)償機(jī)制,本文給大家介紹使用redis的stream數(shù)據(jù)類(lèi)型做消息隊(duì)列的相關(guān)知識(shí),感興趣的朋友一起看看吧2025-06-06
如何利用 Redis 實(shí)現(xiàn)接口頻次限制
這篇文章主要介紹了如何利用 Redis 實(shí)現(xiàn)接口頻次限制,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
Redis筆記點(diǎn)贊排行榜的實(shí)現(xiàn)示例
探店筆記類(lèi)似點(diǎn)評(píng)網(wǎng)站的評(píng)價(jià),本文主要介紹了Redis筆記點(diǎn)贊排行榜的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01

