---
# System prepended metadata

title: Redis 持久化
tags: [Redis]

---

# Redis 持久化

記錄一下 Redis 持久化的一些選擇和執行方式，方便日後選擇用哪種方式。

## 選項
- RDB (Redis Database)：在指定時間間隔內建立資料集時間點的快照
- AOF (Append Only File)：記錄每個操作，伺服器啟動的時候依照檔案內的操作順序執行一遍來還原
- RDB + AOF：同時使用 RDB 和 AOF
- 不使用

## RDB
- 在指定時間間隔內建立資料集時間點的快照，例如一個小時存一次、每個月第一天存一次
- 除了自動建立之外，也可以執行 `save` (同步，不建議)或 `bgsave` (非同步，建議) 指令來手動建立
- 資料儲存在 `dump.rdb` 中，裡面是壓縮過的二進位資料
- 重啟恢復資料時，直接將 RDB 寫入記憶體中

設定範例：  
/etc/redis/redis.conf
```
save 300 10  # 300 秒內有 10 次異動就建立快照
save 60 1000 # 60 秒內有 1000 次異動就建立快照

save "" # 最後一行加上這個空字串，代表不要用 RDB
```

### 運作方式
使用 copy-on-write (CoW) 的方式處理
- Redis 執行 fork() 分叉出另一個子 process 出來
- 子 process 開始寫入目前的資料到暫存 RDB 檔案
- 寫入完成後，暫存 RDB 檔案取代現有的檔案

### 優點
- 只有一個非常緊湊的檔案 (二進位)，儲存了某個時間點的資料集
- 檔案易於異地備份，RDB 檔案就是快照
- 不太影響 Redis 的效能。備份時會 Redis 執行 fork() 分叉出另一個 process 來處理，主 process 不用管 IO 的操作
- 在恢復大的資料集時比 AOF 快
- 可以拿出來分析當前資料的情況，如資料量、各 key 大小等

### 缺點
- 不能完整備份。由於是指定時間點才建立快照，如果 Redis 在兩個 save points 之間壞掉，這段期間的資料就會丟失
- 每次儲存 RDB 的時候都需要 fork() 一個 process 來處理，會佔用額外的記憶體。如果資料集龐大的話，可能會暫停服務幾毫秒，如果 CPU 用量也高，可能會暫停到 1 秒

## AOF
- 全名 Append Only File
- 只會在尾行增加資料，不會異動前面的資料
- 每當收到資料異動的指令，就會把這個指令寫到 AOF 檔案的最尾端
- 重啟恢復資料時，AOF 檔案內的指令從第一行到最後一行執行一遍
- 建議搭配 RDB 使用，以防 AOF 檔案損毀時無法還原

### 運作方式
- 收到客戶端資料異動的指令
- 將指令記錄到 AOF 的 buffer 中
- 透過 fsync 的設定，將指令寫入 AOF 檔案的最尾端
    - always: 每個操作都寫。很慢，最安全
    - everysec: 每秒寫入一次。速度和 RDB 差不多，失敗頂多遺失 1 秒的資料 (預設，建議)
    - no: 不使用 fsync，由作業系統決定 (通常 30 秒)。很快，但是不安全

### 優點
- 記錄的細節比 RDB 更完整。依照 fsync 的設定來記錄，預設 1 秒一次 (everysec)，也可以每執行一次資料異動的指令時執行 (always)，或關閉 (no)
- fsync 在背景執行緒執行
- AOF 檔案是 append only log，只會持續增加
- AOF 檔案體積變大時，可設定在後台自動重寫 (rewrite)，重寫後的 AOF 包含恢復目前資料集的最小指令集合
- AOF 檔案的內容比較容易給人閱讀和容易解析
- 如果執行了 flushall 後沒有再執行任何指令，可以先停止服務，到 AOF 檔案裡刪除 flushall 後，重啟 Redis 來還原資料

### 缺點
- AOF 檔案的體積比 RDB 大
- Redis 寫入資料的效能會降低
- 還原速度較慢，需要一條一條執行
- fsync 的策略會影響寫入的效能，甚至比 RDB 慢
- 還原時會額外消耗記憶體
- AOF 檔案重寫時會額外消耗 CPU、記憶體和磁碟 IO 與空間
- 可能會因為一些 bug 導致檔案損毀，甚至無法還原
  > AOF 在过去曾经发生过这样的 bug ： 因为个别命令的原因，导致 AOF 文件在重新载入时，无法将数据集恢复成保存时的原样。 （举个例子，阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug 。） 测试套件里为这种情况添加了测试： 它们会自动生成随机的、复杂的数据集， 并通过重新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见， 但是对比来说， RDB 几乎是不可能出现这种 bug 的。 - 來源：http://doc.redisfans.com/topic/persistence.html#id4

## RDB + AOF
同時使用 RDB 和 AOF

### 優點
- 資料完整性媲美 PostgreSQL
- 還原時優先使用 AOF，因為完整。AOF 不存在的時候用 RDB
- 保留 AOF 的完整性，也有 RDB 的方便備份、還原

### 缺點
- 設定要同時考慮 RDB 和 AOF
- 佔用較多的磁碟空間、記憶體

## 不使用
不使用任何持久化，資料都存在記憶體中

### 優點
- 超級快
- 配置簡單

### 缺點
- Redis 停止之後，資料就消失了

## 比較



## 參考
- [Redis persistence | Docs](https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/)
- [持久化（persistence） — Redis 命令参考](http://doc.redisfans.com/topic/persistence.html)
- [關於 Redis Persistence - 資料持久化 - Yowko's Notes](https://blog.yowko.com/redis-persistence/)
- [10分钟彻底理解Redis的持久化机制：RDB和AOF - 乖怪丶 - 博客园](https://www.cnblogs.com/SparkMore/p/17213087.html)