Redis企業級數據備份與恢復方案
一、持久化配置
-
RBD和AOF建議同時打開(Redis4.0之後支援)
-
RDB做冷備,AOF做數據恢復(數據更可靠)
-
RDB採取默認配置即可,AOF推薦採取everysec每秒策略
AOF和RDB還不懂的,請轉移到如下幾篇:
天天在用Redis,那你對Redis的AOF持久化到底了解多少呢?
二、數據備份方案
1、需求
我們需要定時備份rdb文件來做冷備,為什麼?不是有aof和rbd了嗎為什麼還要單獨寫定時任務去備份?因為Redis的aof和rdb是僅僅有一個最新的,比如誰手賤再Redis宕機的時候執行rm -rf aof/rdb
了,那不就GG了嗎?或者rdb/aof文件損壞了等不可預期的情況。所以我們需要單獨備份rdb文件以防萬一。
為什麼不定時備份aof而是rdb?定時備份aof沒意義呀,定時本身就是冷備份,不是實時的,rdb文件又小恢復又快,她哪裡不香?
2、方案
-
寫crontab定時調度腳本去做數據備份。
-
每小時都copy一份redis的rdb文件到一個其他目錄中,這個目錄里的rdb文件僅僅保留48小時內的。也就是每小時都做備份,保留2天內的rdb,只保留48個rdb。
-
每天0點0分copy一份redis的rdb文件到一個其他目錄中,這個保留一個月的。也就是按天備份。
-
每天半夜找個時間將當前服務上的所有rdb備份都上傳到雲服務上。
3、實現
3.1、按小時
每小時copy一次備份,刪除48小時前的數據。
crontab -e # 每小時都執行/usr/local/redis/copy/redis_rdb_copy_hourly.sh腳本 0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.sh # redis_rdb_copy_hourly.sh腳本的內容如下: #!/bin/sh # +%Y%m%d%k == 年月日時 cur_date=`date +%Y%m%d%k` rm -rf /usr/local/redis/rdb/$cur_date mkdir /usr/local/redis/rdb/$cur_date # 拷貝rdb到目錄 cp /var/redis/6379/dump.rdb /usr/local/redis/rdb/$cur_date # date -d -48hour +%Y%m%d%k == 48小時前的日期,比如今天2020060214,這個結果就是2020053114 del_date=`date -d -48hour +%Y%m%d%k` # 刪除48小時之前的目錄 rm -rf /usr/local/redis/rdb/$del_date
3.2、按天
每天copy一次備份,刪除一個月前的數據。
crontab -e # 每天0點0分開始執行/usr/local/redis/copy/redis_rdb_copy_daily.sh腳本 0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_daily.sh # redis_rdb_copy_daily.sh腳本的內容如下: #!/bin/sh # 年月日 cur_date=`date +%Y%m%d` rm -rf /usr/local/redis/rdb/$cur_date mkdir /usr/local/redis/rdb/$cur_date # 拷貝rdb到目錄 cp /var/redis/6379/dump.rdb /usr/local/redis/rdb/$cur_date # 獲取一個月前的時間,比如今天是20200602,那麼del_date就是20200502 del_date=`date -d -1month +%Y%m%d` # 刪除一個月前的數據 rm -rf /usr/local/redis/rdb/$del_date
3.3、傳到雲
沒法演示,最終目的就是磁碟備份完上傳到雲,雲保留多少天等策略自己看需求。
三、數據恢復方案
1、redis掛了
如果僅僅是redis進程掛了,那麼直接重啟redis進程即可,Redis會按照持久化配置直接基於持久化文件進行恢複數據。
如果有AOF則按照AOF,AOF和RDB一起開的話也走AOF。
2、持久化文件丟了
如果持久化文件(rdb/aof)損壞了,或者直接丟失了。那麼就要採取我們上面所做的rdb備份來進行恢復了。
不要腦子一熱想著很簡單,就以為直接把rdb拖過來重啟redis進程就完事了,這種想法有很多問題。慢慢道來。
2.1、問題
問題一:直接把備份的rdb扔到redis持久化目錄下然後重啟redis不行的原因在於:redis是按照先aof後rdb進行恢復的,所以都是開啟aof的,redis啟動後會重新生成新的aof文件,裡面是空的。所以不會進行任何數據恢復,也就是說雖然你把rdb丟給redis了,但是redis會按照aof來恢復,而aof是redis啟動的時候新生成的空文件,所以不會有任何數據進行恢復。
問題二:那麼我們把rdb文件丟給redis後,先將redis的aof關閉再啟動redis進程不就能按照rdb來進行恢復了嗎?是這樣的,沒毛病!但是新的問題來了,我們aof肯定要開的,aof對數據保障更可靠。那什麼我們按照rdb文件恢復完後再修改redis配置文件開啟aof然後重啟redis進程不就得了嘛?大哥…你打開aof然後重啟redis,這時候redis又會生成一個空的aof文件,這時候恢復的時候又是啥數據都沒了。
因為數據是存到記憶體里,你重啟後肯定沒了,需要持久化文件來恢復。這時候aof是空的,我恢復個雞毛啊。
2.2、具體方案
可能有人想到方案了,但是耐心看完,看看我的文采如何。
我不管你是持久化文件丟了還是壞了,我都先rm -rf *
給他刪了。
-
停止redis進程
-
刪除壞掉的rdb和aof持久化文件。
-
修改配置文件關閉redis的aof持久化。
-
找到最新備份的rdb文件扔到redis的持久化目錄里。(這裡最新的肯定是按照小時備份的最後一個)
-
啟動Redis進程
-
執行
set appendonly yes
動態打開aof持久化。
也就是說打開aof的操作不是修改配置文件然後重啟,而是先熱修改讓他生成aof,這次生成肯定是會帶著記憶體中完整的數據的。然後再修改配置文件重啟。
-
等aof文件生成後再修改redis配置文件打開aof。
-
重啟redis進程。
-
完美收官。