三、Redis的持久化

1、RDB(Redis DataBase)

基本介紹

在指定的時(shí)間間隔內(nèi),將內(nèi)存中的數(shù)據(jù)集快照寫(xiě)入磁盤(pán),也就是Snapshot快照,它恢復(fù)時(shí)是將快照文件直接讀取到內(nèi)存里。

快照文件默認(rèn)被存儲(chǔ)在當(dāng)前文件夾中,名稱為dump.rdb,可以通過(guò)dir和dbfilename參數(shù)來(lái)修改默認(rèn)值。

Redis會(huì)單獨(dú)創(chuàng)建(fork)一個(gè)子進(jìn)程來(lái)進(jìn)行持久化,會(huì)先將數(shù)據(jù)寫(xiě)入到一個(gè)臨時(shí)文件中,待持久化過(guò)程都結(jié)束了,再用這個(gè)臨時(shí)文件替換上次持久化好的文件。整個(gè)過(guò)程中,主進(jìn)程是不進(jìn)行任何的IO操作的,這就確保了極高的性能。

Fork

fork的作用相當(dāng)于復(fù)制一個(gè)與當(dāng)前進(jìn)程一樣的進(jìn)程。但是是一個(gè)全新的進(jìn)程,并作為原進(jìn)程的子進(jìn)程。

配置文件

# redis是基于內(nèi)存的數(shù)據(jù)庫(kù),可以通過(guò)設(shè)置該值定期寫(xiě)入磁盤(pán)。 
# 注釋掉“save”這一行配置項(xiàng)就可以讓保存數(shù)據(jù)庫(kù)功能失效 
# 900秒(15分鐘)內(nèi)至少1個(gè)key值改變(則進(jìn)行數(shù)據(jù)庫(kù)保存--持久化) 
# 300秒(5分鐘)內(nèi)至少10個(gè)key值改變(則進(jìn)行數(shù)據(jù)庫(kù)保存--持久化) 
# 60秒(1分鐘)內(nèi)至少10000個(gè)key值改變(則進(jìn)行數(shù)據(jù)庫(kù)保存--持久化) 
save 900 1 
save 300 10 
save 60 10000 

#當(dāng)RDB持久化出現(xiàn)錯(cuò)誤后,是否依然進(jìn)行繼續(xù)進(jìn)行工作,
#yes:不能進(jìn)行工作,no:可以繼續(xù)進(jìn)行工作,可以通過(guò)info中的rdb_last_bgsave_status了解RDB持久化是否有錯(cuò)誤 
stop-writes-on-bgsave-error yes 

#使用壓縮rdb文件,rdb文件壓縮使用LZF壓縮算法,
#yes:壓縮,但是需要一些cpu的消耗。no:不壓縮,需要更多的磁盤(pán)空間 
rdbcompression yes 

#是否校驗(yàn)rdb文件。從rdb格式的第五個(gè)版本開(kāi)始,在rdb文件的末尾會(huì)帶上CRC64的校驗(yàn)和。
#這跟有利于文件的容錯(cuò)性,但是在保存rdb文件的時(shí)候,會(huì)有大概10%的性能損耗,所以如果你追求高性能,可以關(guān)閉該配置。 
rdbchecksum yes 

#rdb文件的名稱 
dbfilename dump.rdb 

#數(shù)據(jù)目錄,數(shù)據(jù)庫(kù)的寫(xiě)入會(huì)在這個(gè)目錄。rdb、aof文件也會(huì)寫(xiě)在這個(gè)目錄 
dir /data

觸發(fā)條件

(1)配置文件中默認(rèn)的快照配置(可自行修改)
一般會(huì)將主機(jī)中的dump.rdb文件拷貝到備機(jī)中,防止主機(jī)損壞無(wú)法恢復(fù)數(shù)據(jù),冷拷貝后重新使用(可以cp dump.rdb dump_new.rdb)

    save 900 1
    save 300 10
    save 60 10000

1分鐘key變化一萬(wàn)次,5分鐘key變化10次,15分鐘key變化1次,就會(huì)生成dump.rdb文件。

(2)手動(dòng)通過(guò)save和bgsave命令

  1. save:save時(shí)只管保存,其他不管,全部阻塞
  2. bgsave:redis會(huì)在后臺(tái)異步的進(jìn)行快照操作,同時(shí)還可以響應(yīng)客戶端請(qǐng)求??梢酝ㄟ^(guò)lastsave命令獲取最后一次成功執(zhí)行快照的事件

(3)執(zhí)行flushall和shutdown命令

  1. flushall命令,也會(huì)產(chǎn)生dump.rdb文件,但里面是空的,無(wú)意義。
  2. shutdown命令,安全退出,也會(huì)生成快照文件(和異常退出形成對(duì)比,比如:kill殺死進(jìn)程的方式)

如何恢復(fù)

appendonly no
dbfilename dump.rdb
dir /var/lib/redis  #可以自行指定

appendonly 設(shè)置成no,redis啟動(dòng)時(shí)會(huì)把/var/lib/redis 目錄下的dump.rdb 中的數(shù)據(jù)恢復(fù)。dir 和dbfilename 都可以設(shè)置。若將appendonly 設(shè)置成yes ,則不會(huì)恢復(fù)dump.rdb文件中的數(shù)據(jù)。

將備份文件(dump.rdb)移動(dòng)到redis安裝目錄并啟動(dòng)服務(wù)即可,使用CONFIG GET dir 命令獲取目錄。

優(yōu)勢(shì)

  1. 恢復(fù)數(shù)據(jù)的速度很快,適合大規(guī)模的數(shù)據(jù)恢復(fù),而又對(duì)部分?jǐn)?shù)據(jù)不敏感的情況;
  2. dump.db文件是一個(gè)壓縮的二進(jìn)制文件,文件暫用空間小。

劣勢(shì)

  1. 當(dāng)出現(xiàn)異常退出時(shí),會(huì)丟失最后一次快照后的數(shù)據(jù);
  2. 當(dāng)fork時(shí),內(nèi)存中的數(shù)據(jù)會(huì)被克隆一份,大致兩倍的膨脹需要考慮。而且,當(dāng)數(shù)據(jù)過(guò)大時(shí),fork操作占用過(guò)多的系統(tǒng)資源,造成主服務(wù)器進(jìn)程假死。

使用場(chǎng)景

  1. 數(shù)據(jù)備份
  2. 可容忍部分?jǐn)?shù)據(jù)丟失
  3. 跨數(shù)據(jù)中心的容災(zāi)備份

小總結(jié)

2、AOF(Append Only File)

基本介紹

以日志的形式來(lái)記錄每個(gè)寫(xiě)操作,將Redis執(zhí)行過(guò)的所有寫(xiě)指令記錄下來(lái),只許追加文件但不可以改寫(xiě)文件,redis啟動(dòng)之初會(huì)讀取改文件重新構(gòu)建數(shù)據(jù)。保存的是appendonly.aof文件

aof機(jī)制默認(rèn)關(guān)閉,可以通過(guò)appendonly = yes參數(shù)開(kāi)啟aof機(jī)制,通過(guò)appendfilename = myaoffile.aof指定aof文件名稱。

配置文件

#默認(rèn)redis使用的是rdb方式持久化,這種方式在許多應(yīng)用中已經(jīng)足夠用了。
#但是redis如果中途宕機(jī),會(huì)導(dǎo)致可能有幾分鐘的數(shù)據(jù)丟失,根據(jù)save來(lái)策略進(jìn)行持久化,
#Append Only File是另一種持久化方式,可以提供更好的持久化特性。
#Redis會(huì)把每次寫(xiě)入的數(shù)據(jù)在接收后都寫(xiě)入 appendonly.aof 文件,
#每次啟動(dòng)時(shí)Redis都會(huì)先把這個(gè)文件的數(shù)據(jù)讀入內(nèi)存里,先忽略RDB文件。 
appendonly no 

#aof文件名 
appendfilename "appendonly.aof" 

#aof持久化策略的配置
#no表示不執(zhí)行fsync,由操作系統(tǒng)保證數(shù)據(jù)同步到磁盤(pán),速度最快。
#always表示每次寫(xiě)入都執(zhí)行fsync,以保證數(shù)據(jù)同步到磁盤(pán)。
#everysec表示每秒執(zhí)行一次fsync,可能會(huì)導(dǎo)致丟失這1s數(shù)據(jù)。
appendfsync everysec

重寫(xiě)Rewrite是什么?
AOF采用文件追加方式,文件會(huì)越來(lái)越大,為避免出現(xiàn)此種情況,新增了重寫(xiě)機(jī)制,當(dāng)AOF文件的大小超過(guò)所設(shè)定的閾值時(shí),Redis就會(huì)啟動(dòng)AOF文件的內(nèi)容壓縮,只保留可以恢復(fù)數(shù)據(jù)的最小指令集,可以使用命令bgrewriteaof。

重寫(xiě)觸發(fā)機(jī)制:
Redis 會(huì)記錄上次重寫(xiě)時(shí)的AOF大小,默認(rèn)配置是當(dāng)AOF文件大小是上次rewrite后大小的一倍,且文件大于64M時(shí)觸發(fā)。

重寫(xiě)時(shí)是否可以運(yùn)用持久化追加(Appendfsync),用默認(rèn)no即可no-appendfsync-on-rewrite no,保證數(shù)據(jù)安全性。

#aof自動(dòng)重寫(xiě)配置。
#當(dāng)目前aof文件大小超過(guò)上一次重寫(xiě)的aof文件大小的百分之多少進(jìn)行重寫(xiě),
#即當(dāng)aof文件增長(zhǎng)到一定大小的時(shí)候Redis能夠調(diào)用bgrewriteaof對(duì)日志文件進(jìn)行重寫(xiě)。
#當(dāng)前AOF文件大小是上次日志重寫(xiě)得到AOF文件大小的二倍(設(shè)置為100)時(shí),自動(dòng)啟動(dòng)新的日志重寫(xiě)過(guò)程。
auto-aof-rewrite-percentage 100

# 設(shè)置允許重寫(xiě)的最小aof文件大小,避免了達(dá)到約定百分比但尺寸仍然很小的情況還要重寫(xiě)
auto-aof-rewrite-min-size 64mb

# 在aof重寫(xiě)或者寫(xiě)入rdb文件的時(shí)候,會(huì)執(zhí)行大量IO,此時(shí)對(duì)于everysec和always的aof模式來(lái)說(shuō),
#執(zhí)行fsync會(huì)造成阻塞過(guò)長(zhǎng)時(shí)間,no-appendfsync-on-rewrite字段設(shè)置為默認(rèn)設(shè)置為no,
#是最安全的方式,不會(huì)丟失數(shù)據(jù),但是要忍受阻塞的問(wèn)題。如果對(duì)延遲要求很高的應(yīng)用,
#這個(gè)字段可以設(shè)置為yes,設(shè)置為yes表示rewrite期間對(duì)新寫(xiě)操作不fsync,暫時(shí)存在內(nèi)存中,
#不會(huì)造成阻塞的問(wèn)題(因?yàn)闆](méi)有磁盤(pán)競(jìng)爭(zhēng)),等rewrite完成后再寫(xiě)入,這個(gè)時(shí)候redis會(huì)丟失數(shù)據(jù)。
#Linux的默認(rèn)fsync策略是30秒??赡軄G失30秒數(shù)據(jù)。因此,如果應(yīng)用系統(tǒng)無(wú)法忍受延遲,
#而可以容忍少量的數(shù)據(jù)丟失,則設(shè)置為yes。如果應(yīng)用系統(tǒng)無(wú)法忍受數(shù)據(jù)丟失,則設(shè)置為no。
no-appendfsync-on-rewrite no

如何恢復(fù)

(1)正?;謴?fù)
將文件放到dir指定的文件夾下,當(dāng)redis啟動(dòng)的時(shí)候會(huì)自動(dòng)加載數(shù)據(jù),注意:aof文件的優(yōu)先級(jí)比dump大。

(2)異?;謴?fù)

  • 有些操作可以直接到appendonly.aof文件里去修改。
    eg:使用了flushall這個(gè)命令,此刻持久化文件中就會(huì)有這么一條命令記錄,把它刪掉就可以了
  • 寫(xiě)壞的文件可以通過(guò) redis-check-aof --fix進(jìn)行修復(fù)

優(yōu)勢(shì)

  1. 根據(jù)不同的策略,可以實(shí)現(xiàn)每秒,每一次修改操作的同步持久化,就算在最?lèi)毫拥那闆r下只會(huì)丟失不會(huì)超過(guò)兩秒數(shù)據(jù)。
  2. 當(dāng)文件太大時(shí),會(huì)觸發(fā)重寫(xiě)機(jī)制,確保文件不會(huì)太大。
  3. 文件可以簡(jiǎn)單的讀懂

劣勢(shì)

  1. aof文件的大小太大,就算有重寫(xiě)機(jī)制,但重寫(xiě)所造成的阻塞問(wèn)題是不可避免,aof文件恢復(fù)速度慢于rdb
  2. aof運(yùn)行效率要慢于rdb,每秒同步策略效率較好,不同步效率和rdb相同

小總結(jié)

3、Redis的持久化總結(jié)

  • RDB持久化方式能夠在指定的時(shí)間間隔內(nèi)對(duì)你的數(shù)據(jù)進(jìn)行快照存儲(chǔ)。

  • AOF持久化方式記錄每次對(duì)服務(wù)器寫(xiě)的操作,當(dāng)服務(wù)器重啟時(shí)會(huì)重新執(zhí)行這些命令來(lái)恢復(fù)原始的數(shù)據(jù),AOF命令以redis協(xié)議追加保存每次寫(xiě)的操作到文件末尾。Redis還能對(duì)AOF文件進(jìn)行后臺(tái)重寫(xiě),使得AOF文件的體積不至于過(guò)大。

  • 只做緩存:如果你只希望你的數(shù)據(jù)在服務(wù)器運(yùn)行的時(shí)候存在,可以不使用任何的持久化方式。

  • 一般建議同時(shí)開(kāi)啟兩種持久化方式。
    這種情況下,當(dāng)redis重啟時(shí)會(huì)優(yōu)先載入AOF文件來(lái)恢復(fù)原始的數(shù)據(jù),因?yàn)樵谕ǔG闆r下AOF文件保存的數(shù)據(jù)集比RDB文件保存的數(shù)據(jù)集要完整。
    RDB更適合用于備份數(shù)據(jù)庫(kù)(AOF在不斷變化不好備份),快速重啟,而且不會(huì)有AOF可能潛在的bug,留著一個(gè)做萬(wàn)一的手段。

  • 性能建議:
    因?yàn)镽DB文件只用做后備用途,建議只在Slave上持久化RDB文件,而且只要在15分鐘備份一次就行,只保留save 900 1這條規(guī)則。

    如果Enalbe AOF,好處是在最?lèi)毫忧闆r下也只會(huì)丟失不超過(guò)兩秒數(shù)據(jù),啟動(dòng)腳本較簡(jiǎn)單只load自己的AOF文件就可以了。代價(jià):一是帶來(lái)了持續(xù)的IO;二是AOF rewrite的最后將rewrite過(guò)程中產(chǎn)生的新數(shù)據(jù)寫(xiě)到新文件造成的阻塞幾乎是不可避免的。只要硬盤(pán)許可,應(yīng)該盡量減少AOF rewrite的頻率,AOF重寫(xiě)的基礎(chǔ)大小默認(rèn)值64M太小了,可以設(shè)到5G以上。默認(rèn)超過(guò)原大小100%大小時(shí)重寫(xiě)可以改到適當(dāng)?shù)臄?shù)值。

    如果不Enable AOF,僅靠Master-Slave Replication 實(shí)現(xiàn)高可用性也可以。能省掉一大筆IO也減少了rewrite時(shí)帶來(lái)的系統(tǒng)波動(dòng)。代價(jià)是如果Master/Slave同時(shí)宕掉,會(huì)丟失10幾分鐘的數(shù)據(jù),啟動(dòng)腳本也要比較兩個(gè)Master/Slave中的RDB文件,載入較新的那個(gè)。新浪微博就選用了這種架構(gòu)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容