一篇主要針對Redis的內(nèi)存淘汰機制以及Redis容易引發(fā)的三大問題:緩存擊穿、緩存穿透以及緩存雪崩進行了詳細的講解以及提供了業(yè)界常用的解決方案。本篇主要講講Redis的持久化機制,Redis受開發(fā)者歡迎的一大原因就是因為可持久化的特性。我們?nèi)绾伪WCRedis宕機之后重啟可以將數(shù)據(jù)進行恢復(fù)?所以一般情況下我們需要定時進行持久化將內(nèi)存中的數(shù)據(jù)寫入到硬盤中。而Redis中支持兩種不同的持久化機制:RDB持久化以及AOF持久化。

快照持久化是一次全量備份,備份的是內(nèi)存數(shù)據(jù)的二進制序列化格式。而AOF持久化是增量備份,記錄的是內(nèi)存數(shù)據(jù)修改的指令記錄文本。所以AOF持久化生成的日志會隨著運行時間變長而變得越來越臃腫,每次重啟Redis都需要加載AOF日志進行指令重放,所以需要定期重寫AOF日志進行瘦身操作。
快照持久化(RDB)
RDB持久化是指在指定的時間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫入磁盤,實際操作過程是fork一個子進程,子進程負責(zé)將數(shù)據(jù)集寫入臨時文件由于os的寫時復(fù)制機制父子進程會共享相同的物理界面,當(dāng)父進程處理寫請求時os會為父進程創(chuàng)建頁面副本,所以紫禁城地址空間的數(shù)據(jù)實際上就是一個快照,寫入成功后,再替換之前的文件,用二進制壓縮存儲。RDB是Redis默認的持久化方式,會在對應(yīng)的目錄下生產(chǎn)一個dump.rdb文件,重啟會通過加載dump.rdb文件恢復(fù)數(shù)據(jù)。Redis使用操作系統(tǒng)的多進程COW機制實現(xiàn)RDB持久化。
優(yōu)點:
- 只有一個備份文件dump.rdb,方便持久化備份;
- 容災(zāi)性好,一個文件可以保存到其他存儲介質(zhì);
- 性能最大化,fork出子進程來完成寫操作,讓主進程繼續(xù)處理命令,所以是IO最大化(使用單獨子進程來進行持久化,主進程不會進行任何IO操作,保證了redis的高性能) ;
- 如果數(shù)據(jù)集偏大,RDB的啟動效率會比AOF更高。
缺點:
- 數(shù)據(jù)安全性低。
- 如果當(dāng)數(shù)據(jù)集較大時,可能會導(dǎo)致整個服務(wù)器停止服務(wù)。
RDB持久化是 Redis 默認采用的持久化方式,可以在 redis.conf 配置文件中進行配置Redis在N秒內(nèi)如果超過M個key被修改就自動做快照:
- save 900 1:在15分鐘內(nèi),如果至少有1個key發(fā)生變化,Redis就會自動觸發(fā)BGSAVE命令創(chuàng)建快照。
- save 300 10:在5分鐘內(nèi),如果至少有10個key發(fā)生變化,Redis就會自動觸發(fā)BGSAVE命令創(chuàng)建快照。
- save 60 10000:在1分鐘之后,如果至少有10000個key發(fā)生變化,Redis就會自動觸發(fā)BGSAVE命令創(chuàng)建快照。
AOF持久化
AOF持久化是以日志的形式記錄每一個增刪操作,會將所有增刪操作通過write函數(shù)追加到文件中。AOF的出現(xiàn)是為了彌補RDB的不足(數(shù)據(jù)的不一致性),所以它采用日志的形式來記錄每個寫操作,并追加到文件中。Redis 重啟會通過執(zhí)行文件中保存的寫命令在內(nèi)存中重建整個數(shù)據(jù)庫的內(nèi)容。與快照持久化相比,AOF 持久化的實時性更好,因此已成為主流的持久化方案。 默認情況下 Redis 沒有開啟 AOF持久化,可以通過設(shè)置 appendonly 參數(shù)開啟:
- appendonly yes
Redis通過fork出子進程,子進程根據(jù)內(nèi)存中的快照,往臨時文件中寫入重建數(shù)據(jù)庫狀態(tài)的指令,父進程繼續(xù)處理請求,當(dāng)子進程將快照內(nèi)容寫入到臨時文件中則發(fā)信號通知父進程將緩存中的寫操作也寫入到臨時文件中,最后使用臨時文件替代舊備份文件并進行重命名。AOF 文件的保存位置和 RDB 文件的位置相同,都是通過 dir 參數(shù)設(shè)置的,默認的文件名是 appendonly.aof。在 Redis 的配置文件中存在三種不同的 AOF 持久化方式,它們分別是:
- appendfsync always:每次有數(shù)據(jù)修改發(fā)生時都會寫入AOF文件
- appendfsync everysec:每秒鐘同步一次,將多個寫命令同步到硬盤
- appendfsync no:讓操作系統(tǒng)決定何時進行同步
用戶可以使用appendfsync everysec選項 ,讓 Redis 每秒同步一次 AOF 文件,這樣Redis性能幾乎不會受到影響,而且這樣即使出現(xiàn)宕機,用戶最多只會丟失一秒之內(nèi)產(chǎn)生的數(shù)據(jù)。當(dāng)硬盤忙于執(zhí)行寫入操作的時候,Redis 還會優(yōu)雅的放慢自己的速度以便適應(yīng)硬盤的最大寫入速度。
優(yōu)點:
- 數(shù)據(jù)安全性更高,AOF持久化可以配置appendfsync屬性
- 通過append模式寫文件,即使中途服務(wù)器宕機,可以通過redis-check-aof工具解決數(shù)據(jù)一致性問題。
- AOF機制的rewrite模式。
缺點:
- AOF文件比RDB文件大,且恢復(fù)速度慢;
- 數(shù)據(jù)集大的時候,比RDB啟動效率低。
- 根據(jù)同步策略的不同,AOF在運行效率上往往會慢于RDB。
對于Redis的兩種持久化機制的選擇,主要還是得針對特定的系統(tǒng)討論,看是可以犧牲一定的性能使用AOF持久化換取緩存一致性,還是在增刪操作頻繁時關(guān)閉備份,等到Redis空閑手動save做RDB持久化備份。所以其實最佳方案應(yīng)該是采用混合持久化方案,開啟混合持久化后,AOF重寫日志時會將RDB持久化的內(nèi)容寫到AOF文件開頭,于是在Redis重啟時,可以先加載RDB的內(nèi)容,再對增量的AOF日志進行重放,提升Redis重啟的效率。
原文連接:https://segmentfault.com/a/1190000020653415