Redis AOF持久化(二)

一、AOF持久化的配置java

AOF持久化,默認是關閉的,默認是打開RDB持久化mysql

appendonly yes,能夠打開AOF持久化機制,在生產環境裏面,通常來講AOF都是要打開的,除非你說隨便丟個幾分鐘的數據也無所謂redis

打開AOF持久化機制以後,redis每次接收到一條寫命令,就會寫入日誌文件中,固然是先寫入os cache的,而後每隔必定時間再fsync一下算法

並且即便AOF和RDB都開啓了,redis重啓的時候,也是優先經過AOF進行數據恢復的,由於aof數據比較完整sql

能夠配置AOF的fsync策略,有三種策略能夠選擇,一種是每次寫入一條數據就執行一次fsync; 一種是每隔一秒執行一次fsync; 一種是不主動執行fsync緩存

always: 每次寫入一條數據,當即將這個數據對應的寫日誌fsync到磁盤上去,性能很是很是差,吞吐量很低; 確保說redis裏的數據一條都不丟,那就只能這樣了安全

mysql -> 內存策略,大量磁盤,QPS到多少,一兩k。QPS,每秒鐘的請求數量
redis -> 內存,磁盤持久化,QPS到多少,單機,通常來講,上萬QPS沒問題服務器

everysec: 每秒將os cache中的數據fsync到磁盤,這個最經常使用的,生產環境通常都這麼配置,性能很高,QPS仍是能夠上萬的app

no: 僅僅redis負責將數據寫入os cache就撒手無論了,而後後面os本身會時不時有本身的策略將數據刷入磁盤,不可控了oop

二、AOF持久化的數據恢復實驗

(1)先僅僅打開RDB,寫入一些數據,而後kill -9殺掉redis進程,接着重啓redis,發現數據沒了,由於RDB快照還沒生成
(2)打開AOF的開關,啓用AOF持久化
(3)寫入一些數據,觀察AOF文件中的日誌內容

在appendonly.aof文件中,能夠看到剛寫入的日誌,他們就是先寫入到os cache的,而後1s後才fsync到磁盤中,只有fsync到磁盤中才是安全的,光是在os cache中,

機器從新啓動,就什麼都沒有了。 

(4)kill -9殺掉進程,從新啓動redis,數據被恢復回來。就是從aof文件中恢復回來的

redis進程啓動的時候,直接就會從appendonly.aof中加載日誌,把內存中的數據恢復回來。

三、AOF rewrite

redis中的數據其實有限的,不少數據可能會自動過時,可能會被用戶刪除,可能會被redis用緩存清除的算法清理掉

redis中的數據會不斷淘汰掉舊的,就一部分經常使用的數據會被自動保留在redis內存中

因此可能不少以前的已經被清理掉的數據,對應的寫日誌還停留在AOF中,AOF日誌文件就一個,會不斷的膨脹,到很大很大

因此AOF會自動在後臺每隔必定時間作rewrite操做,好比日誌裏已經存放了針對100w數據的寫日誌了; 

redis內存只剩下10萬; 基於內存中當前的10萬數據構建一套最新的日誌,到AOF中;

覆蓋以前的老日誌; 確保AOF日誌文件不會過大,保持跟redis內存數據量一致

redis 2.4以前,還須要手動,開發一些腳本,crontab,經過BGREWRITEAOF命令去執行AOF rewrite,可是redis 2.4以後,會自動進行rewrite操做

在redis.conf中,能夠配置rewrite策略

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

好比說上一次AOF rewrite以後,是128mb

而後就會接着128mb繼續寫AOF的日誌,若是發現增加的比例,超過了以前的100%,256mb,就可能會去觸發一次rewrite

可是此時還要去跟min-size,64mb去比較,256mb > 64mb,纔會去觸發rewrite

(1)redis fork一個子進程   

(2)子進程基於當前內存中的數據,構建日誌,開始往一個新的臨時的AOF文件中寫入日誌
(3)redis主進程,接收到client新的寫操做以後,在內存中寫入日誌,同時新的日誌也繼續寫入舊的AOF文件
(4)子進程寫完新的日誌文件以後,redis主進程將內存中的新日誌再次追加到新的AOF文件中
(5)用新的日誌文件替換掉舊的日誌文件

四、AOF破損文件的修復

若是redis在append數據到AOF文件時,機器宕機了,可能會致使AOF文件破損

用redis-check-aof --fix命令來修復破損的AOF文件

五、AOF和RDB同時工做

(1)若是RDB在執行snapshotting操做,那麼redis不會執行AOF rewrite; 若是redis再執行AOF rewrite,那麼就不會執行RDB snapshotting
(2)若是RDB在執行snapshotting,此時用戶執行BGREWRITEAOF命令,那麼等RDB快照生成以後,纔會去執行AOF rewrite
(3)同時有RDB snapshot文件和AOF日誌文件,那麼redis重啓的時候,會優先使用AOF進行數據恢復,由於其中的日誌更完整

(1)在有rdb的dump和aof的appendonly的同時,rdb裏也有部分數據,aof裏也有部分數據,這個時候其實會發現,rdb的數據不會恢復到內存中
(2)咱們模擬讓aof破損,而後fix,有一條數據會被fix刪除
(3)再次用fix得aof文件去重啓redis,發現數據只剩下一條了

數據恢復徹底是依賴於底層的磁盤的持久化的,主要rdb和aof上都沒有數據,那就沒了

 

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

在企業中,RDB的生成策略,用默認的也差很少

save 60 10000:若是你但願儘量確保說,RDB最多丟1分鐘的數據,那麼儘可能就是每隔1分鐘都生成一個快照,低峯期,數據量不多,也不必

10000->生成RDB,1000->RDB,這個根據你本身的應用和業務的數據量,你本身去決定

AOF必定要打開,fsync,everysec

auto-aof-rewrite-percentage 100: 就是當前AOF大小膨脹到超過上次100%,上次的兩倍
auto-aof-rewrite-min-size 64mb: 根據你的數據量來定,16mb,32mb

二、企業級的數據備份方案

RDB很是適合作冷備,每次生成以後,就不會再有修改了

數據備份方案

(1)寫crontab定時調度腳本去作數據備份

(2)每小時都copy一份rdb的備份,到一個目錄中去,僅僅保留最近48小時的備份

(3)天天都保留一份當日的rdb的備份,到一個目錄中去,僅僅保留最近1個月的備份

(4)每次copy備份的時候,都把太舊的備份給刪了

(5)天天晚上將當前服務器上全部的數據備份,發送一份到遠程的雲服務上去

目錄:/usr/local/redis

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

crontab -e

sh /usr/local/redis/copy/redis_rdb_copy_hourly.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一次備份

crontab -e

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

del_date=`date -d -1month +%Y%m%d`
rm -rf /usr/local/redis/snapshotting/$del_date

   天天一次將全部數據上傳一次到遠程的雲服務器上去

三、數據恢復方案

(1)若是是redis進程掛掉,那麼重啓redis進程便可,直接基於AOF日誌文件恢復數據

fsync everysec,最多就丟一秒的數

(2)若是是redis進程所在機器掛掉,那麼重啓機器後,嘗試重啓redis進程,嘗試直接基於AOF日誌文件進行數據恢復

AOF沒有破損,也是能夠直接基於AOF恢復的

AOF append-only,順序寫入,若是AOF文件破損,那麼用redis-check-aof fix

(3)若是redis當前最新的AOF和RDB文件出現了丟失/損壞,那麼能夠嘗試基於該機器上當前的某個最新的RDB數據副本進行數據恢復

當前最新的AOF和RDB文件都出現了丟失/損壞到沒法恢復,通常不是機器的故障,人爲

大數據系統,hadoop,有人不當心就把hadoop中存儲的大量的數據文件對應的目錄,rm -rf一下,/var/redis/6379下的文件給刪除了

找到RDB最新的一份備份,小時級的備份能夠了,小時級的確定是最新的,copy到redis裏面去,就能夠恢復到某一個小時的數據

 appendonly.aof + dump.rdb,優先用appendonly.aof去恢復數據,可是咱們發現redis自動生成的appendonly.aof是沒有數據的

咱們本身的dump.rdb是有數據的,可是明顯沒用咱們的數據

redis啓動的時候,自動從新基於內存的數據,生成了一份最新的rdb快照,直接用空的數據,覆蓋掉了咱們有數據的,拷貝過去的那份dump.rdb

中止redis以後,其實應該先刪除appendonly.aof,而後將咱們的dump.rdb拷貝過去,而後再重啓redis

刪除了appendonly.aof,可是由於打開了aof持久化,redis就必定會優先基於aof去恢復,即便文件不在,那就建立一個新的空的aof文件

中止redis,暫時在配置中關閉aof,而後拷貝一份rdb過來,再重啓redis,數據能不能恢復過來,能夠恢復過來

再關掉redis,手動修改配置文件,打開aof,再重啓redis,數據又沒了,空的aof文件,全部數據又沒了

在數據安全丟失的狀況下,基於rdb冷備,如何完美的恢復數據,同時還保持aof和rdb的雙開

正確方法:

1.中止redis,2.關閉aof,3.拷貝rdb備份,4.重啓redis,確認數據恢復,5.直接在命令行熱修改redis配置,打開aof,這個redis就會將內存中的數據對應的日誌,寫入aof文件中

此時aof和rdb兩份數據文件的數據就同步了

redis config set熱修改配置參數,可能配置文件中的實際的參數沒有被持久化的修改,再次中止redis,手動修改配置文件,打開aof的命令,再次重啓redis

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

(5)若是是發現有重大的數據錯誤,好比某個小時上線的程序一會兒將數據所有污染了,數據全錯了,那麼能夠選擇某個更早的時間點,對數據進行恢復

舉個例子,12點上線了代碼,發現代碼有bug,致使代碼生成的全部的緩存數據,寫入redis,所有錯了

找到一份11點的rdb的冷備,而後按照上面的步驟,去恢復到11點的數據,

相關文章
相關標籤/搜索