Redis 持久化有哪幾種方式,怎么選?
前言
大家好,我是程序員田螺。今天給大家分享一道經(jīng)典面試題:Redis 持久化有哪幾種方式,怎么選?
- AOF持久化
- RDB持久化
- AOF和RDB如何選擇
1 AOF 持久化
Redis是基于內(nèi)存的,如果Redis服務(wù)器掛了,數(shù)據(jù)就會(huì)丟失。為了避免數(shù)據(jù)丟失了,Redis提供了兩種持久化方式,RDB和AOF。我們先來介紹AOF。
AOF(append only file) 持久化,采用日志的形式來記錄每個(gè)寫操作,追加到AOF文件的末尾。Redis默認(rèn)情況是不開啟AOF的。重啟時(shí)再重新執(zhí)行AOF文件中的命令來恢復(fù)數(shù)據(jù)。它主要解決數(shù)據(jù)持久化的實(shí)時(shí)性問題。
AOF是執(zhí)行完命令后才記錄日志的。為什么不先記錄日志再執(zhí)行命令呢?這是因?yàn)镽edis在向AOF記錄日志時(shí),不會(huì)先對(duì)這些命令進(jìn)行語法檢查,如果先記錄日志再執(zhí)行命令,日志中可能記錄了錯(cuò)誤的命令,Redis使用日志回復(fù)數(shù)據(jù)時(shí),可能會(huì)出錯(cuò)。
正是因?yàn)閳?zhí)行完命令后才記錄日志,所以不會(huì)阻塞當(dāng)前的寫操作。但是會(huì)存在兩個(gè)風(fēng)險(xiǎn):
- 更執(zhí)行完命令還沒記錄日志時(shí),宕機(jī)了會(huì)導(dǎo)致數(shù)據(jù)丟失
- AOF不會(huì)阻塞當(dāng)前命令,但是可能會(huì)阻塞下一個(gè)操作。
這兩個(gè)風(fēng)險(xiǎn)最好的解決方案是折中妙用AOF機(jī)制的三種寫回策略 appendfsync:
- always,同步寫回,每個(gè)子命令執(zhí)行完,都立即將日志寫回磁盤。
- everysec,每個(gè)命令執(zhí)行完,只是先把日志寫到AOF內(nèi)存緩沖區(qū),每隔一秒同步到磁盤。
- no:只是先把日志寫到AOF內(nèi)存緩沖區(qū),有操作系統(tǒng)去決定何時(shí)寫入磁盤。
always同步寫回,可以基本保證數(shù)據(jù)不丟失,no策略則性能高但是數(shù)據(jù)可能會(huì)丟失,一般可以考慮折中選擇everysec。
如果接受的命令越來越多,AOF文件也會(huì)越來越大,文件過大還是會(huì)帶來性能問題。日志文件過大怎么辦呢?AOF重寫機(jī)制!就是隨著時(shí)間推移,AOF文件會(huì)有一些冗余的命令如:無效命令、過期數(shù)據(jù)的命令等等,AOF重寫機(jī)制就是把它們合并為一個(gè)命令(類似批處理命令),從而達(dá)到精簡(jiǎn)壓縮空間的目的。
AOF重寫會(huì)阻塞嘛?AOF日志是由主線程會(huì)寫的,而重寫則不一樣,重寫過程是由后臺(tái)子進(jìn)程bgrewriteaof完成。
- AOF的優(yōu)點(diǎn):數(shù)據(jù)的一致性和完整性更高,秒級(jí)數(shù)據(jù)丟失。
- 缺點(diǎn):相同的數(shù)據(jù)集,AOF文件體積大于RDB文件。數(shù)據(jù)恢復(fù)也比較慢。
2 RDB持久化
因?yàn)锳OF持久化方式,如果操作日志非常多的話,Redis恢復(fù)就很慢。有沒有在宕機(jī)快速恢復(fù)的方法呢,有的,RDB!
RDB,就是把內(nèi)存數(shù)據(jù)以快照的形式保存到磁盤上。和AOF相比,它記錄的是某一時(shí)刻的數(shù)據(jù),,并不是操作。
什么是快照?可以這樣理解,給當(dāng)前時(shí)刻的數(shù)據(jù),拍一張照片,然后保存下來。
RDB持久化,是指在指定的時(shí)間間隔內(nèi),執(zhí)行指定次數(shù)的寫操作,將內(nèi)存中的數(shù)據(jù)集快照寫入磁盤中,它是Redis默認(rèn)的持久化方式。執(zhí)行完操作后,在指定目錄下會(huì)生成一個(gè)dump.rdb文件,Redis 重啟的時(shí)候,通過加載dump.rdb文件來恢復(fù)數(shù)據(jù)。RDB觸發(fā)機(jī)制主要有以下幾種:
圖片
RDB通過bgsave命令的執(zhí)行全量快照,可以避免阻塞主線程。basave命令會(huì)fork一個(gè)子進(jìn)程,然后該子進(jìn)程會(huì)負(fù)責(zé)創(chuàng)建RDB文件,而服務(wù)器進(jìn)程會(huì)繼續(xù)處理命令請(qǐng)求
快照時(shí),數(shù)據(jù)能修改嘛? Redis接住操作系統(tǒng)的寫時(shí)復(fù)制技術(shù)(copy-on-write,COW),在執(zhí)行快照的同時(shí),正常處理寫操作。
雖然bgsave執(zhí)行不會(huì)阻塞主線程,但是頻繁執(zhí)行全量快照也會(huì)帶來性能開銷。比如bgsave子進(jìn)程需要通過fork操作從主線程創(chuàng)建出來,創(chuàng)建后不會(huì)阻塞主線程,但是創(chuàng)建過程是會(huì)阻塞主線程的??梢宰鲈隽靠煺?。
- RDB的優(yōu)點(diǎn):與AOF相比,恢復(fù)大數(shù)據(jù)集的時(shí)候會(huì)更快,它適合大規(guī)模的數(shù)據(jù)恢復(fù)場(chǎng)景,如備份,全量復(fù)制等
- 缺點(diǎn):沒辦法做到實(shí)時(shí)持久化/秒級(jí)持久化。
Redis4.0開始支持RDB和AOF的混合持久化,就是內(nèi)存快照以一定頻率執(zhí)行,兩次快照之間,再使用AOF記錄這期間的所有命令操作。
3 如何選擇RDB和AOF
- 如果數(shù)據(jù)不能丟失,RDB和AOF混用
- 如果只作為緩存使用,可以承受幾分鐘的數(shù)據(jù)丟失的話,可以只使用RDB。
- 如果只使用AOF,優(yōu)先使用everysec的寫回策略。



























