RDB持久化 |
AOF持久化 |
全量備份,一次保存整個數據庫 |
增量備份,一次保存一個修改數據庫的命令 |
保存的間隔較長 |
保存的間隔默認一秒 |
數據還原速度快 |
數據還原速度一般 |
save會阻塞,但bgsave或者自動不會阻塞 |
無論是平時還是AOF重寫,都不會阻塞 |
更適合數據備份,默認開啟 |
更適合用來保存數據,和一般SQL持久化方式一樣,默認關閉 |
啟動優先級 : 低 |
啟動優先級 : 高 |
體積 : 小 |
體積 : 大 |
恢復速度 : 快 |
恢復速度 : 慢 |
數據安全性 : 丟數據 |
數據安全性 : 根據策略決定 |
輕重 : 重 |
輕重: 輕 |
1、Redis持久化
RDB(Redis DataBase)------數據
AOF(AppendOnlyFiel)------命令
默認情況下,RDB開啟,AOF關閉。
這兩種形式都可以將存儲在內存中的數據庫數據以文件形式保存到硬盤中,防止數據丟失。文件位置:/var/lib/redis/6379
RDB持久化功能可以將服務器包含的所有數據庫數據以二進制文件的形式保存到硬盤中,創建RDB類型的文件,默認為dump.rdb。服務器再次啟動時會載入RDB文件,根據RDB文件的內容、還原服務器原有的數據庫數據。
1.1 創建RDB文件方式
前兩種需要用戶手動執行,第三種有redis服務器自動執行
服務器執行客戶端發送SAVE命令
服務器執行客戶端發送BGSAVE命令
使用save配置選項設置的自動保存條件被滿足,服務器自動執行BGSAVE
- SAVE命令
執行save命令的過程中,即創建RDB文件過程中,redis服務器將被阻塞,無法處理客戶端發送的命令請求,只有在SAVE命令執行完畢之后,,服務器才重新開始處理客戶端發送的命令請求。
如果RDB文件已經存在,那么服務器將自動使用新的RDB文件去代替舊的RDB文件。(為防止rdb文件丟失或被惡意篡改,可以設置定時將rdb文件轉移到別的位置,文件命名標明保存時間)
- BGSAVE命令
執行bgsave命令同樣會創建一個新的RDB文件,但這個命令執行過程中不會造成redis服務器阻塞。
【1、當redis服務器接受到BGSAVE命令時,他不會自動創建RDB文件,而是通過fork()來生成一個子進程,然后由子進程負責創建RDB文件,而自己繼續處理客戶端的命令請求 2、當子進程創建好RDB文件並退出時,他會向父進程(即負責處理命令請求的redis服務器)發送一個信號,告知他RDB文件已經創建完畢 3、最后redis服務器(父進程)解手子進程創建的RDB文件,BGSAVE執行完畢】
創建子進程會消耗額外的內存,所以SAVE創建RDB文件的速度會比BGSAVE塊,可以集中資源來創建RDB文件。SAVE和BGSAVE沒有孰好孰壞之分,如果數據庫正在上線當中,用BGSAVE更好;而如果維護停機期間,則使用SAVE,因為此時系統阻塞也沒關系,創建速度會更快,任務可以更快得完成。
自動創建RDB文件
默認redis.conf文件中為如下設置,可自行修改。只要三個條件滿足任意一個,服務器就會執行BGSAVE。RDB文件創建后,服務器會將時間計數器和次數計數器清零,重新開始記錄
save 900 1 :如果距離上次創建RDB文件已經過去了900秒,且服務器所有數據庫總共已經發生了不少於1次修改,那么執行BGSAVE命令
save 300 10 :如果距離上次創建RDB文件已經過去了300秒,且服務器所有數據庫總共已經發生了不少於10次修改,那么執行BGSAVE命令
save 60 10000:如果距離上次創建RDB文件已經過去了60秒,且服務器所有數據庫總共已經發生了不少於10000次修改,那么執行BGSAVE命令
2、常見問題
1.在dump rdb過程中,aof如果停止同步,會不會丟失?
不會,所有的操作緩存在內存隊列里,dump完后后,統一操作
2.aof重寫是什么?
aof重寫就是把內存中的數據逆化成命令,寫入到aof文件,以解決aof日志過大的問題
3.如果rdb和aof文件都存在,優先使用誰恢復數據?
在這種情況下,當redis重啟的時候會優先載入AOF文件來恢復原始的數據,因為在通常情況下AOF文件保存的數據集要比RDB文件完整
4.rdb和aof是否可以同時用?
可以,推薦同時使用
5.恢復時,rdb和aof哪個更快?
rdb快,因為rdb是數據的內存映射,直接載入到內存,而aof是命令,需要逐條執行
6.如何在不用【config set】命令的情況下,將Redis持久化由RDB切換到AOF
利用主從,從機配置AOF重啟后,將生成的AOF文件復制至主機Redis數據目錄,主機配置AOF后再重啟。
注:在 Redis 2.2 或以上版本,通過【config set】可以在不重啟的情況下,從 RDB 切換到 AOF。
1)為最新的 dump.rdb 文件創建一個備份。
2)將備份放到一個安全的地方。
3)執行以下兩條命令: redis-cli> CONFIG SET appendonly yes redis-cli> CONFIG SET save ""
4)確保命令執行之后,數據庫的鍵的數量沒有改變。
5)確保寫命令會被正確地追加到 AOF 文件的末尾。
步驟 3 執行的第一條命令開啟了AOF功能:<font style="color:red">Redis會阻塞直到初始AOF文件創建完成為止</font>,之后Redis會繼續處理命令請求, 並開始將寫入命令追加到 AOF 文件末尾。
步驟 3 執行的第二條命令用於關閉RDB功能。這一步是可選的,如果你願意的話,也可以同時使用RDB和AOF這兩種持久化功能。
不過別忘了在redis.conf中打開AOF功能!否則的話,服務器重啟之后,之前通過【CONFIG SET】設置的配置就會被遺忘,程序會按原來的配置來啟動服務器。
3、 RDB持久化的配置
RDB是在某個時間點將數據寫入一個臨時文件,持久化結束后,用這個臨時文件替換上次持久化的文件,達到數據恢復。
優點:使用單獨子進程來進行持久化,主進程不會進行任何IO操作,保證了redis的高性能
缺點:RDB是間隔一段時間進行持久化,如果持久化之間redis發生故障,會發生數據丟失。所以這種方式更適合數據要求不嚴謹的時候
創建RDB文件需要將服務器所有的數據庫的數據保存起來,這是一個非常耗費資源和時間的操作,所以服務器需要隔一段時間才創建一個新的RDB文件,也就是說,創建RDB文件的操作不能執行得過於頻繁,否則就會嚴重得影響服務器性能。
相比而言,AOF持久化的巨大優勢就是用戶可以根據自己的需要對AOF持久化進行調整,讓redis在遭遇意外停機時不丟失任何數據,或者只丟失一秒鍾的數據。
這里說的這個執行數據寫入到臨時文件的時間點是可以通過配置來自己確定的,通過配置redis在n秒內如果超過m個key被修改這執行一次RDB操作。這個操作就類似於在這個時間點來保存一次Redis的所有數據,一次快照數據。所有這個持久化方法也通常叫做snapshots。
RDB默認開啟,redis.conf中的具體配置參數如下;
1 #dbfilename:持久化數據存儲在本地的文件 2 dbfilename dump.rdb 3 #dir:持久化數據存儲在本地的路徑,如果是在/redis/redis-3.0.6/src下啟動的redis-cli,則數據會存儲在當前src目錄下 4 dir ./ 5 #snapshot觸發的時機,save <seconds> <changes> 6 #如下為900秒后,至少有一個變更操作,才會snapshot 7 #對於此值的設置,需要謹慎,評估系統的變更操作密集程度 8 #可以通過“save “””來關閉snapshot功能 9 #save時間,以下分別表示更改了1個key時間隔900s進行持久化存儲;更改了10個key300s進行存儲;更改10000個key60s進行存儲。 10 save 900 1 11 save 300 10 12 save 60 10000 13 #當snapshot時出現錯誤無法繼續時,是否阻塞客戶端“變更操作”,“錯誤”可能因為磁盤已滿/磁盤故障/OS級別異常等 14 stop-writes-on-bgsave-error yes 15 #是否啟用rdb文件壓縮,默認為“yes”,壓縮往往意味着“額外的cpu消耗”,同時也意味這較小的文件尺寸以及較短的網絡傳輸時間 16 rdbcompression yes
snapshot觸發的時機,是有“間隔時間”和“變更次數”共同決定,同時符合2個條件才會觸發snapshot,否則“變更次數”會被繼續累加到下一個“間隔時間”上。snapshot過程中並不阻塞客戶端請求。snapshot首先將數據寫入臨時文件,當成功結束后,將臨時文件重名為dump.rdb。
使用RDB恢復數據:
自動的持久化數據存儲到dump.rdb后。實際只要重啟redis服務即可完成(啟動redis的server時會從dump.rdb中先同步數據)
客戶端使用命令進行持久化save存儲:
./redis-cli -h ip -p port save ./redis-cli -h ip -p port bgsave
4、AOF持久化的配置
4.1 AOF重寫原理:
AOF 是redis的一種持久化方式,用來記錄所有的寫操作,但是隨着時間增加,aof文件會越來越大,所以需要進行重寫,將內存中的數據重新以命令的方式寫入aof文件。
在重寫的過程中,由於redis還會有新的寫入,為了避免數據丟失,會開辟一塊內存用於存放重寫期間產生的寫入操作,等到重寫完畢后會將這塊內存中的操作再追加到aof文件中。
4.2 優缺點:
優點:可以保持更高的數據完整性,如果設置追加file的時間是1s,如果redis發生故障,最多會丟失1s的數據;且如果日志寫入不完整支持redis-check-aof來進行日志修復;AOF文件沒被rewrite之前(文件過大時會對命令進行合並重寫),可以刪除其中的某些命令(比如誤操作的flushall)。
缺點:AOF文件比RDB文件大,且恢復速度慢。
4.3 什么情況觸發rewrite?
127.0.0.1:6379> config get auto-aof-rewrite-percentage 1) "auto-aof-rewrite-percentage" 2) "200" 127.0.0.1:6379> config set auto-aof-rewrite-percentage 800 OK
auto-aof-rewrite-percentage 是設置aof rewrite觸發時機的一個參數,當當前的aof文件大小超過上一次rewrite后aof文件的百分比后觸發rewrite。
200 改為 800 ,即當前的aof文件超過上一次重寫后aof文件的8倍時才會再次rewrite
- AOF持久化默認是關閉的,默認是打開RDB持久化
- appendonly yes,(在redis.conf中修改appendonly 的策略,將no改成yes即可)此配置可以打開AOF持久化機制,在生產環境里面,一般來說AOF都是要打開的,除非你說隨便丟個幾分鍾的數據也無所謂
- 打開AOF持久化機制之后,redis每次接收到一條寫命令,就會寫入日志文件中,當然是先寫入os cache的,然后每隔一定時間再fsync一下
- 而且即使AOF和RDB都開啟了,redis重啟的時候,也是優先通過AOF進行數據恢復的,因為aof數據比較完整
- 可以配置AOF的fsync策略,有三種策略可以選擇(redis提供了3中aof記錄同步選項):
一種是每次寫入一條數據就執行一次fsync; 一種是每隔一秒執行一次fsync; 一種是不主動執行fsync
appendfsync always: 每次寫入一條數據,立即將這個數據對應的寫日志fsync到磁盤上去,性能非常非常差,吞吐量很低; 確保說redis里的數據一條都不丟,那就只能這樣了appendfsync everysec: 每秒將os cache中的數據fsync到磁盤,這個最常用的,生產環境一般都這么配置,性能很高,QPS還是可以上萬的(QPS指每秒鍾請求次數)appendfsync no: 僅僅redis負責將數據寫入os cache就撒手不管了,然后后面os自己會時不時有自己的策略將數據刷入磁盤,不可控了
我們可以簡單的認為AOF就是日志文件,此文件只會記錄“變更操作”(例如:set/del等),如果server中持續的大量變更操作,將會導致AOF文件非常的龐大,意味着server失效后,數據恢復的過程將會很長;事實上,一條數據經過多次變更,將會產生多條AOF記錄,其實只要保存當前的狀態,歷史的操作記錄是可以拋棄的;因為AOF持久化模式還伴生了“AOF rewrite”。
AOF的特性決定了它相對比較安全,如果你期望數據更少的丟失,那么可以采用AOF模式。如果AOF文件正在被寫入時突然server失效,有可能導致文件的最后一次記錄是不完整,你可以通過手工或者程序的方式去檢測並修正不完整的記錄,以便通過aof文件恢復能夠正常;同時需要提醒,如果你的redis持久化手段中有aof,那么在server故障失效后再次啟動前,需要檢測aof文件的完整性。
AOF默認關閉,開啟方法,修改配置文件reds.conf:appendonly yes
1 #此選項為aof功能的開關,默認為“no”,可以通過“yes”來開啟aof功能 2 ##只有在“yes”下,aof重寫/文件同步等特性才會生效 3 appendonly yes 4 5 #指定aof文件名稱 6 appendfilename appendonly.aof 7 8 #指定aof操作中文件同步策略,有三個合法值:always everysec no,默認為everysec 9 appendfsync everysec 10 #在aof-rewrite期間,appendfsync是否暫緩文件同步,"no"表示“不暫緩”,“yes”表示“暫緩”,默認為“no” 11 no-appendfsync-on-rewrite no 12 13 #aof文件rewrite觸發的最小文件尺寸(mb,gb),只有大於此aof文件大於此尺寸是才會觸發rewrite,默認“64mb”,建議“512mb” 14 auto-aof-rewrite-min-size 64mb 15 16 #相對於“上一次”rewrite,本次rewrite觸發時aof文件應該增長的百分比。 17 #每一次rewrite之后,redis都會記錄下此時“新aof”文件的大小(例如A),那么當aof文件增長到A*(1 + p)之后 18 #觸發下一次rewrite,每一次aof記錄的添加,都會檢測當前aof文件的尺寸。 19 auto-aof-rewrite-percentage 100
4.4、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中加載所有的日志,把內存中的數據恢復回來
4.5、AOF破損文件的修復
如果redis在append數據到AOF文件時,機器宕機了,可能會導致AOF文件破損
用redis-check-aof --fix命令來修復破損的AOF文件
5、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進行數據恢復,因為其中的日志更完整