Ubuntu 22.04 Redis 持久化策略設定

Ubuntu 22.04 Redis Persistence Configuration

Redis 持久化概述

Redis 是一款記憶體資料庫,所有資料預設儲存於記憶體中。然而,若伺服器重新啟動或發生故障,記憶體中的資料將會遺失。為了解決這個問題,Redis 提供了持久化機制,將記憶體中的資料保存到硬碟上。

Redis 持久化的重要性

  • 資料安全:防止伺服器重啟或故障時資料遺失
  • 災難復原:可從備份檔案還原資料
  • 資料遷移:便於將資料轉移到其他伺服器

Redis 提供的持久化方式

Redis 提供三種持久化策略:

  1. RDB(Redis Database):定時將記憶體中的資料快照儲存為二進位檔案
  2. AOF(Append Only File):將每個寫入操作以日誌方式記錄
  3. 混合持久化:結合 RDB 和 AOF 的優點(Redis 4.0+)

RDB 快照機制

RDB 是 Redis 預設的持久化方式。它會在指定的時間間隔內,將記憶體中的資料集快照寫入硬碟,產生一個 dump.rdb 檔案。

RDB 運作原理

  1. Redis 主程序 fork 一個子程序
  2. 子程序將資料集寫入臨時 RDB 檔案
  3. 寫入完成後,用臨時檔案取代舊的 RDB 檔案
  4. 子程序退出,主程序繼續處理請求

RDB 優點

  • 檔案緊湊:RDB 是壓縮的二進位格式,檔案較小
  • 還原速度快:適合大規模資料還原
  • 效能影響小:由子程序處理,不影響主程序效能
  • 適合備份:適合定期備份和災難復原

RDB 缺點

  • 資料遺失風險:兩次快照之間的資料可能遺失
  • fork 耗時:大資料集 fork 可能造成短暫阻塞

RDB 設定參數

編輯 Redis 設定檔 /etc/redis/redis.conf

1
sudo nano /etc/redis/redis.conf

自動觸發條件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 在 900 秒(15 分鐘)內,如果至少有 1 個 key 被修改,則觸發 RDB 快照
save 900 1

# 在 300 秒(5 分鐘)內,如果至少有 10 個 key 被修改,則觸發 RDB 快照
save 300 10

# 在 60 秒(1 分鐘)內,如果至少有 10000 個 key 被修改,則觸發 RDB 快照
save 60 10000

# 如要停用 RDB,可註解以上所有 save 指令或設定:
# save ""

RDB 檔案設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# RDB 檔案名稱
dbfilename dump.rdb

# RDB 檔案儲存目錄
dir /var/lib/redis

# 背景儲存失敗時,停止接受寫入(建議保持 yes)
stop-writes-on-bgsave-error yes

# 是否壓縮 RDB 檔案(使用 LZF 壓縮)
rdbcompression yes

# 是否在載入 RDB 時檢查檔案完整性
rdbchecksum yes

手動觸發 RDB 快照

1
2
3
4
5
6
7
8
# 同步儲存(會阻塞 Redis)
redis-cli SAVE

# 非同步儲存(背景執行,推薦使用)
redis-cli BGSAVE

# 查看最後一次 RDB 快照時間
redis-cli LASTSAVE

AOF 日誌機制

AOF(Append Only File)持久化會記錄伺服器執行的所有寫入命令,並在伺服器啟動時重新執行這些命令來還原資料。

AOF 運作原理

  1. 客戶端發送寫入命令
  2. Redis 執行命令並更新記憶體
  3. 將命令追加寫入 AOF 緩衝區
  4. 根據設定的同步策略,將緩衝區內容寫入 AOF 檔案

AOF 優點

  • 資料安全性高:可設定每秒或每次寫入同步
  • 可讀性佳:AOF 是純文字格式,便於閱讀和修復
  • 彈性較高:可對 AOF 檔案進行編輯和修復

AOF 缺點

  • 檔案較大:AOF 檔案通常比 RDB 檔案大
  • 還原速度慢:需要重新執行所有命令
  • 寫入效能:頻繁的磁碟 I/O 可能影響效能

AOF 設定參數

啟用 AOF

1
2
3
4
5
6
7
8
# 啟用 AOF 持久化(預設為 no)
appendonly yes

# AOF 檔案名稱
appendfilename "appendonly.aof"

# AOF 檔案儲存目錄(與 RDB 共用)
dir /var/lib/redis

同步策略

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 同步策略設定(三選一)

# always:每次寫入都同步到磁碟(最安全,但效能最低)
# appendfsync always

# everysec:每秒同步一次(預設值,兼顧安全與效能)
appendfsync everysec

# no:由作業系統決定何時同步(效能最高,但可能遺失較多資料)
# appendfsync no

同步策略比較

策略寫入效能資料安全性可能遺失資料
always較慢最高最多 1 個命令
everysec中等較高最多 1 秒資料
no最快較低依系統而定

AOF 重寫

隨著時間推移,AOF 檔案會越來越大。Redis 提供 AOF 重寫機制,可以產生一個較小的 AOF 檔案。

AOF 重寫原理

AOF 重寫不是讀取舊的 AOF 檔案,而是:

  1. Redis fork 一個子程序
  2. 子程序根據目前記憶體中的資料,產生新的 AOF 檔案
  3. 主程序將重寫期間的新命令寫入緩衝區
  4. 子程序完成後,將緩衝區內容追加到新檔案
  5. 用新檔案取代舊檔案

AOF 重寫設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 當 AOF 檔案大小超過上次重寫後大小的 100% 時觸發重寫
auto-aof-rewrite-percentage 100

# AOF 檔案最小重寫大小(避免檔案太小時頻繁重寫)
auto-aof-rewrite-min-size 64mb

# 重寫時是否停用 fsync(可提高重寫效能,但降低安全性)
no-appendfsync-on-rewrite no

# 載入 AOF 時,若發現檔案末端損壞是否繼續載入
aof-load-truncated yes

# 是否使用 RDB 前導的 AOF 格式(混合持久化,Redis 4.0+)
aof-use-rdb-preamble yes

手動觸發 AOF 重寫

1
2
3
4
5
# 背景執行 AOF 重寫
redis-cli BGREWRITEAOF

# 查看 AOF 相關資訊
redis-cli INFO persistence

RDB vs AOF 比較

特性RDBAOF
檔案格式二進位純文字
檔案大小較小較大
還原速度較快較慢
資料安全性較低較高
寫入效能較高較低
可讀性不可讀可讀
適用場景備份、災難復原即時資料保護

選擇建議

  • 只用 RDB:可接受數分鐘的資料遺失,重視備份和還原速度
  • 只用 AOF:需要較高的資料安全性,可接受較慢的還原速度
  • 混合使用:同時啟用兩者,獲得最佳的資料安全性和還原速度(推薦)

混合持久化

Redis 4.0 引入混合持久化模式,結合 RDB 和 AOF 的優點。

混合持久化原理

在 AOF 重寫時:

  1. 將目前資料以 RDB 格式寫入 AOF 檔案開頭
  2. 後續的增量命令以 AOF 格式追加
  3. 還原時先載入 RDB 部分,再執行 AOF 命令

啟用混合持久化

1
2
3
4
5
# 啟用 AOF
appendonly yes

# 啟用混合持久化(預設為 yes)
aof-use-rdb-preamble yes

混合持久化優點

  • 還原速度快:RDB 部分可快速載入
  • 資料安全性高:AOF 部分記錄增量變更
  • 檔案較小:RDB 壓縮 + 增量 AOF

備份與還原

備份 RDB 檔案

1
2
3
4
5
6
7
8
# 建立備份目錄
sudo mkdir -p /backup/redis

# 觸發 RDB 快照
redis-cli BGSAVE

# 等待快照完成後複製檔案
sudo cp /var/lib/redis/dump.rdb /backup/redis/dump_$(date +%Y%m%d_%H%M%S).rdb

自動備份腳本

建立備份腳本 /usr/local/bin/redis-backup.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash

REDIS_DIR="/var/lib/redis"
BACKUP_DIR="/backup/redis"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7

# 建立備份目錄
mkdir -p $BACKUP_DIR

# 觸發 RDB 快照
redis-cli BGSAVE

# 等待快照完成
sleep 10

# 複製 RDB 檔案
cp $REDIS_DIR/dump.rdb $BACKUP_DIR/dump_$DATE.rdb

# 複製 AOF 檔案(如果存在)
if [ -f "$REDIS_DIR/appendonly.aof" ]; then
    cp $REDIS_DIR/appendonly.aof $BACKUP_DIR/appendonly_$DATE.aof
fi

# 刪除過期備份
find $BACKUP_DIR -name "dump_*.rdb" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "appendonly_*.aof" -mtime +$RETENTION_DAYS -delete

echo "Redis backup completed: $DATE"

設定執行權限並加入排程:

1
2
3
4
5
6
7
8
# 設定執行權限
sudo chmod +x /usr/local/bin/redis-backup.sh

# 編輯 crontab
sudo crontab -e

# 每天凌晨 3 點執行備份
0 3 * * * /usr/local/bin/redis-backup.sh >> /var/log/redis-backup.log 2>&1

還原資料

從 RDB 還原

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 停止 Redis 服務
sudo systemctl stop redis-server

# 複製備份檔案
sudo cp /backup/redis/dump_YYYYMMDD_HHMMSS.rdb /var/lib/redis/dump.rdb

# 設定正確的權限
sudo chown redis:redis /var/lib/redis/dump.rdb

# 啟動 Redis 服務
sudo systemctl start redis-server

從 AOF 還原

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 停止 Redis 服務
sudo systemctl stop redis-server

# 複製備份檔案
sudo cp /backup/redis/appendonly_YYYYMMDD_HHMMSS.aof /var/lib/redis/appendonly.aof

# 設定正確的權限
sudo chown redis:redis /var/lib/redis/appendonly.aof

# 啟動 Redis 服務
sudo systemctl start redis-server

修復損壞的 AOF 檔案

1
2
# 檢查 AOF 檔案
redis-check-aof --fix /var/lib/redis/appendonly.aof

檢查 RDB 檔案

1
2
# 檢查 RDB 檔案完整性
redis-check-rdb /var/lib/redis/dump.rdb

生產環境建議設定

以下是建議的生產環境持久化設定:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# RDB 設定
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /var/lib/redis
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes

# AOF 設定
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes

重新載入設定:

1
sudo systemctl restart redis-server

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy