本文鏈接:http://www.cnblogs.com/zhenghongxin/p/9050219.html
- 使用兩種備份方案
備份方案選擇RDB和AOF同時進行備份,必須打開AOF的持久化機制,除非能接受在故障環境下丟失幾分鍾的數據。
在redis重啟的時候,是優先通過AOF進行數據恢復的,因為AOF數據比較完整。
- RDB的生成策略
要修改的是該條命令:
save 60 10000
該條命令是60秒內,如果有1萬條命令執行,那么就進行快照備份。這個值略大,可以根據自己的業務量而定,可以調小至1000。但也同時意味着,在一分鍾內,如果命令執
行了999條,且在最后一秒redis掛掉,該分鍾內的命令將會全部丟失。
注意不要用:redis-cli SHUTDOWN 這樣的方式去測試,這是一種安全退出的模式,redis會安全生成dump.rdb
它的工作流程:
(1)redis根據配置自己嘗試去生成rdb快照文件 (2)fork一個子進程出來 (3)子進程嘗試將數據dump到臨時的rdb快照文件中 (4)完成rdb快照文件的生成之后,就替換之前的舊的快照文件dump.rdb,每次生成一個新的快照,都會覆蓋之前的老快照
- AOF的生成策略
當AOF開啟之后,redis每次接收到一條寫命令,就會寫入日志文件中,先寫入系統的 os cache中,然后隔一段時間再fsync一下。
fsync的策略有三種:
always: 每次寫入一條數據,立即將這個數據對應的寫日志fsync到磁盤上去,性能非常非常差,吞吐量很低;
如果說確保說redis里的數據一條都不丟,那就只能這樣了
everysec: 每秒將os cache中的數據fsync到磁盤,這個最常用的,生產環境一般都這么配置,性能很高,QPS還是可以上萬的
no:就是直接寫入os cache就不管了,讓linux自帶的機制去將數據刷入磁盤,這樣很不可控
因此我們要配置為everysec。
接着配置兩條命令:
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
redis 2.4之前,還需要手動,開發一些定時任務腳本,通過BGREWRITEAOF命令去執行AOF rewrite,但是redis 2.4之后,會自動進行rewrite操作
也就是說在上一次AOF rewrite之后,日志大小是128mb,接着再往里面寫日志,當總日志大小增長的比例,超過了之前的100%,即達到256mb后,就會觸發rewrite操作。
注意,此時還要跟 auto-aof-rewrite-min-size 比較大小,256M 大於 64m,可以觸發rewrite操作。這兩條命令,可以根據業務進行調節大小,或者保持默認值
- 定時任務備份方案(重要)
並不是說讓redis自動進行持久化備份就可以的,而是要另開腳本,進行更細致的備份。
1 )每小時都copy一份rdb的備份,到一個目錄中去,僅僅保留最近48小時的備份
0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.sh 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` # 48小時前的目錄文件名 rm -rf /usr/local/redis/snapshotting/$del_date # 刪除48小時前的目錄
2 )每天copy一次備份
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/snapshotting/$cur_date #先刪除原有的目錄 mkdir /usr/local/redis/snapshotting/$cur_date #創建該目錄 cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date //備份cp del_date=`date -d -1month +%Y%m%d` #僅保留近一個月的數據 rm -rf /usr/local/redis/snapshotting/$del_date #刪除
3)每天一次將所有數據上傳一次到遠程的雲服務器上去
原理跟第2點一樣,只是不是用cp,而是用scp或rsync等命令將文件備份到遠程安全服務器
以上只給了rdb的備份,aof的備份腳本基本一致。
- 數據恢復方案(重要)
(1)如果是redis進程掛掉,那么重啟redis進程即可,直接基於AOF日志文件恢復數據
(2)如果是redis進程所在機器掛掉,那么重啟機器后,嘗試重啟redis進程,嘗試直接基於AOF日志文件進行數據恢復
如果AOF沒有破損,可以直接基於AOF恢復的
AOF append-only,順序寫入,如果AOF文件破損,那么用redis-check-aof fix
(3)如果redis當前最新的AOF和RDB文件出現了丟失/損壞,那么可以嘗試基於該機器上當前的某個最新的RDB數據副本進行數據恢復
找到RDB最新的一份備份,小時級的備份可以了,小時級的肯定是最新的,copy到redis里面去,就可以恢復到某一個小時的數據
(4)如果當前機器上的所有RDB文件全部損壞,那么從遠程的雲服務上拉取最新的RDB快照回來恢復數據
恢復的過程:
(1)優先用appendonly.aof去恢復數據
(2)停止redis,關閉aof (為什么要關閉?如果不關閉,啟動redis后,redis會生成一份新的可能為空的aof強行覆蓋目錄下的aof,導致恢復失敗)
(3)拷貝備份文件,重啟redis
(4)命令行修改redis配置,開啟aof (redis config set )
-------------------------------------------------------------------------------------
AOF的重寫機制
隨着命令不斷寫入AOF,文件會越來越大,為了解決這個問題,Redis引入AOF重寫機制壓縮文件體積。AOF文件重寫是把Rdis進程內的數據轉化為寫命令同步到
新AOF文件的過程。
重寫后的AOF文件為什么可以變小?有如下原因:
(1)進程內已經超時的數據不再寫入文件。
(2)舊的AOF文件含有無效命令,如del key1、hdel key2、srem keys、set a111、set a222等。重寫使用進程內數據直接生成,這樣新的AOF文件只保留最終數據的寫入命令。
(3)多條寫命令可以合並為一個,如:lpush list a、lpush list b、lpush list c可以轉化為:lpush list a b c。為了防止單條命令過大造成客戶端緩沖區溢出,對於list、set、hash、zset等類型操作,以64個元素為界拆分為多條。
(4)AOF重寫降低了文件占用空間,除此之外,另一個目的是:更小的AOF文件可以更快地被Redis加載。