redis的持久化

redis持久化一般支持兩種方式,快照持久化(rdb)和日志持久化(aof)

rdb持久化

1. rdb的配置選項
save 900 1   900秒內(nèi),有一條寫入,則產(chǎn)生快照

save 300   300秒內(nèi),有1000次寫入,則產(chǎn)生快照

save 60 10000   如果60秒內(nèi)有10000次寫入,則產(chǎn)生快照

這三個選項如果都屏蔽,則rdb禁用
stop-writes-on-bgsave-error yes  后臺備份進(jìn)程出錯時,主進(jìn)程停不停止寫入

rdbcompression yes   導(dǎo)出的rdb文件是否壓縮

rdbchecksum yes  導(dǎo)入rdb恢復(fù)數(shù)據(jù)時,要不要檢測rdb的完整性

dbfilename dump.rdb  導(dǎo)出來的rdb文件名

dir ./  rdb的放置路徑
2. 快照生成原理

Redis借助了fork命令的copy on write機(jī)制。在生成快照時,將當(dāng)前進(jìn)程fork出一個子進(jìn)程,然后在子進(jìn)程中循環(huán)所有的數(shù)據(jù),將數(shù)據(jù)寫成為RDB文件。

3. Client 也可以使用save或者bgsave命令通知redis做一次快照持久化。

save操作是在主線程中保存快照的,由于redis是用一個主線程來處理所有 client的請求,這種方式會阻塞所有client請求。所以不推薦使用。另一點需要注意的是,每次快照持久化都是將內(nèi)存數(shù)據(jù)完整寫入到磁盤一次,并不 是增量的只同步臟數(shù)據(jù)。如果數(shù)據(jù)量大的話,而且寫操作比較多,必然會引起大量的磁盤io操作,可能會嚴(yán)重影響性能。
Redis的RDB文件不會壞掉,因為其寫操作是在一個新進(jìn)程中進(jìn)行的。當(dāng)生成一個新的RDB文件時,Redis生成的子進(jìn)程會先將數(shù)據(jù)寫到一個臨時文件中,然后通過原子性rename系統(tǒng)調(diào)用將臨時文件重命名為RDB文件。這樣在任何時候出現(xiàn)故障,Redis的RDB文件都總是可用的。并且Redis的RDB文件也是Redis主從同步內(nèi)部實現(xiàn)中的一環(huán):

4. 快照持久化過程

1).redis調(diào)用fork,現(xiàn)在有了子進(jìn)程和父進(jìn)程。

2).父進(jìn)程繼續(xù)處理client請求,子進(jìn)程負(fù)責(zé)將內(nèi)存內(nèi)容寫入到臨時文件。由于os的寫時復(fù)制機(jī)制(copy on write)父子進(jìn)程會共享相同的物理頁面,當(dāng)父進(jìn)程處理寫請求時os會為父

進(jìn)程要修改的頁面創(chuàng)建副本,而不是寫共享的頁面。所以子進(jìn)程的地址空間內(nèi)的數(shù) 據(jù)是fork時刻整個數(shù)據(jù)庫的一個快照。

3).當(dāng)子進(jìn)程將快照寫入臨時文件完畢后,用臨時文件替換原來的快照文件,然后子進(jìn)程退出。

5. rdb的不足

就是一旦數(shù)據(jù)庫出現(xiàn)問題,那么我們的RDB文件中保存的數(shù)據(jù)并不是全新的,從上次RDB文件生成到Redis停機(jī)這段時間的數(shù)據(jù)全部丟掉了(因為刷寫機(jī)制還沒有發(fā)出)。RDB就是Snapshot快照存儲,是默認(rèn)的持久化方式。

aof持久化

1. aof持久化相關(guān)參數(shù)

 appendonly no # 是否打開 aof日志功能

appendfsync always   # 每1個命令,都立即同步到aof. 安全,速度慢

appendfsync everysec # 折衷方案,每秒寫1次

appendfsync no      # 寫入工作交給操作系統(tǒng),由操作系統(tǒng)判斷緩沖區(qū)大小,統(tǒng)一寫入到aof. 同步頻率低,速度快,

no-appendfsync-on-rewrite  yes: # 正在導(dǎo)出rdb快照的過程中,要不要停止同步aof

auto-aof-rewrite-percentage 100 #aof文件大小比起上次重寫時的大小,增長率100%時,重寫

auto-aof-rewrite-min-size 64mb #aof文件,至少超過64M時,重寫
2. AOF(Append Only File)<二進(jìn)制文件>比RDB方式有更好的持久化性。

由于在使用AOF持久化方式時,Redis會將每一個收到的寫命令都通過Write函數(shù)追加到文件最后,類似于MySQL的binlog。當(dāng)Redis重啟是會通過重新執(zhí)行文件中保存的寫命令來在內(nèi)存中重建整個數(shù)據(jù)庫的內(nèi)容。

AOF的完全持久化方式同時也帶來了另一個問題,持久化文件會變得越來越大。(比如我們調(diào)用INCR test命令100次,文件中就必須保存全部的100條命令,但其實99條都是多余的。因為要恢復(fù)數(shù)據(jù)庫的狀態(tài)其實文件中保存一條SET test 100就夠了)。為了合并重寫AOF的持久化文件,Redis提供了bgrewriteaof命令。收到此命令后Redis將使用與快照類似的方式將內(nèi)存中的數(shù)據(jù)以命令的方式保存到臨時文件中,最后替換原來的文件,以此來實現(xiàn)控制AOF文件的合并重寫。由于是模擬快照的過程,因此在重寫AOF文件時并沒有讀取舊的AOF文件,而是將整個內(nèi)存中的數(shù)據(jù)庫內(nèi)容用命令的方式重寫了一個新的AOF文件。

3. AOF持久化過程:

1). redis調(diào)用fork ,現(xiàn)在有父子兩個進(jìn)程
2). 子進(jìn)程根據(jù)內(nèi)存中的數(shù)據(jù)庫快照,往臨時文件中寫入重建數(shù)據(jù)庫狀態(tài)的命令
3).父進(jìn)程繼續(xù)處理client請求,除了把寫命令寫入到原來的aof文件中。同時把收到的寫命令緩存起來。這樣就能保證如果子進(jìn)程重寫失敗的話并不會出問題。
4).當(dāng)子進(jìn)程把快照內(nèi)容寫入已命令方式寫到臨時文件中后,子進(jìn)程發(fā)信號通知父進(jìn)程。然后父進(jìn)程把緩存的寫命令也寫入到臨時文件。
5).現(xiàn)在父進(jìn)程可以使用臨時文件替換老的aof文件,并重命名,后面收到的寫命令也開始往新的aof文件中追加。

兩者的區(qū)別

從上面看出,RDB和AOF操作都是順序IO操作,性能都很高。而同時在通過RDB文件或者AOF日志進(jìn)行數(shù)據(jù)庫恢復(fù)的時候,也是順序的讀取數(shù)據(jù)加載到內(nèi)存中。所以也不會造成磁盤的隨機(jī)讀。

到底選擇什么呢?下面是來自官方的建議:

通常,如果你要想提供很高的數(shù)據(jù)保障性,那么建議你同時使用兩種持久化方式。如果你可以接受災(zāi)難帶來的幾分鐘的數(shù)據(jù)丟失,那么你可以僅使用RDB。

很多用戶僅使用了AOF,但是我們建議,既然RDB可以時不時的給數(shù)據(jù)做個完整的快照,并且提供更快的重啟,所以最好還是也使用RDB。

在數(shù)據(jù)恢復(fù)方面:

RDB的啟動時間會更短,原因有兩個:

一是RDB文件中每一條數(shù)據(jù)只有一條記錄,不會像AOF日志那樣可能有一條數(shù)據(jù)的多次操作記錄。所以每條數(shù)據(jù)只需要寫一次就行了。

另一個原因是RDB文件的存儲格式和Redis數(shù)據(jù)在內(nèi)存中的編碼格式是一致的,不需要再進(jìn)行數(shù)據(jù)編碼工作,所以在CPU消耗上要遠(yuǎn)小于AOF日志的加載。
注意:
上面說了RDB快照的持久化,需要注意:在進(jìn)行快照的時候(save),fork出來進(jìn)行dump操作的子進(jìn)程會占用與父進(jìn)程一樣的內(nèi)存,真正的copy-on-write,對性能的影響和內(nèi)存的耗用都是比較大的。比如機(jī)器8G內(nèi)存,Redis已經(jīng)使用了6G內(nèi)存,這時save的話會再生成6G,變成12G,大于系統(tǒng)的8G。這時候會發(fā)生交換;要是虛擬內(nèi)存不夠則會崩潰,導(dǎo)致數(shù)據(jù)丟失。所以在用redis的時候一定對系統(tǒng)內(nèi)存做好容量規(guī)劃。

目前,通常的設(shè)計思路是利用Replication機(jī)制來彌補(bǔ)aof、snapshot性能上的不足,達(dá)到了數(shù)據(jù)可持久化。即Master上Snapshot和AOF都不做,來保證Master的讀寫性能,而Slave上則同時開啟Snapshot和AOF來進(jìn)行持久化,保證數(shù)據(jù)的安全性。

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

相關(guān)閱讀更多精彩內(nèi)容

  • Redis 提供了多種不同級別的持久化方式: 了解 RDB 持久化和 AOF 持久化之間的異同是非常重要的, 以下...
    笑Skr人啊閱讀 511評論 0 1
  • redis有兩種持久化方案: RDB:以指定時間間隔對數(shù)據(jù)集進(jìn)行備份(全量備份); AOF:AOF模式記錄serv...
    AlanSun2閱讀 663評論 0 1
  • 一、Redis高可用概述 在介紹Redis高可用之前,先說明一下在Redis的語境中高可用的含義。 我們知道,在w...
    空語閱讀 1,678評論 0 2
  • ??因為Redis是內(nèi)存數(shù)據(jù)庫,它將自己的數(shù)據(jù)庫狀態(tài)存儲在內(nèi)存當(dāng)中,所以如果不想辦法將存儲在內(nèi)存中的數(shù)據(jù)庫狀態(tài)保存...
    紙中圓閱讀 1,552評論 0 0
  • 打卡日期:2018年8月20日 打卡累計天數(shù):6/30 #宣言(專注腳下的路)# 第一個30天目標(biāo): 孩子 : 1...
    又媽悅之閱讀 254評論 0 0

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