Redis的持久化機制-RDB和AOF
1.什麼是持久化
簡單的說就是指資料放到斷電後,仍然不會丟失的裝置上,也就是我們通常理解的硬碟上
2.資料庫在進行寫操作的時候,經歷那些過程
- 客戶端向資料庫服務端傳送寫操作(資料在客戶端的記憶體中)
- 資料庫服務端接收到寫請求的資料(資料在服務端的記憶體中)
- 資料庫服務端呼叫write這個系統呼叫,將資料往磁碟上寫(資料在系統記憶體的緩衝區中)
- 作業系統將緩衝區中的資料轉移到磁碟控制器上(資料在磁碟快取中)
- 磁碟控制器將資料寫到磁碟的物理介質中(資料真正落到磁碟上)
3.Redis提供了兩種持久化機制
- RDB持久化機制是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟
- AOF持久化機制redis會將每一個收到的寫命令都通過write函式追加到檔案中(預設是 appendonly.aof)去
4.RDB持久化機制的詳細介紹
4.1-RDB是redis預設的持久化機制,這種方式是將記憶體中的資料以快照的形式寫入到二進位制檔案中去,預設檔案
名為dump.rdb
4.2-實現方式是通過redis.conf檔案中的配置實現的
save 900 1 //900秒內,如果超過了1個key被修改,則發起快照儲存 save 300 10 //300秒內,如果超過了10個key被修改,則發起快照儲存 save 60 10000
4.3-RDB檔案的儲存過程
4.3.1 符合RDB持久化條件時,redis呼叫fork,開啟子程序,現在存在兩個程序一個父程序,一個子程序
4.3.2 父程序負責處理客戶端請求,子程序負責把記憶體中的資料寫入臨時檔案
4.3.3 當子程序將快照完整的寫入臨時檔案後,用臨時檔案替換原來的快照檔案,退出子程序
由於os的寫時複製機制(copy on write)父子程序會共享相同的物理頁面,當父程序處理寫請求時
os會為父程序要修改的頁面建立副本,而不是寫共享的頁面。所以子程序的地址空間內的資料是fork時刻
整個資料庫的一個快照。
4.4-redis-cli端也可以通過save或者bgsave命令來通知redis做一次快照持久化,save操作時通過主執行緒進行快照操作的,
由於redis是用一個主執行緒進行處理所有client端的請求,所以這種方式會阻塞所有的客戶端請求
4.5-採用RDB方式的優點
- 一旦採用這種方式,那麼整個reids資料庫就只包含一個檔案,這樣方便進行資料的備份(直接拷貝整個檔案就可)
- 方便備份,可以很容易的把一個一個的RDB檔案拷貝到其他儲存介質上
- RDB在進行大資料集的恢復時,比AOF方式速度塊
- RDB方式可以使Redis最大效能化,父程序在儲存RDB檔案資料時唯一要做的就是fork出一個子程序,子程序進行處理接下來RDB檔案儲存的所有工作,父程序無需進行任何的磁碟I/O操作
5.AOF持久化機制的詳細介紹
5.1 AOF持久化機制實現的方式-當redis重啟時會通過重新執行appendonly.aof檔案中的命令來在記憶體中重建整個資料庫
5.2 AOF持久化機制的實現方式
appendonly no // 預設不開啟 開啟配置 yes
appendfilename "appendonly.aof" // 預設redis寫操作命令儲存檔案的檔名
# appendfsync always //每次收到寫命令,立即強轉寫入磁碟,最慢的,保證完整的持久化
appendfsync everysec // 預設每秒強制寫入磁碟一次,在效能和持久化方面做了折中,推薦
# appendfsync no //完全依賴os,效能最好,持久化沒保證
5.3 AOF持久化機制帶來的問題,持久化檔案會越來越大;但是檔案中可能存在冗餘的命令,舉例說明:
執行incr count 命令100次,aof檔案會記錄100條命令的記錄
上面的命令等價於
set count 100
如果能把上面100條命令替換成 下面的 一條命令,這樣可以節省99條命令的空間
5.4 針對aof記錄冗餘命令的情況,redis-cli客戶端提供了bgrewriteaof命令,來壓縮aof的持久化檔案;收到此命令,redis會
使用與快照類似的方式將記憶體中的資料 以命令的方式寫入到臨時檔案中去,最後替換原來的檔案
5.4.1 當redis-cli執行bgrewriteaof命令時,redis呼叫fork,開啟子程序,現在存在兩個程序一個父程序,一個子程序
5.4.2 子程序根據記憶體中的資料庫快照,往臨時檔案中寫入重建資料庫的命令
5.4.3 父程序繼續處理client端的請求,此時,父程序除了把寫命令寫入原aof的持久化檔案外;同時把收到的寫命令快取
起來,這部分命令是在子程序進行快照處理期間發生的操作,需要在臨時檔案快照處理完成後,追加到臨時檔案中去,這樣
才能用臨時檔案替換原來的aof持久化檔案
5.4.4 當子程序把資料庫快照內容已命令的方式寫入臨時檔案完成後,子程序傳送訊號通知父程序,然後父程序把快取的
命令寫入臨時檔案
5.4.5 現在父程序可以使用臨時檔案替換老的aof檔案,後面收到的寫命令也開始往新的aof檔案中追加
5.5 AOF持久化的優勢
5.5.1 AOF 的預設策略為每秒鐘 fsync 一次,在這種配置下,Redis 仍然可以保持良好的效能,並且就算髮生故障停機,也最多隻會丟失一秒鐘的資料
5.5.2 AOF 檔案是一個只進行追加操作的日誌檔案(append only log), 因此對 AOF 檔案的寫入不需要進行 seek(查詢) , 即使日誌因為某些原因而包含了未寫入完整的命令(比如寫入時磁碟已滿,寫入中途停機,等等), redis-check-aof 工具也可以輕易地修復這種問題。Redis 可以在 AOF 檔案體積變得過大時,自動地在後臺對 AOF 進行重寫
5.5.3 AOF 檔案有序地儲存了對資料庫執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式儲存, 因此 AOF 檔案的內容非常容易被人讀懂, 對檔案進行分析也很輕鬆。 匯出 AOF 檔案也非常簡單: 舉個例子, 如果你不小心執行了 FLUSHALL 命令, 但只要 AOF 檔案未被重寫, 那麼只要停止伺服器, 移除 AOF 檔案末尾的 FLUSHALL 命令, 並重啟 Redis , 就可以將資料集恢復到 FLUSHALL 執行之前的狀態。
注意可以開啟混合持久化-配置屬性為 aof-use-rdb-preamble yes