Redis筆記(一)-Redis持久化

Redis持久化

1、故障發生的時候會怎麼樣

2、如何應對故障的發生

redis的持久化,RDB,AOF,區別、工作機制,各自的特點是什麼,適合什麼場景。如何抉擇

redis的企業級的持久化方案是什麼,是用來跟哪些企業級的場景結合起來使用的???

 

如果想redis僅作爲純內存的緩存來用,可禁止RDB和AOF所有的持久化機制

 

Redis持久化的作用:

Redis所有的數據都保存在內存中,對數據的更新將異步地保存在磁盤上

 

Redis持久化與高可能有很大關係。

Redis持久化的意義:

在於數據備份和故障恢復。持久化主要是做災難恢復,數據恢復

部署一個redis作爲cache緩存,或保存一些較爲重要的數據

如果沒有持久化,redis遇到災難性故障時,由於redis數據存儲在內存中,就會丟失所有的數據

如果通過持久化將數據搞一份兒在磁盤上去,然後定期比如說同步和備份到一些雲存儲服務上去,就可以保證數據不丟失全部,還是可以恢復一部分數據回來的。

對於企業級的redis架構來說,持久化是不可減少的

企業級redis集羣架構:海量數據、高併發、高可用

 

Redis持久化的重要性-緩存雪崩

如redis不可用了,要做的事是讓redis儘快變得可用,重啓redis,儘快讓它對外提供服務,

如果沒做數據備份,這時redis啓動了也不可用,因爲數據都沒了。

有可能大量的請求過來,緩存全部無法命中,在redis裏找不到數據,這時緩存雪崩問題,所有請求,沒有在redis命中,就會去mysql數據庫這種數據源頭中去找,一下子mysql承接高併發,然後就掛了。

mysql掛掉,數據也就無法恢復到redis裏面去。redis的數據從mysql來。。。

 

如果把redis的持久化做好,備份和恢復方案做到企業級的程度,即使redis故障了,也可通過備份數據,快速恢復,一旦恢復立即對外提供服務。

 

 

緩存雪崩解決方案:

具體的完整的緩存雪崩的場景,還有企業級的解決方案,到後面講

Redis持久化和高可用是有關係的。企業級redis架構中去講解

 

 

持久化的方式:

  1. 快照(先把數據拷貝出來,做個備份):Mysql Dump 和 Redis RDB
  2. 日誌(某時某點的日誌記錄):MySQL Binlog和Hbase HLog和Redis AOF

PDB(快照)和AOF(日誌)

 

RDB和AOF兩種持久化機制的工作原理:

 

AOF日誌會越來越大。

Redis通過rewrite的機制,讓AOF文件不至於太龐大。就是大概是數據量多的時候,重寫一個新的,把不需要的剔除。

 

 

RDB和AOF兩種持久化機制的介紹:

RDB持久化機制:對redis中的數據執行週期性的持久化

AOF持久化機制:對每條寫入命令作爲日誌,以append-only的模式寫入一個日誌文件中,在redis重啓時,可通過回放AOF日誌中的寫入指令來重新構建整個數據集

 

RDB或AOF都可將redis內存中的數據給持久化到磁盤上面來,然後可將這些數據備份到雲服務器,如阿里雲。

如果redis掛了,服務器上的內存和磁盤上的數據都丟了,可從雲服務上拷貝回來之前的數據,放到指定的目錄中,然後重新啓動redis,redis就會自動根據持久化數據文件中的數據,去恢復內存中的數據,繼續對外提供服務。

 

注:如果同時用RDB和AOF兩種持久化機制,在redis重啓時,會用AOF來重新構建數據,因AOF中的數據更加完整

 

1、RDB(快照)持久化機制

1)工作流程

(1)redis根據配置嘗試去生成rdb快照文件

(2)fork一個子進程出來

(3)子進程嘗試將數據dump到臨時的rdb快照文件中

(4)完成rdb快照文件的生成之後,就替換之前的舊的快照文件

只有一個dump.rdb(二進制文件,可以直接載入),每次生成一個新的快照,會覆蓋之前的老快照

 

2)優點:

(1)適合做冷備:RDB會生成多個數據文件,每個數據文件都代表了某一時刻中redis的數據,這種多個數據文件的方式,適合做冷備,可以將這種完整的數據文件發送到一些遠程的安全存儲上去,如Amazon的S3雲服務,阿里雲的ODPS分佈式存儲上,以預定好的備份策略來定期備份redis中的數據

 

關於冷備:

RDB可以做冷備,生成多個文件,每個文件都代表了某一個時刻的完整的數據快照

AOF也可以做冷備,只有一個文件,但是可以每隔一定時間去copy一份這個文件出來

 

RDB做冷備,優勢在由redis去控制固定時長生成快照文件的事情,比較方便; ,在最壞的情況下,提供數據恢復的時候,速度比AOF快

AOF還需自己寫一些腳本去做這個事情,各種定時。

(2)RDB對redis對外提供的讀寫服務,影響小,可讓redis保持高性能,因爲redis主進程只需要fork一個子進程,讓子進程執行磁盤IO操作來進行RDB持久化即

RDB,每次寫,都是直接寫redis內存,只是在一定時,纔會將數據寫入磁盤中

AOF,每次都是要寫文件的,雖然可以快速寫入os cache中,但還是有一定的時間開銷,速度肯定比RDB略慢一些

 

(3)相對於AOF持久化機制來說,直接基於RDB數據文件來重啓和恢復redis進程,更加快速

AOF存放的指令日誌,做數據恢復時,要回放和執行所有的指令日誌來恢復出來內存中的所有數據

RDB,就是一份數據文件,恢復的時候,直接加載到內存中即可

 

結合上述優點,RDB特別適合做冷備份

 

3)缺點:

(1)丟失數據多:如果想在redis故障時,儘可能少的丟失數據,不及AOF。一般RDB數據快照文件是每隔5分鐘,或更長時間生成一次,一旦redis進程宕機,會丟失最近5分鐘的數據。丟失的數據可能比較多。

所以RDB不適合做第一優先的恢復方案,所以默認是採用AOF進行第一優先恢復

(2)RDB每次在fork子進程來執行RDB快照數據文件生成的時候,如果數據文件特別大,可能導致對客戶端提供的服務暫停數毫秒,或者甚至數秒。

一般不要讓RDB的間隔太長,否則每次生成的RDB文件太大,對redis本身的性能可能會有影響的

 

耗時、耗性能(大量消耗性能)。不可控、丟失數據(如果save過程中中途宕機,其他的數據就會丟失,即使是定時策略,也存在這種問題,因爲無法保證什麼時候宕機)。

 

 

4)配置RDB持久化:

redis.conf文件,也就是/etc/redis/6379.conf,去配置持久化

save 60 1000

每隔60s,如果超過1000個key發生了變更,就生成一個新的dump.rdb文件,當前redis內存中完整的數據快照,這個操作也被稱之爲snapshotting,快照

也可手動調用save或bgsave命令,同步或異步執行rdb快照生成

 

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

 

5)生成RDB文件的三種觸發方式:

Save(同步)、bgsave(異步)、自動

(1)save命令:複雜度:O(N)、不同步

文件策略:如果存在老的RDB文件,新的替換老的

(2)bgsave命令:文件策略和複雜度與save相同

兩種方式比較:

 

(3)配置文件配置的方式:配置文件配置save seconds changes。但是這樣無法控制save頻率。

最佳配置:

 

 

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

(1)在redis中保存幾條數據,立即停掉redis進程,然後重啓redis,看看剛纔插入的數據還在不在?

數據還在,爲什麼?

因爲通過redis-cli SHUTDOWN這種方式去停掉redis是一種安全退出的模式,redis在退出的時候會將內存中的數據立即生成一份完整的rdb快照

/var/redis/6379/dump.rdb

(2)在redis中再保存幾條新的數據,用kill -9粗暴殺死redis進程,模擬redis故障異常退出,導致內存數據丟失的場景。redis進程異常被殺掉,數據沒有進dump文件,幾條最新的數據就丟失了

(2)手動設置一個save檢查點,save 5 1   5秒鐘一次snapshotting

(3)寫入幾條數據,等待5秒鐘,會發現自動進行了一次dump rdb快照,在dump.rdb中發現了數據

(4)異常停掉redis進程,再重新啓動redis,看剛纔插入的數據還在

 

rdb的手動配置檢查點,以及rdb快照的生成,包括數據的丟失和恢復

 

7)總結

1.     RDB是Redis內存到硬盤的快照,用於持久化。

2.     save通常會阻塞Redis。影響其他客戶端連接時間。

3.     bgsave不會阻塞Redis ,但是會fork新進程。

4.     save自動配置滿足任一就會被執行。

5.     有些觸發機制不容忽視

 

2、AOF(日誌)持久化機制

以日誌的形式來記錄每個寫操作(讀操作不記錄),將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加文件但不可以改寫文件,redis啓動之初會讀取該文件重新構建數據,換言之,redis重啓的話就根據日誌文件的內容將寫指令從前到後執行一次以完成數據的恢復工作

 

•      開啓:默認AOF沒有開啓:appendonly no #如果要開啓,改爲yes

注意的是啓動的目錄和保存aof文件目錄是否一致

•      修復:使用redis-check-aof –fix 進行修復

•      恢復:重啓redis然後重新加載

5)AOF破損文件的修復

如果redis在append數據到AOF文件時,機器宕機了,可能會導致AOF文件破損

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

 

AOF默認名稱:appendonlyfilename   appendonly.aof

 

1)AOF工作原理與rewrite重寫機制

工作原理:

(1)redis fork一個子進程

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

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

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

(5)用新的日誌文件替換掉舊的日誌文件

 

重寫機制:把過期的,重複的,沒有用的,都丟掉,只留了有用的。減少磁盤的佔用量,加速恢復速度。

AOF採用文件追加方式,文件會越來越大爲避免出現此種情況,新增了重寫機制,當AOF文件的大小超過所設定的閾值時,Redis就會啓動AOF文件的內容壓縮,只保留可以恢復數據的最小指令集.可以使用命令bgrewriteaof

AOF文件持續增長而過大時,會fork出一條新進程來將文件重寫(也是先寫臨時文件最後再rename),

遍歷新進程的內存中數據,每條記錄有一條的Set語句。重寫aof文件的操作,並沒有讀取舊的aof文件,

而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點類似

Rewrite觸發機制:

Redis會記錄上次重寫時的AOF大小,默認配置是當AOF文件大小是上次rewrite後大小的一倍且文件大於64M時觸發。默認64M。

 

AOF日誌膨脹:

redis中的數據有限,很多數據或自動過期,或被用戶刪除,或被redis用緩存清除的算法清理掉。

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

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

 

解決方案-rewrite:

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。

 

2)優點:

(1)數據丟失少:AOF可更好的保護數據不丟失,一般AOF會每隔1秒,通過一個後臺線程執行一次fsync操作,保證os cache中的數據寫入磁盤中,最多丟失1秒鐘的數據

(2)AOF日誌文件以append-only模式寫入,所以沒有任何磁盤尋址的開銷,寫入性能非常高,而且文件不容易破損,即使文件尾部破損,也很容易修復(提供了工具)

(3)AOF日誌文件即使過大的時候,出現後臺重寫操作也不會影響客戶端的讀寫。因爲在rewrite log時,會對其中的指導進行壓縮,創建出一份需要恢復數據的最小日誌出來。再創建新日誌文件的時候,老的日誌文件還是照常寫入。當新的merge後的日誌文件ready的時候,再交換新老日誌文件即可。

(4)AOF日誌文件的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。如某人不小心用flushall命令清空了所有數據,只要這個時候後臺rewrite還沒有發生,那麼就可以立即拷貝AOF文件,將最後一條flushall命令給刪了,然後再將該AOF文件放回去,就可以通過恢復機制,自動恢復所有數據(很少使用到)

 

3)缺點:

(1)對於同一份數據來說,AOF日誌文件通常比RDB數據快照文件更大

(2)AOF開啓後,支持的寫QPS會比RDB支持的寫QPS低,因爲AOF一般會配置成每秒fsync一次日誌文件,當然,每秒一次fsync,性能也還是很高的。

如果要保證一條數據都不丟,可以AOF的fsync設置成每寫入一條數據,fsync一次,但這樣redis的QPS大降

(3)以前AOF發生過bug,就是通過AOF記錄的日誌,進行數據恢復的時候,沒有恢復一模一樣的數據出來。所以說,類似AOF這種較爲複雜的基於命令日誌/merge/回放的方式,比基於RDB每次持久化一份完整的數據快照文件的方式,更加脆弱一些,容易有bug。不過AOF就是爲了避免rewrite過程導致的bug,因此每次rewrite並不是基於舊的指令日誌進行merge的,而是基於當時內存中的數據進行指令的重新構建,這樣健壯性會好很多。

(4)唯一的比較大的缺點,其實就是做數據恢復的時候,會比較慢,還有做冷備,定期的備份,不太方便,可能要自己手寫複雜的腳本去做,做冷備不太合適

 

•      相同數據集的數據而言aof文件要遠大於rdb文件,恢復速度慢於rdb

•      aof運行效率要慢於rdb,每秒同步策略效率較好,不同步效率和rdb相同

 

4)AOF持久化的配置

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

appendonly yes,打開AOF持久化機制,在生產環境一般來說AOF都是打開的,除非允許隨便丟個幾分鐘的數據。

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

即使AOF和RDB都開啓了,redis重啓的時候,也是優先通過AOF進行數據恢復的,因爲aof數據比較完整

可以配置AOF的fsync策略,有三種策略,

1.always:每次寫入一條數據就執行一次fsync; 每次寫入一條數據,立即將這個數據對應的寫日誌fsync到磁盤上去,性能非常非常差,吞吐量很低; 確保redis裏的數據一條都不丟

2. everysec(默認): 每隔一秒執行一次fsync; 每秒將os cache中的數據fsync到磁盤,最常用的,生產環境一般都這麼配置,性能很高,QPS還是可以上萬的

3.no: 不主動執行fsync。僅僅redis負責將數據寫入os cache就撒手不管了,後面os自己會時不時有自己的策略將數據刷入磁盤,不可控了

 

mysql -> 內存策略,大量磁盤,QPS到一兩k。QPS,每秒鐘的請求數量

redis -> 內存,磁盤持久化,QPS到多少,單機,一般來說,上萬QPS沒問題

 

 

5)AOF日誌修改策略(3種):

三種appendfsysnc:同步策略:

•      每修改同步:appendfsync always 同步持久化 每次發生數據變更會被立即記錄到磁盤 性能較差但數據完整性比較好

•      每秒同步:appendfsync everysec(默認)異步操作,每秒記錄 如果一秒內宕機,有數據丟失

•      不同步:appendfsync no 從不同步

能保證保護硬盤。有可能會丟失數據

 

 

6)AOF重寫實現方式(2種):

一種是bgrewriteaof。一種是AOF重寫配置

AOF重寫配置:

多大後需要重寫

觸發時機:

自動觸發時機=

aof_current_size>auto-aof-rewrite-min-size&&(aof_current_size-aof_base_size)/aof_base_size>=auto-aof-rewrite-percentage

 

7)AOF持久化的數據恢復實驗

(1)先僅僅打開RDB,寫入一些數據,然後kill -9殺掉redis進程,重啓redis,發現數據沒了,因爲RDB快照還沒生成

(2)打開AOF的開關,啓用AOF持久化

(3)寫入一些數據,觀察AOF文件中的日誌內容

其實在appendonly.aof文件中,可以看到剛寫的日誌,它們其實就是先寫入os cache的,然後1秒後才fsync到磁盤中,只有fsync到磁盤中了,纔是安全的,要不然光是在os cache中,機器只要重啓,就什麼都沒了

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

 

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

 

總結:

•      AOF 文件是一個只進行追加的日誌文件

•      Redis可以在AOF文件體積變得過大時,自動地在後臺對AOF進行重寫

•      AOF文件有序地保存了對數據庫執行所有寫入操作,這些寫入操作作爲redis協議的格式保存,因此AOF文件的內容非常容易被人讀懂,對文件進行分析也很輕鬆

•      對於相同的數據集來說,AOF文件的體積通常大於RDB文件的體積,根據所使用的fsync策略,AOF的速度可能會慢於RDB

 

3、RDB和AOF如何選擇:

(1)不要僅僅使用RDB,因爲會導致丟失很多數據

(2)也不要僅僅使用AOF,因爲有兩個問題,

第一,通過AOF做冷備,沒有RDB做冷備,來的恢復速度更快;

第二,RDB每次簡單粗暴生成數據快照,更加健壯,可以避免AOF這種複雜的備份和恢復機制的bug

(3)綜合使用AOF和RDB兩種持久化機制,用AOF來保證數據不丟失,作爲數據恢復的第一選擇; 用RDB來做不同程度的冷備,在AOF文件都丟失或損壞不可用的時候,還可以使用RDB來進行快速的數據恢復

 

只做緩存:如果你只希望你的數據在服務器運行的時候存在,你也可以不使用任何持久化方式.

同時開啓兩種持久化方式 
–在這種情況下,當redis重啓的時候會優先載入AOF文件來恢復原始的數據, 因爲在通常情況下AOF文件保存的數據集要比RDB文件保存的數據集要完整. 
–RDB的數據不實時,同時使用兩者時服務器重啓也只會找AOF文件。那要不要只使用AOF呢? 

不要,因爲RDB更適合用於備份數據庫(AOF在不斷變化不好備份), 快速重啓,而且不會有AOF可能潛在的bug,留着作爲一個萬一的手段。

 

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進行數據恢復,因爲其中的日誌更完整

 

Q:同時出現RDB和AOF是衝突呢?還是協作?

協作,不會衝突! 那麼是如何協作,首先加載哪一個文件呢?

進行測試,生成dump.rdb和appendonly.aof文件,然後在appendonly.aof使文件最後隨便加入一些東西,使文件出錯,然後重新啓動redis服務,發現服務沒有啓動成功!那麼就可以知道首先加載的是aof文件,使用redis-check-aof 工具修復aof文件,重新啓動,發現啓動成功!

總結:兩者可以共存,但是首先啓動找的是aof。

當redis服務器掛掉時,重啓時將按照以下優先級恢復數據到內存:

如果只配置AOF,重啓時加載AOF文件恢復數據;

如果同時 配置了RBD和AOF,啓動是隻加載AOF文件恢復數據;

如果只配置RBD,啓動是講加載dump文件恢復數據。

恢復時需要注意,要是主庫掛了不能直接重啓主庫,否則會直接覆蓋掉從庫的AOF文件,一定要確保要恢復的文件都正確才能啓動,否則會沖掉原來的文件。

如何修復:redis-check-aof –fix appendonly.aof

 

 

 

 

持久化恢復:

查看日誌

看到有臨時子進程

一段時間後就沒了子進程

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章