1. 程式人生 > >對比 Redis 中 RDB 和 AOF 持久化

對比 Redis 中 RDB 和 AOF 持久化

![](http://cdn.chaohang.top/20200915140846.jpg) ## 概念 Redis 是記憶體資料庫,資料儲存在記憶體中,一旦伺服器程序退出,資料就丟失了,所以 Redis 需要想辦法將儲存在記憶體中的資料持久化到磁碟。 Redis 提供了兩種持久化功能: 1. RDB (Redis Database):生成 RDB 檔案,儲存的是 key-value 的形式。 2. AOF (Append Only File):儲存 Redis 執行過程中的寫命令。 ## 生成 ### RDB 的生成 1. `SAVE` 命令會阻塞 Redis 服務程序,直到 RDB 檔案建立完畢為止,在伺服器程序阻塞期間,伺服器不能處理任何命令請求。 2. `BGSAVE` 命令會派生出一個子程序,然後由子程序負責建立 RDB 檔案,伺服器程序(父程序)繼續處理命令請求。 如果兩個 key 值的修改具有事務性,需要手動加事務,不然備份時可能會導致兩個值不一致。 除了主動執行命令,我們還可以通過 save 選項設定多個儲存條件,只要任意一個條件滿足,伺服器就會執行 `BGSAVE` 命令: ```java save 900 1 save 300 10 save 60 10000 ``` 那麼只要滿足以下三個條件中的任意一個,`BGSAVE` 命令就會被執行: 1. 伺服器在900秒之內,對資料庫進行了至少1次修改。 2. 伺服器在300秒之內,對資料庫進行了至少10次修改。 3. 伺服器在60秒之內,對資料庫進行了至少10000次修改。 ### AOF 的生成 只要開啟 AOF 持久化功能,伺服器在執行完一個寫命令後,會以協議格式將被執行的寫命令追加到伺服器狀態的 aof_buf 緩衝區的末尾。 現代作業系統中,使用者在寫檔案時,作業系統通常會將寫入資料暫時儲存在一個記憶體緩衝區裡面,等到緩衝區被填滿,或者超過了指定時限之後,才真正將緩衝區中的資料寫入磁碟。這就有可能導致緩衝區內的資料還未寫入磁碟,計算機發生停機,導致資料丟失。 `appendfsync` 選項的值可以決定 AOF 持久化功能的效率和安全性: 1. `always` 每次都同步到磁碟,效率低,安全性高; 2. `everysec` 每隔一秒同步到磁碟,效率足夠快,安全性高,只丟失一秒的資料; 3. `no` 由作業系統控制同步到磁碟的時機,速度最快,安全性最低。 ### AOF 的重寫 因為 AOF 儲存的是寫命令,隨著伺服器的執行,同一個鍵值被操作的次數越多,單個鍵值就會產生多條寫命令,AOF 檔案就會越大,還原的時間就會越久。 為了解決 AOF 體積膨脹的問題,Redis 提供了 AOF 檔案重寫(rewrite)功能。 AOF 重寫並不是對舊的 AOF 檔案進行壓縮。Redis 會從資料庫中讀出資料,生成對應的寫命令,並寫入新的 AOF 檔案中,當新的 AOF 檔案重寫了所有資料的寫命令,就可以替換掉舊 AOF 檔案。 AOF 重寫可以在後臺進行,在重寫過程中新產生的資料,會寫入 AOF 重寫緩衝區中,當重寫結束再把緩衝區的寫命令追加到新的 AOF 檔案中即可。 ![](http://cdn.chaohang.top/20200915091441.png) ## 載入 ### RDB 的載入 RDB 檔案的載入工作是在伺服器啟動時自動執行的,所以 Redis 沒有專門用於載入的命令。 因為 AOF 檔案的更新頻率通常比 RDB 檔案的更新頻率高,所以: 1. 如果伺服器啟動了AOF 持久化功能,那麼伺服器會優先使用 AOF 檔案來還原資料庫狀態。 2. 只有在 AOF 持久化功能處於關閉狀態時,伺服器才會使用 RDB 檔案來還原資料庫狀態。 ![http://cdn.chaohang.top/20200914084027.png](http://cdn.chaohang.top/20200914084027.png) ### AOF 的載入 AOF 中包含了所有的寫命令,伺服器只要讀入並重新執行一遍AOF檔案裡儲存的寫命令,就可以還原伺服器關閉前的狀態。 Redis 讀取 AOF 檔案並還原資料庫狀態的詳細步驟: 1. 建立一個不帶網路連線的偽客戶端:因為 Redis 的命令只能在客戶端上下文中執行,而載入 AOF 檔案時所使用的命令直接來源於 AOF 檔案而不是網路連線,所以用來還原資料的偽客戶端不需要網路連線; 2. 從 AOF 檔案中分析並讀取出一條寫命令; 3. 使用偽客戶端執行讀出的寫命令; 4. 迴圈執行步驟2和步驟3,直到 AOF 檔案中的所有命令都被執行。 ![](http://cdn.chaohang.top/20200915090522.png) ## 資料 [Redis設計與實現-黃健巨集-微信讀書](https://weread.qq.com/web/reader/d35323e0597db0d35bd957bk7cb321502467cbbc409e62d) > 本文首發於我的個人部落格 https://chaohang.top > > 作者[張小超](https://chaohang.top) > > 轉載請註明出處 歡迎關注我的微信公眾號 【超超不會飛】,獲取第一時間的更新。 ![](http://cdn.chaohang.top/20200812114