Redis資料持久化的兩種方式
一、RDB(Redis DataBase)
1.1什麼是RDB
在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,也就是Snapshot 快照,它恢復時是將快照檔案直接讀到記憶體裡,這個快照檔案預設是dump.rdb ,可以在redis.conf 中檢視與修改。
Redis 會單獨建立(fork)一個子程序來進行持久化,會先將資料寫入到一個臨時檔案中,待持久化過程都結束了,再用這個臨時檔案替換上次持久化好的檔案。整個過程中,主程序是不進行任何IO 操作的,這就確保了極高的效能如果需要進行大規模資料的恢復,且對於資料恢復的完整性不是非常敏感,那RDB 方式要比AOF 方式更加的高效。RDB 的缺點是最後一次持久化後的資料可能丟失。其中rdb 儲存的是dump.rdb 檔案。
1.2什麼是fork
fork的作用是複製一個與當前程序一樣的程序。新程序的所有資料(變數、環境變數、程式計數器等)。數值都和原程序一致,但是是一個全新的程序,並作為原程序的子程序。
1.3配置快照
在redis.conf 配置檔案中有關於快照的相關配置如下圖:在滿足下面的配置資訊時將會觸發RDB 。
1.4如何觸發RDB快照
1. 執行Save:save時只管儲存,其它不管,全部阻塞 。
2. 執行BGSAVE:Redis會在後臺非同步進行快照操作,快照同時還可以響應客戶端請求。可以通過lastsave 命令獲取最後一次成功執行快照的時間 。
3. 執行flushall命令,也會產生dump.rdb檔案,但裡面是空的,無意義 。
4. 自定義快照觸發條件 。
1.5資料恢復演示
//1. 更改redis.conf 配置檔案中5 分鐘修改10 次的觸發條件為:30 秒修改1 次
save 30 1
//2.在終端1 中刪除原來的 dump.rdb檔案,保證正確性
[root@localhost bin]# ls
redis-benchmark redis-cli redis-server
//3. 在終端2 中開啟Redis 服務並做了一次設定
127.0.0.1:6379> SET s1 v1
//4. 30 秒後在終端1 中查詢檔案,這時就多了一個dump.rdb 檔案,並將該檔案複製一份
[root@localhost bin]# ls
dump.rdb redis-benchmark redis-cli redis-server
[root@localhost bin]# cp dump.rdb dump_cp.rdb
[root@localhost bin]# ls
dump_cp.rdb redis-benchmark redis-server
dump.rdb redis-cli
//5.在終端2 中清除所有的資料,執行FLUSHDB ,重新啟動Redis 服務,執行keys * 進行查詢,發現並沒有備份資料
127.0.0.1:6379> FLUSHDB
OK
........退出,登入步驟省略
127.0.0.1:6379> keys *
(empty list or set)
//6.原因是執行FLUSHDB 也會觸發快照,dump.rdb 中的資料被清空,所以我們在終端2退出Redis 服務
127.0.0.1:6379> SHUTDOWN
not connected> EXISTS
//7.在終端1 中刪除dump.rdb 空檔案,並將拷貝的dump_cp.rdb(改檔案儲存了原快照資訊) 命名為 dump.rdb
mv dump_cp.rmb dump.rmb
//8.在終端2 中重新開啟Redis 服務,再查詢時就發現s1 資料被恢復了
[root@localhost bin]# ./redis-server /myredis/redis.conf
[root@localhost bin]# ./redis-cli -p 6379
127.0.0.1:6379> keys *
1) "s1"
1.6RDB 的優缺點
適合大規模的資料恢復。
對資料完整性和一致性要求不高。
在一定間隔時間做一次備份,所以如果redis 出故障的話,就會丟失最後一次快照後的所有修改。
fork的時候,記憶體中的資料被克隆了一份,大致2倍的膨脹性需要考慮。
1.7RDB 總結
二、AOF(Append Only File)
2.1什麼是AOF
以日誌的形式來記錄每個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加檔案但不可以改寫檔案,redis 啟動之初會讀取該檔案重新構建資料,換言之,redis 重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作。其中AOF 儲存的是appendonly.aof 檔案,可以在redis.conf 配置檔案中檢視與修改。
相關配置資訊:AOF 預設配置是關閉的。
2.2資料恢復演示
//1.在終端1 中將redis.conf 配置檔案中的appendonly 改為yes
appendonly yes
//2.在終端2 中開啟Redis 的服務,並做一個數據設定,刪除資料庫中的資訊,退出Redis 的服務
[root@localhost bin]# ./redis-server /myredis/redis.conf
[root@localhost bin]# ./redis-cli -p 6379
127.0.0.1:6379> set s1 v1
OK
127.0.0.1:6379> keys *
1) "s1"
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> SHUTDOWN
not connected> exit
//3.在終端1 中檢視查詢該目錄下的檔案,會發現多了一個appendonly.aof 檔案
[root@localhost bin]# ls
appendonly.aof redis-benchmark redis-server
dump.rdb redis-cli
//4.在終端1 中刪除dump.rdb 檔案,防止這個檔案影響,然後檢視appendonly.aof 配置檔案,發現所有的操作都以日誌的形式被記錄下來
[root@localhost bin]# rm -rf dump.rdb
[root@localhost bin]# cat appendonly.aof
*2
......省略一部分資料
0
*1
$7
FLUSHDB
//5.為了讓資料恢復用刪除appendonly.aof 中的FLUSHDB,儲存退出
//6.在終端2 中重新開啟Redis 服務,發現數據被恢復
[root@localhost bin]# ./redis-server /myredis/redis.conf
[root@localhost bin]# ./redis-cli -p 6379
127.0.0.1:6379> keys *
1) "s1"
當appendonly.aof 檔案出現錯誤時(比如亂加一些資料),在啟動Redis 時會報錯,可以使用redis-check-aof –fix進行修復,對不符合語法的資料進行刪除。
2.3rewrite介紹
什麼是rewrite
AOF採用檔案追加方式,檔案會越來越大,為避免出現此種情況,新增了重寫機制,當AOF檔案的大小超過所設定的閾值時,Redis就會啟動AOF檔案的內容壓縮,只保留可以恢復資料的最小指令集.可以使用命令bgrewriteaof。
rewrite 重寫的原理
AOF檔案持續增長而過大時,會fork出一條新程序來將檔案重寫(也是先寫臨時檔案最後再rename),遍歷新程序的記憶體中資料,每條記錄有一條的Set語句。重寫aof檔案的操作,並沒有讀取舊的aof檔案,而是將整個記憶體中的資料庫內容用命令的方式重寫了一個新的aof檔案,這點和快照有點類似。
rewrite 觸發機制
Redis會記錄上次重寫時的AOF大小,預設配置是當AOF檔案大小是上次rewrite後大小的一倍且檔案大於64M時觸發
2.4AOF的優缺點
每修改同步:appendfsync always 同步持久化 每次發生資料變更會被立即記錄到磁碟 效能較差但資料完整性比較好。
每秒同步:appendfsync everysec 非同步操作,每秒記錄 如果一秒內宕機,有資料丟失。
不同步:appendfsync no 從不同步。
相同資料集的資料而言aof檔案要遠大於rdb檔案,恢復速度慢於rdb。
aof執行效率要慢於rdb,每秒同步策略效率較好,不同步效率和rdb相同。
2.5AOF 總結
三、RDB 與 AOF 總結
RDB持久化方式能夠在指定的時間間隔能對你的資料進行快照儲存 。
AOF持久化方式記錄每次對伺服器寫的操作,當伺服器重啟的時候會重新執行這些命令來恢復原始的資料,AOF命令以redis協議追加儲存每次寫的操作到檔案末尾.Redis還能對AOF檔案進行後臺重寫,使得AOF檔案的體積不至於過大 。
只做快取:如果你只希望你的資料在伺服器執行的時候存在,你也可以不使用任何持久化方式 。
在這種情況下,當redis重啟的時候會優先載入AOF檔案來恢復原始的資料,因為在通常情況下AOF檔案儲存的資料集要比RDB檔案儲存的資料集要完整 。
RDB的資料不實時,同時使用兩者時伺服器重啟也只會找AOF檔案。那要不要只使用AOF呢?作者建議不要,因為RDB更適合用於備份資料庫(AOF在不斷變化不好備份),快速重啟,而且不會有AOF可能潛在的bug 。
效能上的建議
因為RDB檔案只用作後備用途,建議只在Slave上持久化RDB檔案,而且只要15分鐘備份一次就夠了,只保留save 900 1這條規則。
如果Enalbe AOF,好處是在最惡劣情況下也只會丟失不超過兩秒資料,啟動指令碼較簡單隻load自己的AOF檔案就可以了。代價一是帶來了持續的IO,二是AOF rewrite的最後將rewrite過程中產生的新資料寫到新檔案造成的阻塞幾乎是不可避免的。只要硬碟許可,應該儘量減少AOF rewrite的頻率,AOF重寫的基礎大小預設值64M太小了,可以設到5G以上。預設超過原大小100%大小時重寫可以改到適當的數值。
如果不Enable AOF ,僅靠Master-Slave Replication 實現高可用性也可以。能省掉一大筆IO也減少了rewrite時帶來的系統波動。代價是如果Master/Slave同時倒掉,會丟失十幾分鐘的資料,啟動指令碼也要比較兩個Master/Slave中的RDB檔案,載入較新的那個。