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