Redis提供了RDB持久化和AOF持久化,本篇文章中將會對這兩種機制進行一些對比javascript
RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤。 也是默認的持久化方式,這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名爲dump.rdb。java
能夠經過配置設置自動作快照持久化的方式。咱們能夠配置redis在n秒內若是超過m個key被修改就自動作快照,下面是默認的快照保存配置redis
save 900 1 #900秒內若是超過1個key被修改,則發起快照保存 save 300 10 #300秒內容如超過10個key被修改,則發起快照保存 save 60 10000
client 也可使用save或者bgsave命令通知redis作一次快照持久化。save操做是在主線程中保存快照的,因爲redis是用一個主線程來處理全部 client的請求,這種方式會阻塞全部client請求。因此不推薦使用。數據庫
另外一點須要注意的是,每次快照持久化都是將內存數據完整寫入到磁盤一次,並不 是增量的只同步髒數據。若是數據量大的話,並且寫操做比較多,必然會引發大量的磁盤io操做,可能會嚴重影響性能。緩存
redis會將每個收到的寫命令都經過write函數追加到文件中(默認是 appendonly.aof)。安全
當redis重啓時會經過從新執行文件中保存的寫命令來在內存中重建整個數據庫的內容。固然因爲os會在內核中緩存 write作的修改,因此可能不是當即寫到磁盤上。這樣aof方式的持久化也仍是有可能會丟失部分修改。不過咱們能夠經過配置文件告訴redis咱們想要 經過fsync函數強制os寫入到磁盤的時機。有三種方式以下(默認是:每秒fsync一次)服務器
appendonly yes //啓用aof持久化方式 # appendfsync always //每次收到寫命令就當即強制寫入磁盤,最慢的,可是保證徹底的持久化,不推薦使用 appendfsync everysec //每秒鐘強制寫入磁盤一次,在性能和持久化方面作了很好的折中,推薦 # appendfsync no //徹底依賴os,性能最好,持久化沒保證
aof 的方式也同時帶來了另外一個問題。持久化文件會變的愈來愈大。例如咱們調用incr test命令100次,文件中必須保存所有的100條命令,其實有99條都是多餘的。由於要恢復數據庫的狀態其實文件中保存一條set test 100就夠了。app
爲了壓縮aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis將使用與快照相似的方式將內存中的數據 以命令的方式保存到臨時文件中,最後替換原來的文件。具體過程以下函數
須要注意到是重寫aof文件的操做,並無讀取舊的aof文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點相似。工具
使用 AOF 持久化會讓 Redis 變得很是耐久(much more durable):你能夠設置不一樣的 fsync 策略,好比無 fsync ,每秒鐘一次 fsync ,或者每次執行寫入命令時 fsync 。 AOF 的默認策略爲每秒鐘 fsync 一次,在這種配置下,Redis 仍然能夠保持良好的性能,而且就算髮生故障停機,也最多隻會丟失一秒鐘的數據( fsync 會在後臺線程執行,因此主線程能夠繼續努力地處理命令請求)。
AOF 文件是一個只進行追加操做的日誌文件(append only log), 所以對 AOF 文件的寫入不須要進行 seek , 即便日誌由於某些緣由而包含了未寫入完整的命令(好比寫入時磁盤已滿,寫入中途停機,等等), redis-check-aof 工具也能夠輕易地修復這種問題。
Redis 能夠在 AOF 文件體積變得過大時,自動地在後臺對 AOF 進行重寫: 重寫後的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。 整個重寫操做是絕對安全的,由於 Redis 在建立新 AOF 文件的過程當中,會繼續將命令追加到現有的 AOF 文件裏面,即便重寫過程當中發生停機,現有的 AOF 文件也不會丟失。 而一旦新 AOF 文件建立完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操做。
AOF 文件有序地保存了對數據庫執行的全部寫入操做, 這些寫入操做以 Redis 協議的格式保存, 所以 AOF 文件的內容很是容易被人讀懂, 對文件進行分析(parse)也很輕鬆。 導出(export) AOF 文件也很是簡單: 舉個例子, 若是你不當心執行了 FLUSHALL 命令, 但只要 AOF 文件未被重寫, 那麼只要中止服務器, 移除 AOF 文件末尾的 FLUSHALL 命令, 並重啓 Redis , 就能夠將數據集恢復到 FLUSHALL 執行以前的狀態。
對於相同的數據集來講,AOF 文件的體積一般要大於 RDB 文件的體積。
根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。 在通常狀況下, 每秒 fsync 的性能依然很是高, 而關閉 fsync 可讓 AOF 的速度和 RDB 同樣快, 即便在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 能夠提供更有保證的最大延遲時間(latency)。
AOF 在過去曾經發生過這樣的 bug : 由於個別命令的緣由,致使 AOF 文件在從新載入時,沒法將數據集恢復成保存時的原樣。 (舉個例子,阻塞命令 BRPOPLPUSH 就曾經引發過這樣的 bug 。) 測試套件裏爲這種狀況添加了測試: 它們會自動生成隨機的、複雜的數據集, 並經過從新載入這些數據來確保一切正常。 雖然這種 bug 在 AOF 文件中並不常見, 可是對比來講, RDB 幾乎是不可能出現這種 bug 的。
通常來講, 若是想達到足以媲美 PostgreSQL 的數據安全性, 你應該同時使用兩種持久化功能。
若是你很是關心你的數據, 但仍然能夠承受數分鐘之內的數據丟失, 那麼你能夠只使用 RDB 持久化。
其他狀況我我的喜愛選擇AOF