對比 Redis 中 RDB 和 AOF 持久化
阿新 • • 發佈:2020-09-16
![](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