Redis 企業級數據備份方案

企業級的持久化的配置策略

在實際生產環境,RDB 和 AOF 一定都要打開,RDB 和 AOF 的配置需要根據業務的數據量決定

Redis RDB 持久化配置和數據恢復實驗

RDB 持久化配置

RDB 持久化在 redis.conf 文件中配置,目前配置文件存放在 /etc/redis/6379.conf,打開配置文件,添加 save 屬性配置,定期生成 RDB 快照。

# 每隔15分鐘,如果有超過1個key發生了變更,那麼就生成一個新的dump.rdb文件
save 900 1
# 每隔5分鐘,如果有超過300個key發生了變更,那麼就生成一個新的dump.rdb文件
save 300 10
# 每隔1分鐘,如果有超過10000個key發生了變更,那麼就生成一個新的dump.rdb文件
save 60 10000

save 屬性可以設置多個,就是設置多個 SNAPSHOTTING 檢查點,每到一個檢查點,就會去 check 一下,是否有指定的 key 數量發生了變更,如果有,就生成一個新的 dump.rdb 文件。

也可以在 redis-cli 命令中輸入 save 或者 bgsave 命令,手動同步或異步生成 RDB 快照。

RDB 持久化機制的工作流程

  1. Redis 根據配置自己嘗試去生成 RDB 快照文件;

  2. fork 一個子進程出來;

  3. 子進程嘗試將數據 dump 到臨時的 RDB 快照文件中;

  4. 完成 RDB 快照文件的生成之後,就替換之前的舊的快照文件;

基於 RDB 持久化機制的數據恢復實驗

通過 redis-cli SHUTDOWN 這種方式去停掉 Redis,其實是一種安全退出的模式,Redis 在退出的時候會將內存中的數據立即生成一份完整的 RDB 快照,存放在 /var/redis/6379/dump.rdb。

需要使用 kill -9 *** 強制殺死進程的方式來模擬 Redis 異常退出。執行步驟如下:

  1. 先往 Redis 中插入幾條數據;

  2. kill -9 強制殺死 Redis 進程,刪除 /var/run/redis_6379.pid 文件,再重新啓動 Redis;

  3. 通過 redis-cli 客戶端查看剛剛插入的數據,發現最新的幾條數據已經丟失;

  4. 配置 save 檢查點,save 5 1(每隔 5 秒,如果有超過 1 個 key 發生了變更,那麼就生成一個新的 dump.rdb 文件);

  5. 往 Redis 中插入幾條數據,暫停 5 秒以上;

  6. kill -9 強制殺死 Redis 進程,刪除 /var/run/redis_6379.pid 文件,再重新啓動 Redis;

  7. 通過 redis-cli 客戶端查看剛剛插入的數據,發現最新的幾條數據還在,查看 dump 文件,發現已經更新爲成最新的了;

Redis AOF 持久化配置和相關實驗

AOF 持久化配置

AOF 持久化配置,默認是關閉的,默認打開的是 RDB 持久化配置。AOF 持久化在 redis.conf 文件中配置,目前配置文件存放在 /etc/redis/6379.conf。

打開配置文件,修改  appendonly 屬性爲 yes ,打開 AOF 持久化配置:

appendonly yes

AOF 有三種 fsync 策略:

# 每次寫入一條數據就執行一次 fsync
# appendfsync always
# 每隔一秒執行一次 fsync
appendfsync everysec
# 不主動執行fsync
# appendfsync no

基於 AOF 持久化機制的數據恢復實驗

  1. 設置 appendonly 屬性爲 yes,打開 AOF 持久化,重啓 Redis;

  2. 往 Redis 中寫入幾條數據,等待一秒;

  3. kill -9 強制殺死 Redis 進程,刪除 /var/run/redis_6379.pid 文件,再重新啓動 Redis;

  4. 通過 redis-cli 客戶端查看剛剛插入的數據,發現最新的幾條數據還在,查看 /var/redis/6379 文件夾,發現已經存在 appendonly.aof 文件;

AOF rewrite 操作

Redis 中的內存中的數據是有一定限量的,內存到一定大小後,Redis 就會使用緩存淘汰算法(LRU)自動將一部分過期數據從內存中清除。AOF 是存放沒有寫命令的,所以文件會不斷膨脹,當大到一定的時候,AOF 會做 rewrite 操作。

在 redis.conf 文件中,可以配置 rewrite 策略。

# 如果 AOF 日誌文件增長的比例,超過了之前的100%,就可能會去觸發一次 rewrite
auto-aof-rewrite-percentage 100
# 但是此時還要去跟min-size比較,大於64M纔會去觸發一次 rewrite
auto-aof-rewrite-min-size 64mb

AOF rewrite 操作步驟:

  1. Redis fork 一個子進程;

  2. 子進程基於當前內存中的數據,構建日誌,開始往一個新的臨時的 AOF 文件中寫入日誌;

  3. Redis 主進程,接收到 client 新的寫操作之後,在內存中寫入日誌,同時新的日誌也繼續寫入舊的 AOF 文件;

  4. 子進程寫完新的日誌文件之後,Redis 主進程將內存中的新日誌再次追加到新的 AOF 文件中;

  5. 用新的日誌文件替換掉舊的日誌文件;

AOF 破損文件的修復

如果 Redis 在 append 數據到 AOF 文件時,機器宕機了,可能會導致 AOF 文件破損,用 redis-check-aof --fix 命令來修復破損的 AOF 文件。

redis-check-aof --fix /usr/local/appendonly.aof

AOF 和 RDB 同時工作

企業級的數據備份方案

按小時備份

redis_rdb_copy_hourly.sh

#!/bin/sh 
cur_date=`date +%Y%m%d%k`
rm -rf /usr/local/redis/snapshotting/$cur_date
mkdir /usr/local/redis/snapshotting/$cur_date
cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date
del_date=`date -d -48hour +%Y%m%d%k`
rm -rf /usr/local/redis/snapshotting/$del_date

每小時 copy 一次備份,刪除 48 小時前的數據。

crontab -e
0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.sh

按天備份

redis_rdb_copy_daily.sh

#!/bin/sh 
cur_date=`date +%Y%m%d`
rm -rf /usr/local/redis/snapshotting/$cur_date
mkdir /usr/local/redis/snapshotting/$cur_date
cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date
del_date=`date -d -1month +%Y%m%d`
rm -rf /usr/local/redis/snapshotting/$del_date

每天 copy 一次備份,刪除一個月前的數據。

crontab -e
0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.sh
0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_daily.sh

數據恢復方案

  1. 如果是 Redis 進程掛掉,那麼重啓 Redis 進程即可,直接基於 AOF 日誌文件恢復數據;

  2. 如果是 Redis 進程所在機器掛掉,那麼重啓機器後,嘗試重啓 Redis 進程,嘗試直接基於 AOF 日誌文件進行數據恢復;

  3. 如果 Redis 當前最新的 AOF 和 RDB 文件出現了丟失 / 損壞,那麼可以嘗試基於該機器上當前的某個最新的 RDB 數據副本進行數據恢復;

恢復步驟參考如下:

  1. 如果當前機器上的所有 RDB 文件全部損壞,那麼從遠程的雲服務上拉取最新的 RDB 快照回來恢復數據

  2. 如果是發現有重大的數據錯誤,比如某個小時上線的程序一下子將數據全部污染了,數據全錯了,那麼可以選擇某個更早的時間點,對數據進行恢復

舉個例子,12 點上線了代碼,發現代碼有 bug,導致代碼生成的所有的緩存數據全部錯了,找到一份 11 點的 rdb 的冷備,然後按照上面的步驟,去恢復到 11 點的數據,就可以了。

source: //www.yuque.com/yinjianwei/vyrvkf/hm1goc

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/S8zvzIyxcDVdWLe6KnYQ3w