[TOC]
1. Redis持久化
redis提供了多種持久化方式:
- none:沒有使用任何持久化方式,當(dāng)redis實(shí)例停止后,redis中的全部數(shù)據(jù)丟失。使用none就是將數(shù)據(jù)存儲(chǔ)在內(nèi)存和硬盤的臨時(shí)文件中。
- RDB:快照模式绿贞,redis在間隔指定的時(shí)間間隔,對(duì)全部數(shù)據(jù)做快照橘原,然后使用新的快照替換舊的快照籍铁。redis實(shí)例重啟后,會(huì)直接按照最新的快照恢復(fù)數(shù)據(jù)趾断。
- AOF:日志模式拒名,redis將受到的全部的命令,按照一定的協(xié)議芋酌,存儲(chǔ)進(jìn)入日志文件增显。當(dāng)日志文件達(dá)到一定的條件,redis會(huì)進(jìn)行后臺(tái)重寫脐帝,保證AOF的日志文件不會(huì)太大同云。
- 混合模式:可以同時(shí)開啟RDB和AOF模式,這樣redis的所有操作都被記錄堵腹,而且每隔指定的時(shí)間炸站,都會(huì)做快照。redis在重啟后疚顷,會(huì)優(yōu)先使用AOF的日志文件進(jìn)行恢復(fù)旱易,因?yàn)锳OF的日志記錄的數(shù)據(jù)比RDB的快照文件記錄的數(shù)據(jù)更加全面。
RDB只記錄了某一時(shí)間點(diǎn)的數(shù)據(jù)。AOF記錄了某一段時(shí)間的數(shù)據(jù)變化咒唆。
從時(shí)間上來說,RDB是一個(gè)時(shí)間點(diǎn)的數(shù)據(jù)释液,AOF是時(shí)間段的數(shù)據(jù)全释。
從行為上來說,RDB是靜態(tài)記錄數(shù)據(jù)误债,AOF是動(dòng)態(tài)記錄數(shù)據(jù)浸船。
2. RDB 的優(yōu)點(diǎn)
- RDB數(shù)據(jù)非常緊湊,它保存了某個(gè)時(shí)間點(diǎn)的全部數(shù)據(jù)寝蹈,所以非常適合用于數(shù)據(jù)集的備份李命。
- RDB數(shù)據(jù)擁有全部數(shù)據(jù),同時(shí)又很緊湊箫老,所以封字,很方便將RDB文件從一個(gè)機(jī)器傳輸?shù)狡渌麢C(jī)器。耍鬓,適合災(zāi)難恢復(fù)阔籽。
- RDB在保存快照文件的時(shí)候,父進(jìn)程會(huì)fork出一個(gè)子進(jìn)程牲蜀,接下來保存快照文件的全部工作由子進(jìn)程來做笆制,父進(jìn)程不需要參與保存快照文件的過程,所以RDB持久化方式可以最大化redis性能涣达。
- 與AOF相比在辆,RDB在恢復(fù)大量數(shù)據(jù)的時(shí)候比較快。
3. RDB 的缺點(diǎn)
- RDB在運(yùn)行的時(shí)候會(huì)造成少量數(shù)據(jù)的丟失:比如每隔1小時(shí)備份一次度苔,那么在兩次備份中間匆篓,redis宕機(jī),在宕機(jī)與上次備份期間的數(shù)據(jù)全部丟失林螃。
- RDB每次做快照奕删,需要保存全部的數(shù)據(jù),這是一個(gè)非常繁重的工作疗认。而且99%的備份都不會(huì)使用到完残,但是卻不能不做這個(gè)工作。(換句話說横漏,當(dāng)沒有宕機(jī)時(shí)谨设,這個(gè)工作沒有價(jià)值;但是當(dāng)出現(xiàn)宕機(jī)缎浇,這個(gè)工作的價(jià)值100%)
- RDB保存快照是交給子線程做的扎拣,當(dāng)數(shù)據(jù)量比較大的時(shí)候,fork的過程就比較耗時(shí),會(huì)造成fork時(shí)二蓝,輕微的卡頓(類似jvm的fill gc)誉券。
4. AOF 的優(yōu)點(diǎn)
- 使用AOF可以保證最全的數(shù)據(jù):AOF可以配置fsync策略:無fsync,每秒fsync刊愚,寫fsync踊跟。默認(rèn)是每秒fsync的策略,表示每隔1秒就會(huì)將過去1秒的操作追加到AOF文件中鸥诽。即使redis發(fā)生宕機(jī)商玫,最多丟失1秒的數(shù)據(jù)。
- fsync是由后臺(tái)進(jìn)程完成的牡借,對(duì)主線程幾乎沒有影響拳昌。
- AOF文件是一個(gè)只進(jìn)行追加的日志文件,所以即使在追加的過程中發(fā)生宕機(jī)钠龙,也可以使用redis-check-aof工具進(jìn)行修復(fù)炬藤。
- AOF文件重寫:每當(dāng)redis發(fā)生寫入操作時(shí),1秒后碴里,這些操作就會(huì)被寫入AOF文件中刻像,那么隨著時(shí)間的流逝,AOF會(huì)越來越大并闲。當(dāng)AOF增加到一定程度時(shí)细睡,會(huì)觸發(fā)redis重寫操作。redis重寫會(huì)只保留當(dāng)前數(shù)據(jù)集的最小命令操作集帝火。==比如 set x 7 ,set x 8等多條命令溜徙,只會(huì)保留最后一個(gè)。==在新的AOF創(chuàng)建完成之前犀填,命令都是追加到原AOF文件中的孕讳,當(dāng)原AOF重寫成功牵舱,會(huì)切換到新的AOF文件蛙埂,用新的AOF文件替換舊的AOF文件室琢。
- AOF文件有序的保存了有效的寫入操作,這些寫入操作是以指定的協(xié)議進(jìn)行保存的冕广。所以即使發(fā)生異常操作疏日,只要AOF還未被覆蓋,那么將AOF文件中的異常命令移除撒汉,然后讓redis進(jìn)行恢復(fù)即可沟优。(比如誤操作flush all)
5. AOF 的缺點(diǎn)
- AOF文件的體積大于RDB文件的體積
- 根據(jù)使用的fsync的策略,AOF的速度可能慢于RDB睬辐。在一般情況下挠阁,每秒fsync的性能高宾肺,最壞情況下丟失的數(shù)據(jù)少。
6. 混合使用
如果想達(dá)到最高的數(shù)據(jù)安全性侵俗,應(yīng)該同時(shí)使用兩種策略锨用。
如果能接受最短幾分鐘內(nèi)的數(shù)據(jù)丟失,那么應(yīng)該使用RDB隘谣。
7. 快照文件
在默認(rèn)情況下黔酥,Redis將數(shù)據(jù)庫(kù)快照保存在名字為fump.rdb的二進(jìn)制文件中『殚伲可以對(duì)redis進(jìn)行設(shè)置,實(shí)現(xiàn)只有redis的操作滿足條件時(shí)才進(jìn)行備份棵帽。
save 60 1000
表示在60秒內(nèi)熄求,有1000個(gè)key發(fā)生了數(shù)據(jù)改動(dòng),才進(jìn)行備份逗概。
當(dāng)然弟晚,也可以通過手動(dòng)命令進(jìn)行強(qiáng)行備份。
SAVE
或者BGSAVE
可以手動(dòng)強(qiáng)行備份逾苫。
-
工作方式:
redis需要保存dump.rdb時(shí)卿城,會(huì)執(zhí)行以下操作:
- forks子進(jìn)程,redis同時(shí)有父進(jìn)程和子進(jìn)程
- 子進(jìn)程將數(shù)據(jù)寫入臨時(shí)RDB文件
- 子進(jìn)程完成RDB文件后铅搓,redis會(huì)用新的RDB文件替換舊的RDB文件瑟押,并刪除舊的RDB文件。
==為什么使用fork==:在操作系統(tǒng)中星掰,有一個(gè)優(yōu)化機(jī)制是==寫時(shí)復(fù)制==多望。就是說,fork子線程時(shí)氢烘,子線程持有的數(shù)據(jù)和父線程持有的數(shù)據(jù)是同一份怀偷,只有當(dāng)子線程或者父線程需要寫數(shù)據(jù)時(shí),才會(huì)將子線程的數(shù)據(jù)從父線程拷貝一份播玖。對(duì)于redis來說椎工,fork出來的子線程沒有寫數(shù)據(jù),只有讀數(shù)據(jù)蜀踏,所以维蒙,fork出來的子線程就不涉及數(shù)據(jù)的拷貝了,因?yàn)樽泳€程和父線程使用同一份數(shù)據(jù)果覆。在子線程拷貝期間木西,父線程會(huì)將期間受到的寫操作放到內(nèi)存緩沖中,到了時(shí)間才會(huì)將內(nèi)存緩沖中的數(shù)據(jù)寫入随静。==這也是為什么會(huì)丟失一小部分?jǐn)?shù)據(jù)的原因八千。==
8. 日志文件
在配置文件中使用appendobly yes
打開AOF持久化方式吗讶。
打開后,每當(dāng)redis執(zhí)行一個(gè)改變數(shù)據(jù)集的命令時(shí)恋捆,這個(gè)命令就會(huì)被追加到AOF文件的末尾照皆。當(dāng)redis被重啟后,就會(huì)從AOF文件中讀取命令沸停,重新一次膜毁,就可以達(dá)到重建數(shù)據(jù)集的目的。
-
日志重建:
因?yàn)锳OF的方式是不斷的將命令追加愤钾,所以瘟滨,隨著命令不斷的被追加,AOF文件的體積也會(huì)越來越大能颁。為了解決這個(gè)問題杂瘸,redis可以在不打斷服務(wù)端的情況下,對(duì)AOF文件進(jìn)行重建(rebuild)伙菊。
執(zhí)行
BGREWRITEAOF
會(huì)生成一個(gè)新的AOF文件败玉。 -
fsync配置:
每次有新的命令追加到AOF文件時(shí),就調(diào)用fsync镜硕,將數(shù)據(jù)從內(nèi)存緩沖寫入磁盤:非常慢运翼,非常安全.
每秒一次fsync:足夠快(和使用RDB持久化差不多),并且最多丟失1秒鐘的數(shù)據(jù)==類似配置RDB1秒鐘備份一次兴枯,不過AOF不是全盤備份血淌,而是增量備份.==
從不fsync:將數(shù)據(jù)交給操作系統(tǒng),操作系統(tǒng)認(rèn)為內(nèi)存緩沖區(qū)快滿了财剖,可以寫入磁盤了六剥,那么就進(jìn)行寫入。非撤寤铮快疗疟,但是更不安全。
(默認(rèn)是每秒fsync瞳氓,也是推薦的配置)
-
AOF文件被損壞:
為現(xiàn)有的AOF文件做個(gè)備份策彤,然后使用
redis-check-aof
進(jìn)行修復(fù)。最后重啟redis匣摘,使用修復(fù)后的AOF文件恢復(fù)數(shù)據(jù)店诗。 -
工作原理:
AOF重寫和RDB創(chuàng)建快照一樣,巧妙的利用了寫時(shí)復(fù)制:
- forks子進(jìn)程音榜,redis同時(shí)有父進(jìn)程和子進(jìn)程
- 子進(jìn)程將新的AOF文件寫入臨時(shí)文件
- 在子線程寫入的同時(shí) 庞瘸,如果有新的命令被執(zhí)行,那么父進(jìn)程會(huì)將命令同時(shí)存入內(nèi)存緩沖區(qū)和原AOF文件==(這是為什么AOF數(shù)據(jù)比RDB丟失的少的多的多的原因)==赠叼,即使在重建 的過程中發(fā)生異常擦囊,原AOF文件也持有全部的命令违霞,不會(huì)造成數(shù)據(jù)丟失(最多1秒)
- 子進(jìn)程重寫完成后,父進(jìn)程將內(nèi)存緩沖區(qū)的命令寫入臨時(shí)AOF文件瞬场,然后使用新的AOF文件替換原有的AOF文件买鸽。
9. RDB切換AOF
從RDB切換到AOF的步驟:
- 備份dump.rdb文件
- 執(zhí)行
redis-cli config set appendonly yes
- 執(zhí)行
redis-cli set save ""
執(zhí)行的第一條命令開啟了AOF功能,redis會(huì)阻塞贯被,直到初始AOF文件創(chuàng)建完畢為止眼五,之后redis會(huì)繼續(xù)處理命令請(qǐng)求,并開始將寫入命令追加到AOF文件末尾彤灶。
執(zhí)行的第二條命令關(guān)閉了RDB功能看幼,這一步可以省略,同時(shí)開啟兩種持久化方式幌陕。
==注意:需要記得在redis.conf文件中開啟AOF功能诵姜,否則重啟redis后,配置會(huì)被重置苞轿。==
10. RDB和AOF同時(shí)開啟
在執(zhí)行BGSAVE
進(jìn)行備份RDB文件時(shí),不允許執(zhí)行BGREWRITEAOF
逗物。當(dāng)然搬卒,在執(zhí)行BGREWRITEAOF
時(shí),也不允許執(zhí)行BGSAVE
翎卓。
防止兩個(gè)redis后臺(tái)同時(shí)對(duì)磁盤進(jìn)行大量的IO操作契邀。
如果BGSAVE
正在執(zhí)行,用戶顯式的調(diào)用BGREWRITEAOF
命令失暴,redis會(huì)向用戶回復(fù)一個(gè)OK坯门,告知用戶,BGREWRITEAOF
被預(yù)定執(zhí)行逗扒,當(dāng)BGSAVE
執(zhí)行完畢古戴,就會(huì)執(zhí)行BGREWRITEAOF
。
當(dāng)redis啟動(dòng)時(shí)矩肩,同時(shí)開啟了RDB和AOF现恼,那么redis會(huì)優(yōu)先使用AOF進(jìn)行回復(fù)數(shù)據(jù),因?yàn)锳OF文件保存的數(shù)據(jù)比RDB完整(通常情況下)黍檩。
11. redis數(shù)據(jù)備份
redis對(duì)于數(shù)據(jù)備份非常友好叉袍,你可以在任何時(shí)候?qū)DB備份文件進(jìn)行拷貝:RDB文件一旦被創(chuàng)建就不會(huì)被修改==(只會(huì)進(jìn)行替換)==。當(dāng)服務(wù)器要?jiǎng)?chuàng)建一個(gè)新的RDB文件時(shí)刽酱,redis先會(huì)創(chuàng)建一個(gè)臨時(shí)的RDB文件喳逛,當(dāng)臨時(shí)的RDB備份完成后,redis使用rename原子操作替換原有的RDB文件棵里。
所以润文,任何時(shí)候姐呐,拷貝RDB文件都是絕對(duì)安全的。