這篇文章帶大家聊聊redis中RDB 和 AOF 持久化的原理,它們的優缺點是什麼?分析一下應該用哪一個?希望對大家有幫助!
Redis 提供了RDB 和AOF 兩種持久化方案:
dumpr.rdb二進位。 【相關推薦:
Redis影片教學】
工作原理簡單介紹一下:
當Redis 需要持久化時,Redis 會fork 一個子進程,子進程將資料寫到磁碟上一個臨時RDB 檔案。當子進程完成寫暫存檔案後,將原來的 RDB 替換掉,這樣的好處就是可以copy-on-write。
save或
bgsave(非同步)產生 RDB 檔案。
save 900 1 save 300 10 save 60 10000
RDB 快照指令在預設情況下, Redis 將資料庫快照保存在名字為dump.rdb 的二進位檔案中。
你可以對 Redis 進行設置, 讓它在「 N 秒內資料集至少有 M 個改動」這一條件被滿足時, 自動儲存一次資料集。
你也可以透過呼叫
SAVE或BGSAVE
, 手動讓 Redis 進行資料集儲存操作。比如說, 以下設定會讓Redis 在滿足「 60 秒內有至少有1000 個鍵被改動」這個條件時, 自動儲存一次資料集:
save 60 1000
這個持久化方式稱為快照(snapshot)。
RDB 建立原則當Redis 需要儲存dump.rdb 檔案時, 伺服器執行下列操作:
#Redis 呼叫fork() ,同時擁有父行程和子程序。RDB 的優點RDB 是一個比較緊湊的文件,它保存了Redis 在某個時間點的數據,這種數據比較適合做備份和用於災難復原。
比如說,你可以在最近的 24 小時內,每小時備份一次 RDB 文件,並且在每個月的每一天,也備份一個 RDB 文件。這樣的話,即使遇上問題,也可以隨時將資料集還原到不同的版本。
RDB 的缺點如果你需要盡量避免在伺服器故障時遺失數據,那麼 RDB 不適合你。雖然 Redis 允許你設定不同的保存點來控制保存 RDB 檔案的頻率, 但是, 因為 RDB 檔案需要保存整個資料集的狀態, 所以它並不是一個輕鬆的操作。因此你可能會至少 5 分鐘才儲存一次 RDB 檔案。在這種情況下, 一旦發生故障停機, 你就可能會遺失好幾分鐘的資料。
AOF 持久化函數追加到appendonly.aof
檔案中。AOF 可以做到全程持久化,只需要在設定檔中開啟(預設為no ),
開啟AOF 之後,Redis 每執行一個修改資料的指令,都會把它加入AOF 檔案中,當Redis 重新啟動時,將會讀取AOF 檔案進行「重播」以恢復到Redis 關閉前的最後時刻。
AOF 的設定你可以設定 Redis 多久才將資料 fsync 到磁碟一次。
redis.conf 預設配置
appendfsync yes appendfsync always #每次有数据修改发生时都会写入AOF文件。 appendfsync everysec #每秒钟同步一次,该策略为AOF的缺省策略。
有三個選項:
1,每次有新指令追加到 AOF 檔案時就執行一次 fsync:非常慢,也非常安全。
2,每秒 fsync 一次:夠快(和使用 RDB 持久化差不多),而且在故障時只會遺失 1 秒鐘的資料。
3,從不 fsync:將資料交給作業系統來處理。更快,也更不安全的選擇。
建議(而且也是預設)的措施是每秒 fsync 一次, 這種 fsync 策略可以兼顧速度和安全性。
AOF 創建原則
AOF 重寫和 RDB 創建快照一樣,都巧妙地利用了寫時複製機制。
以下是 AOF 重寫的執行步驟:
Redis 執行 fork() ,現在同時擁有父行程和子行程。
子程序開始將新 AOF 檔案的內容寫入到暫存檔案。
對於所有新執行的寫入命令,父進程一邊將它們累積到一個內存緩存中,一邊將這些改動追加到現有AOF 文件的末尾: 這樣即使在重寫的中途發生停機,現有的AOF 文件還是安全的。
當子進程完成重寫工作時,它會給父進程發送一個訊號,父進程在接收到訊號之後,將記憶體快取中的所有資料追加到新 AOF 檔案的末尾。
搞定!現在 Redis 原子地用新文件取代舊文件,之後所有指令都會直接追加到新 AOF 文件的最後。
AOF 的優點
1,使用AOF 做持久化,可以設定不同的fsync 策略,例如無fsync ,每秒鐘一次fsync ,或每次執行寫入指令時fsync 。
AOF 的預設策略為每秒鐘 fsync 一次,在這種配置下,Redis 仍然可以保持良好的效能,並且就算發生故障停機,也最多只會遺失一秒鐘的資料。
fsync 會在後台執行緒執行,所以主執行緒可以繼續努力地處理指令請求。
2,AOF 文件是一個只進行追加操作的日誌文件,不是產生新的之後替換掉那種,即使日誌因為某些原因而包含了未寫入完整的命令(例如寫入時磁碟已滿,寫入中途停機,等等), redis-check-aof 工具也可以輕易地修復這種問題。
3,Redis 可以在 AOF 檔案體積變得過大時,自動地在後台對 AOF 進行重寫: 重寫後的新 AOF 檔案包含了恢復目前資料集所需的最小命令集合。
整個重寫操作是絕對安全的,因為Redis 重寫是創建新AOF 文件,重寫的過程中會繼續將命令追加到現有舊的AOF 文件裡面,即使重寫過程中發生停機,現有舊的AOF 檔案也不會遺失。而一旦新 AOF 文件創建完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操作。
4,AOF 檔案有序地保存了對資料庫執行的所有寫入操作, 這些寫入操作以Redis 協定的格式保存, 因此AOF 檔案的內容非常容易被人讀懂, 對檔案進行分析(parse)也很輕鬆。匯出(export) AOF 檔案也非常簡單: 舉個例子, 如果你不小心執行了_FLUSH ALL_(清空整個Redis 伺服器的資料(刪除所有資料庫的所有key )。)指令,但只要AOF 檔案未被重寫, 那麼只要停止伺服器, 移除AOF 檔案末端的FLUSHALL指令,並重新啟動Redis , 就可以將資料集還原到FLUSHALL執行之前的狀態。
AOF 的缺點
對於相同的資料集來說,AOF 檔案的體積通常大於 RDB 檔案的體積。
根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB。在一般情況下, 每秒 fsync 的效能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負載之下也是如此。
不過在處理龐大的寫入載入時,RDB 可以提供更有保證的最大延遲時間(latency)。
RDB持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,實際操作過程是fork一個子進程,先將資料集寫入暫存文件,寫入成功後,再取代之前的文件,用二進位壓縮儲存。
AOF持久化以日誌的形式記錄伺服器所處理的每一個寫入、刪除操作,查詢操作不會記錄,以文字的方式追加記錄,可以開啟檔案看到詳細的操作記錄。
如果你非常關心你的數據,但仍然可以承受幾分鐘以內的資料遺失,那麼你可以只使用 RDB 持久。
AOF 將 Redis 執行的每個指令追加到磁碟中,處理巨大的寫入會降低 Redis 的效能,不知道你是否可以接受。
資料庫備份與災難復原:
定時產生 RDB 快照(snapshot)非常方便進行資料庫備份, 且 RDB 復原資料集的速度也要比 AOF 復原的速度要快。
Redis 支援同時開啟 RDB 和 AOF,系統重啟後,Redis 會優先使用 AOF 來恢復數據,這樣遺失的資料會最少。
因為AOF 的運作方式是不斷地將命令追加到文件的末尾, 所以隨著寫入命令的不斷增加, AOF 文件的體積也會越來越大。
舉例
如果你對計數器呼叫了100 次INCR , 那麼只是為了保存這個計數器的目前值, AOF 檔案就需要使用100 筆記錄(entry)。
然而在實際上, 只使用一條 SET 指令已經足以保存計數器的目前值了, 其餘 99 筆記錄其實都是多餘的。
為了處理這種情況, Redis 支援一個有趣的特性: 可以在不打斷服務客戶端的情況下, 對 AOF 檔案進行重建(rebuild)。
執行BG REWRITE AOF
指令, Redis 將產生一個新的 AOF 文件, 這個文件包含重建目前資料集所需的最少指令。
Redis 2.2 需要自行手動執行BGREWRITEAOF
指令; Redis 2.4 則可以自動觸發 AOF 重寫, 具體資訊請查看 2.4 的範例設定檔。
磁碟故障, 節點失效, 諸如此類的問題都可能讓你的資料消失不見, 不進行備份是非常危險的。
Redis 對於資料備份是非常友善的, 因為你可以在伺服器運行的時候對 RDB 檔案進行複製: RDB 檔案一旦被創建, 就不會進行任何修改。當伺服器要建立新的 RDB 檔案時, 它先將檔案的內容保存在一個暫存檔案裡面, 當暫存檔案寫入完畢時, 程式才使用 rename(2) 原子地用暫存檔案取代原來的 RDB 檔案。
這也就是說, 無論何時, 複製 RDB 檔案都是絕對安全的。
以下是我們的建議:
1,建立一個定期任務(cron job), 每小時將一個RDB 檔案備份到一個資料夾,並且每天將一個RDB 檔案備份到另一個資料夾。
2,確保快照的備份都帶有相應的日期和時間信息, 每次執行定期任務腳本時, 使用find 命令來刪除過期的快照: 比如說, 你可以保留最近48 小時內的每小時快照, 還可以保留最近一兩個月的每日快照。
3,至少每天一次, 將 RDB 備份到你的資料中心之外, 或至少備份到你執行 Redis 伺服器的實體機器之外。
更多程式相關知識,請造訪:程式設計影片! !
以上是淺析RDB和AOF持久化,優缺點是什麼?怎麼選?的詳細內容。更多資訊請關注PHP中文網其他相關文章!