序言
在上一篇博客中,博客介紹了redis的數據類型使用場景和redis分布式鎖的正確姿勢。我們知道一旦Redis重啟,存在redis里面的數據就會全部丟失。所以這篇博客中向大家介紹Redis的磁盤持久化。
REDIS持久化
以每隔一段時間對redis進行快照的方式實現持久化
RDB持久化
優點:1、對redis性能影響小。
2、數據集比較大的時候,恢復速度比AOF快。
3、RDB是一個非常緊湊的單一文件,很方便傳到第三方數據中心(亞馬遜S3),以便日后的災難恢復。
缺點:1、因為RDB的快照持久化方式,所以一旦出現宕機,你可能丟失幾分鍾的數據。
2、RDB需要fork一個子進程來保存數據集到磁盤上,所以當數據集比較大的時候,就會造成redis在毫秒級內對客戶端沒反應。
配置文件:在redis.conf文件中,有這樣一段話。
################################ SNAPSHOTTING ################################ # # Save the DB on disk: # # save <seconds> <changes> # # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # # In the example below the behaviour will be to save: # after 900 sec (15 min) if at least 1 key changed # after 300 sec (5 min) if at least 10 keys changed # after 60 sec if at least 10000 keys changed # # Note: you can disable saving completely by commenting out all "save" lines. # # It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # like in the following example: # # save "" save 900 1 save 300 10 save 60 10000
說明在三種策略下,RDB會執行快照來將數據保存在磁盤上。例如 save 60 10000 意思是,"60秒內至少有1000個鍵被改動",這自動保存一次數據集。
notice:當redis剛啟動,這時你使用redis-cli向redis中存入一條數據,會發現並沒有生成dump.rdb。這是因為這時候還沒有滿組以上三種策略,所以不會執行bgsave命令,這時要么你等900秒,要么你進入redis-cli,主動執行bgsave命令。
這樣就會生成dump.rdb。
工作方式:當需要數據持久化的時候,會執行一下操作
1、Redis調用forks.同時擁有父進程和子進程。(這個過程是阻塞的)
2、子進程將數據集寫入一個臨時的rdb文件中。
3、Redis用新的rdb文件替換舊的rdb文件,並刪除舊的rdb文件。
AOF持久化
以向AOF文件中追加redis寫操作方式實現持久化
優點:1、AOF有三種策略:無fsync(完全依賴系統,性能很接近RDB)、每秒fsync、寫時fsync(數據完全同步,但性能比較差)。默認使用每秒fsync,這種策略,即使redis宕機,最多也只會丟失一秒中的數據,兼顧性能和數據實時性。
2、當向AOF文件寫入命令時,由於某些問題(磁盤已滿或寫時宕機等)造成未寫入完整的命令,可以使用redis-check-aof命令修復這些問題。
3、當AOF文件過大時,會自動重寫AOF文件。(例如我們只能了一百次incr count,就會在AOF文件中追加100次這個命令,那么重寫后,就只會有一條類似set count 100的命令)。
4、AOF 文件有序地保存了對redis執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式保存,非常的容易讀懂。因此當我們執行一些誤操作(FLUSHALL)的時候,也可以通過修改AOF文件來修復數據。
缺點:1、相同的數據集情況下,體積會比rdb大。
2、除非使用無fsync,不然AOF的性能都慢於RDB。
配置文件:同樣去看redis.conf文件中的配置注釋。主要配置如下
appendonly yes 是否開啟AOF持久化 appendfilename "appendonly.aof" AOF文件名
# appendfsync always 每次寫入時都追加的AOF文件中
appendfsync everysec 每秒同步一次AOF文件
# appendfsync no 不同步AOF文件,完全依賴操作系統
下面還有一些其他參數配置,詳細的可以去官網下載一份對應版本的redis.conf文件。
工作原理:AOF重寫和RDB創建快照一樣,都巧妙的利用了redis寫時復制機制:
1、redis執行fork(),同時擁有父進程和子進程。
2、子進程將新AOF命令寫入到臨時文件中。
3、所有新執行的寫入命令,redis一邊將其放入內存緩存中,一邊寫入現有的AOF文件中,這樣即使AOF重寫中redis發生宕機,現有AOF文件也是安全的。
4、當子進程完成AOF重寫時,會給父進程發送一個信號,父進程在接收到信號后,會將內存緩存中的所有命令追加到新的AOF文件中。
5、Redis用新的AOF替換原有的AOF。
如何選擇使用哪種持久化
1、如果你對數據的安全性要求非常高,那么建議兩種都適用。
2、如果你可以承受數分鍾的數據損失,那么就可以使用rdb
3、使用AOF
notice:redis官網有這樣一段話:因為以上提到的種種原因, 未來我們可能會將 AOF 和 RDB 整合成單個持久化模型。或許很快,我們就不用糾結使用哪種持久化了。
從RDB切換到AOF
1、為現有的rdb文件創建一個備份,並將備份放到一個安全的地方
2、redis-cli: config set appendonly yes 執行這個命令時,redis會阻塞,知道AOF文件創建完成,然后新的寫入命令會被追加到新的AOF文件中。
3、redis-cli: config set save "" 關閉RDB持久化是可選的,因為你完全可以同時開啟RDB和AOF這兩種持久化功能。
4、記得把前面的修改同步到redis.conf配置文件中,否則redis重啟后,config set設置的配置就失效了。
備份redis數據及容災
牢記:確保你的數據由完整的備份。 磁盤故障,節點失效, 諸如此類的問題都可能讓你的數據消失不見, 不進行備份是非常危險的。
因為RDB的工作原理,所以redis對於數據備份是非常友好的。無論何時,復制RDB文件是絕對安全的。
1、創建一個定期任務(cron job), 每小時將一個 RDB 文件備份到一個文件夾, 並且每天將一個 RDB 文件備份到另一個文件夾。
2、確保快照的備份都帶有相應的日期和時間信息, 每次執行定期任務腳本時, 使用 find 命令來刪除過期的快照: 比如說, 你可以保留最近 48 小時內的每小時快照, 還可以保留最近一兩個月的每日快照。
3、至少每天一次, 將 RDB 備份到你的數據中心之外, 或者至少是備份到你運行 Redis 服務器的物理機器之外。
數據備份了之后,為了做到容災,你可以將備份后的數據放到第三方數據中心。