1. 程式人生 > >Redis基礎(三)Redis持久化:RDB與AOF

Redis基礎(三)Redis持久化:RDB與AOF

什麼是Redis持久化? --- Redis是鍵值對的記憶體資料庫,它將資料儲存在記憶體裡。客戶端傳送命令到伺服器,再由伺服器到記憶體裡查詢資料。 ![image](https://yxl-article.oss-cn-shenzhen.aliyuncs.com/images/redis-basic/03/redis-persistence01.png) 一旦Redis伺服器程序退出,儲存在記憶體裡的資料就會丟失。 ![image](https://yxl-article.oss-cn-shenzhen.aliyuncs.com/images/redis-basic/03/redis-persistence02.png) 為了解決這個問題,Redis提供了持久化機制,即將資料儲存到磁盤裡,以便Redis伺服器程序初始化或重啟後重新載入資料,避免資料丟失。 ![image](https://yxl-article.oss-cn-shenzhen.aliyuncs.com/images/redis-basic/03/redis-persistence03.png) Redis提供兩種持久化方案,分別是RDB(Redis DataBase)和AOF(Append Only File)。 RDB持久化 --- RDB採用快照的方式來實現持久化,把資料庫資料儲存到RDB檔案裡,也可以通過RDB檔案還原資料庫資料。 ![image](https://yxl-article.oss-cn-shenzhen.aliyuncs.com/images/redis-basic/03/redis-rdb.png) ### 開啟RDB持久化的方式 RBD是Redis預設的持久化方案,可以通過三種方式來生成RDB檔案:SAVE、BGSAVE和自動觸發,其中前兩種是主動操作,後一種是被動操作,由Redis伺服器控制。 #### SAVE SAVE命令會阻塞Redis伺服器程序,直到RDB檔案建立完成,在伺服器程序阻塞期間,伺服器不能處理任何命令請求。 ```shell redis> Save // 等待直到RDB檔案建立完成 OK ``` ![image](https://yxl-article.oss-cn-shenzhen.aliyuncs.com/images/redis-basic/03/redis-rdb-save.png) #### BGSAVE 和SAVE命令直接阻塞伺服器程序不同,BGSAVE命令會fork一個子程序來負責建立RDB檔案,伺服器程序繼續處理命令請求。 ```shell redis> BGSAVE // fork子程序,並由子程序建立RDB檔案 Background saving started ``` ![image](https://yxl-article.oss-cn-shenzhen.aliyuncs.com/images/redis-basic/03/redis-rdb-bgsave.png) #### 自動觸發 Redis允許使用者通過設定伺服器配置的save選項,讓伺服器每隔一段時間自動執行一次BGSAVE命令。使用者可以通過save選項設定多個條件,只要滿足其中任意一個條件,伺服器就會執行BGSAVE命令。 ```shell save 900 1 // 伺服器在900秒內,至少1次修改 save 300 10 // 伺服器在300秒內,至少10次修改 save 60 10000 // 伺服器在60秒內,至少10000次修改 ``` AOF持久化 --- 除了RDB外,Redis還提供了AOF。與RDB通過儲存資料庫快照不同,AOF是通過儲存命令來記錄資料庫資料的。預設情況下,Redis是沒有開啟AOF的,可以通過配置redis.conf檔案來開啟AOF持久化,關於AOF的配置如下: ``` # appendonly引數開啟AOF持久化 appendonly no # AOF持久化的檔名,預設是appendonly.aof appendfilename "appendonly.aof" # AOF檔案的儲存位置和RDB檔案的位置相同,都是通過dir引數設定的 dir ./ # 同步策略 # appendfsync always appendfsync everysec # appendfsync no # aof重寫期間是否同步 no-appendfsync-on-rewrite no # 重寫觸發配置 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 載入aof出錯如何處理 aof-load-truncated yes # 檔案重寫策略 aof-rewrite-incremental-fsync yes ``` ### AOF持久化實現 AOF需要記錄Redis的每個命令,步驟分為:命令追加(append)、檔案寫入(write)和檔案同步(sync)。 #### 命令追加 當AOF持久化功能處於開啟狀態時,伺服器在執行完一個寫命令之後,會以協議格式將被執行的寫命令追加到伺服器狀態的 `aof_buf` 緩衝區的末尾。 #### 檔案寫入和同步 關於何時將 `aof_buf` 緩衝區的內容寫入AOF檔案中,Redis提供了三種策略: - `appendfsync always`:將`aof_buf`緩衝區中的所有內容寫入並同步到AOF檔案。 - `appendfsync everysec`:將`aof_buf`緩衝區中的所有內容寫入到AOF檔案,如果上次同步AOF檔案的時間距離現在超過1秒,那麼兩次對AOF檔案進行同步,並且這個同步操作是由一個執行緒專門負責執行的。 - `appendfsync no`:將`aof_buf`緩衝區中的所有內容寫入到AOF檔案,但並不對AOF檔案進行同步,何時同步由作業系統來決定。 關於AOF的同步策略是涉及到作業系統的 `write` 函式和 `fsync` 函式的,在《Redis設計與實現》中是這樣說明的: > 為了提高檔案寫入效率,在現代作業系統中,當用戶呼叫`write`函式,將一些資料寫入檔案時,作業系統通常會將資料暫存到一個記憶體緩衝區裡,當緩衝區的空間被填滿或超過了指定時限後,才真正將緩衝區的資料寫入到磁盤裡。 >
> 這樣的操作雖然提高了效率,但也為資料寫入帶來了安全問題:如果計算機停機,記憶體緩衝區中的資料會丟失。為此,系統提供了`fsync`、`fdatasync`同步函式,可以強制作業系統立刻將緩衝區中的資料寫入到硬盤裡,從而確保寫入資料的安全性。 ### AOF重寫 AOF會記錄每個Redis命令到AOF檔案,隨著時間越來越長,AOF檔案會變得越來越大。如果不加以控制,會對Redis伺服器,甚至對作業系統造成影響,而且AOF檔案越大,資料恢復也越慢。 為了解決AOF檔案體積膨脹的問題,Redis提供AOF檔案重寫功能來對AOF檔案進行“瘦身”。Redis通過建立一個新的AOF檔案來替換現有的AOF,新舊兩個AOF檔案儲存的資料相同,但新AOF檔案沒有了冗餘命令。 RDB和AOF對比 --- 關於RDB和AOF的優缺點,官網上面也給了比較詳細的說明[redis.io/topics/pers…](https://redis.io/topics/persistence) ### RDB 優點: - RDB快照是一個壓縮過的非常緊湊的檔案,儲存著某個時間點的資料集,適合做資料的備份,災難恢復; - 可以最大化Redis的的效能,在儲存RDb檔案,伺服器程序只需要fork一個子程序來完成RDB檔案的建立,父程序不需要做IO操作; - 與AOF相比,恢復大資料集的時候會更快; 缺點: - RDB的資料安全性是不如AOF的,儲存整個資料集的過程是比繁重的,根據配置可能要幾分鐘才快照一次,如果伺服器宕機,那麼就可能丟失幾分鐘的資料; - Redis資料集較大時,fork的子程序要完成快照會比較耗CPU、耗時; ### AOF 優點: - 資料更完整,安全性更高,秒級資料丟失(取決fsync策略,如果是everysec,最多丟失1秒的資料); - AOF檔案是一個只進行追加的日誌檔案,且寫入操作是以Redis協議的格式儲存的,內容是可讀的,適合誤刪緊急恢復; 缺點: - 對於相同的資料集,AOF檔案的體積要大於RDB檔案,資料恢復也會比較慢; - 根據所使用的fsync策略,AOF的速度可能會慢於RDB。 不過在一般情況下,每秒fsync的效能依然非常高; RDB和AOF如何選擇 --- 通常來說,應該同時使用兩種持久化方案,以保證資料安全。 - 如果資料不敏感,且可以從其他地方重新生成,可以關閉持久化。 - 如果資料比較重要,且能夠承受幾分鐘的資料丟失,比如快取等,只需要使用RDB即可。 - 如果是用做記憶體資料,要使用Redis的持久化,建議是RDB和AOF都開啟。 當RDB與AOF兩種方式都開啟時,Redis會優先使用AOF恢復資料,因為AOF儲存的檔案比RDB檔案更完整。 參考資料 --- - [Redis設計與實現](https://book.douban.com/subject/25900156/) - [10分鐘徹底理解Redis的持久化機制:RDB和AOF](https://juejin.im/post/6844903874927525902) - [Redis兩種持久化機制RDB和AOF詳解(面試常問,工作常用)](https://database.51cto.com/art/202002/610603.htm) - [Redis持久化機制:RDB和AOF](https://juejin.im/post/6844903939339452430#hea