詳解 Redis 內(nèi)存淘汰機制和持久化機制原理 剖析Redis必備!
概述
前段時間有朋友問了關(guān)于Redis 內(nèi)存淘汰機制和持久化機制原理,今天抽空整理了下分享給大家,內(nèi)容如下:
- Redis 內(nèi)存淘汰機制
- Redis 持久化機制(怎么保證 Redis 掛掉之后再重啟數(shù)據(jù)可以進(jìn)行恢復(fù))
Redis 內(nèi)存淘汰機制
假設(shè)生產(chǎn)環(huán)境里面MySQL 數(shù)據(jù)庫有 1000w 數(shù)據(jù),Redis 中只存 10w 的數(shù)據(jù),如何保證 Redis 中的數(shù)據(jù)都是熱點數(shù)據(jù)?
Redis 提供 6 種數(shù)據(jù)淘汰策略:
- volatile-lru:從已設(shè)置過期時間的數(shù)據(jù)集(server.db[i].expires)中挑選最近最少使用的數(shù)據(jù)淘汰。
- volatile-ttl:從已設(shè)置過期時間的數(shù)據(jù)集(server.db[i].expires)中挑選將要過期的數(shù)據(jù)淘汰。
- volatile-random:從已設(shè)置過期時間的數(shù)據(jù)集(server.db[i].expires)中任意選擇數(shù)據(jù)淘汰。
- allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時,在鍵空間中,移除最近最少使用的key(這個是最常用的)。
- allkeys-random:從數(shù)據(jù)集(server.db[i].dict)中任意選擇數(shù)據(jù)淘汰。
- no-enviction:禁止驅(qū)逐數(shù)據(jù),也就是說當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時,新寫入操作會報錯。這個應(yīng)該沒人使用吧!
通過這 6 種數(shù)據(jù)淘汰策略redis來保證Redis 中的數(shù)據(jù)都是熱點數(shù)據(jù)
Redis 持久化機制
很多時候我們總會碰到服務(wù)器掛掉或者不小心殺了進(jìn)程之類的情況,那么怎么保證 Redis 掛掉之后再重啟數(shù)據(jù)可以進(jìn)行恢復(fù)?
實際上我們只需要持久化數(shù)據(jù)也就是將內(nèi)存中的數(shù)據(jù)寫入到硬盤里面。
大部分原因是為了之后重用數(shù)據(jù)(比如重啟機器、機器故障之后恢復(fù)數(shù)據(jù)),或者是為了防止系統(tǒng)故障而將數(shù)據(jù)備份到一個遠(yuǎn)程位置。
Redis 不同于 Memcached 的很重要一點就是,Redis 支持持久化,而且支持兩種不同的持久化操作。
Redis 的一種持久化方式叫快照(snapshotting,RDB),另一種方式是只追加文件(append-only file,AOF)。
下面講下這兩種持久化方式。
快照(snapshotting)持久化(RDB)
Redis 可以通過創(chuàng)建快照來獲得存儲在內(nèi)存里面的數(shù)據(jù)在某個時間點上的副本。
Redis 創(chuàng)建快照之后,可以對快照進(jìn)行備份,可以將快照復(fù)制到其他服務(wù)器從而創(chuàng)建具有相同數(shù)據(jù)的服務(wù)器副本(Redis 主從結(jié)構(gòu),主要用來提高 Redis 性能),還可以將快照留在原地以便重啟服務(wù)器的時候使用。
快照持久化是 Redis 默認(rèn)采用的持久化方式,在 redis.conf 配置文件中默認(rèn)有此下配置:
save 900 1 #在900秒(15分鐘)之后,如果至少有1個key發(fā)生變化,Redis就會自動觸發(fā)BGSAVE命令創(chuàng)建快照。 save 300 10 #在300秒(5分鐘)之后,如果至少有10個key發(fā)生變化,Redis就會自動觸發(fā)BGSAVE命令創(chuàng)建快照。 save 60 10000 #在60秒(1分鐘)之后,如果至少有10000個key發(fā)生變化,Redis就會自動觸發(fā)BGSAVE命令創(chuàng)建快照。
AOF(append-only file)持久化
與快照持久化相比,AOF 持久化的實時性更好,因此已成為主流的持久化方案。
默認(rèn)情況下 Redis 沒有開啟 AOF(append only file)方式的持久化,可以通過 appendonly 參數(shù)開啟:
- appendonly yes
開啟 AOF 持久化后每執(zhí)行一條會更改 Redis 中的數(shù)據(jù)的命令,Redis 就會將該命令寫入硬盤中的 AOF 文件。
AOF 文件的保存位置和 RDB 文件的位置相同,都是通過 dir 參數(shù)設(shè)置的,默認(rèn)的文件名是 appendonly.aof。
在 Redis 的配置文件中存在三種不同的 AOF 持久化方式,它們分別是:
- appendfsync always #每次有數(shù)據(jù)修改發(fā)生時都會寫入AOF文件,這樣會嚴(yán)重降低Redis的速度
- appendfsync everysec #每秒鐘同步一次,顯示地將多個寫命令同步到硬盤
- appendfsync no #讓操作系統(tǒng)決定何時進(jìn)行同步
為了兼顧數(shù)據(jù)和寫入性能,用戶可以考慮 appendfsync everysec 選項 ,讓 Redis 每秒同步一次 AOF 文件,Redis 性能幾乎沒受到任何影響。
而且這樣即使出現(xiàn)系統(tǒng)崩潰,用戶最多只會丟失一秒之內(nèi)產(chǎn)生的數(shù)據(jù)。當(dāng)硬盤忙于執(zhí)行寫入操作的時候,Redis 還會優(yōu)雅的放慢自己的速度以便適應(yīng)硬盤的最大寫入速度。
Redis 4.0 對于持久化機制的優(yōu)化
Redis 4.0 開始支持 RDB 和 AOF 的混合持久化(默認(rèn)關(guān)閉,可以通過配置項 aof-use-rdb-preamble 開啟)。
如果把混合持久化打開,AOF 重寫的時候就直接把 RDB 的內(nèi)容寫到 AOF 文件開頭。
這樣做的好處是可以結(jié)合 RDB 和 AOF 的優(yōu)點, 快速加載同時避免丟失過多的數(shù)據(jù)。
當(dāng)然缺點也是有的,AOF 里面的 RDB 部分是壓縮格式不再是 AOF 格式,可讀性較差。