redis的持久化
- 一、概述
- 二、持久化方式
- 1、RDB 持久化
- 2、AOF 持久化
- 三、RDB與AOF對比
- 1、RDB優缺點
- 2、AOF優缺點
- 四、Redis 持久化配置
- 1、RDB配置
- (1)前臺命令方式(save)
- (2)后臺命令方式(bgsave)
- (3)自動執行(組態檔)
- 2、AOF配置(默認關閉)
- 1、重寫功能
- (1)手動重寫bgrewriteaof
- (2)自動重寫
一、概述
Redis 是一種高級 key-value 資料庫,它跟 Memcached 類似,不過資料可以持久化, 而且支持的資料型別很豐富,有字串、串列、集合和有序集合,支持在服務器端計算集合 (difference)等,還支持多種排序功能,所以 Redis 也可以被看成是一個資料結構服務器, Redis 的所有資料都是保存在記憶體中,然后不定期的通過異步方式保存到磁盤上(這稱為“半持久化模式”);也可以把每一次資料變化都寫入到一個 append only file(aof)里面(這稱 為“全持久化模式”), 由于 Redis 的資料都存放在記憶體中,如果沒有配置持久化,Redis 重啟后資料就全丟失了,所以,需要開啟 Redis 的持久化功能,將資料保存到磁盤上,當 Redis 重啟后,可以從磁盤中恢復資料,
二、持久化方式
Redis 提供兩種方式進行持久化,一種是 RDB 持久化(原理是將 Reids 在記憶體中的資料庫記錄定時 dump 到磁盤上的 RDB 持久化),另外一種是AOF(append only file)持久化(原理是將 Reids 的操作日志以追加的方式寫入檔案)
1、RDB 持久化
RDB 持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁盤,實際操作程序是 fork 一個子行程,先將資料集寫入臨時檔案,寫入成功后,再替換之前的檔案,用二進制壓縮存盤

2、AOF 持久化
AOF 持久化以日志的形式記錄服務器所處理的每一個寫、洗掉操作,查詢操作不會記錄,以文本的方式記錄,可以打開檔案看到詳細的操作記錄,

三、RDB與AOF對比
1、RDB優缺點
RDB優點:
- 一旦采用該方式,那么整個 Redis 資料庫將只包含一個檔案,這對于檔案備份而言是非常完美的,比如,計劃每個小時歸檔一次最近 24
小時的資料,同時還要每天歸檔一 次最近 30 天的資料,通過這樣的備份策略,一旦系統出現災難性故障,可以非常容易地進行恢復, - 對于災難恢復而言,RDB 是非常不錯的選擇,可以非常輕松的將一個單獨的檔案壓縮后再轉移到其它存盤介質上,
- 性能最大化,對于 Redis 的服務行程而言,在開始持久化時,它唯一需要做的只是 fork
出子行程,之后再由子行程完成這些持久化的作業,這樣就可以極大的避免服務行程執行 IO 操作了, - 相比于 AOF 機制,如果資料集很大,RDB 的啟動效率會更高
RDB缺點:
- 如果想保證資料的高可用性,即最大限度的避免資料丟失,那么 RDB
將不是一個很好的選擇,因為系統一旦在定時持久化之前出現宕機現象,此前沒有來得及寫入磁盤的資料都將丟失, - 由于 RDB 是通過 fork 子行程來協助完成資料持久化作業的,因此當資料集較大時,可能會導致整個服務器停止服務幾百毫秒,甚至是 1秒鐘,
2、AOF優缺點
AOF優點:
- AOF 機制可以帶來更高的資料安全性,即資料持久性,Redis 中提供了 3
種同步策略,即每秒同步、每次修改同步和不同步,事實上,每秒同步也是異步完成的,其效率也是非常高的,弊端是一旦系統出現宕機現象,那么這一秒鐘之內修改的資料將會丟失,而每次修改同步,可以將其視為同步持久化,即每次發生的資料變化都會被立即記錄到磁盤中,這種方式在效率上是最低的, - 由于該機制對日志檔案的寫入操作采用的是 append 模式,因此在寫入程序中即使出現宕機現象,也不會破壞日志檔案中已經存在的內容,然而如果本次操作只是寫入了一半 資料就出現了系統崩潰問題,那么在 Redis
下一次啟動之前,可以通過 redis-check-aof 工具來解決資料一致性的問題, - 如果日志過大,Redis 可以自動啟用 rewrite 機制,即 Redis 以 append
模式不斷地將修改資料寫入到老的磁盤檔案中,同時 Redis 還會創建一個新的檔案用于記錄此期間 有哪些修改命令被執行,因此在進行rewrite 切換時可以更好的保證資料安全性, - AOF 包含一個格式清晰、易于理解的日志檔案用于記錄所有的修改操作,事實上,也可以通過該檔案完成資料的重建,
AOF缺點:
- 對于相同數量的資料集而言,AOF 檔案通常要大于 RDB 檔案,RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快,
- 根據同步策略的不同,AOF 在運行效率上往往會慢于 RDB,每秒同步策略的效率是比較高的,同步禁用策略的效率和 RDB 一樣高效
四、Redis 持久化配置
1、RDB配置
(1)前臺命令方式(save)
save指令:手動保存操作,執行一次就產生rdb檔案
首先連接到資料庫,里面暫時沒有資料,新建一個key
[root@redis ~]# redis-cli
127.0.0.1:6379>
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> get name
"zhangsan"
127.0.0.1:6379> keys *
1) "name"
在資料目錄里沒有產生任何檔案
[root@redis 6379]# ll
總用量 0
這時退出連接,停止redis服務,在資料目錄中多了一個.rdb檔案,打開是亂碼,這個就是默認的rdb檔案,因為默認開啟了rdb功能,只有關閉服務的時候會產生,相當于是對上次連接資料庫進行的操作拍了快照保存下來
[root@redis 6379]# ll
總用量 4
-rw-r--r-- 1 root root 112 9月 12 08:33 dump.rdb
[root@redis 6379]# cat dump.rdb
REDIS0009 redis-ver5.0.7
redis-bits?eT\used-memxa
?preamble~?mzhangsan?¨錻l[root@redis 6379]#
現在洗掉這個rdb檔案,重啟服務,重新連接資料庫
[root@redis 6379]# rm -rf dump.rdb
[root@redis 6379]# ll
總用量 0
資料庫有一個key,我們輸入save之后再查看資料目錄,立即多了一個rdb檔案
[root@redis ~]# redis-cli
127.0.0.1:6379>
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> save
OK
[root@redis 6379]# ll
總用量 4
-rw-r--r-- 1 root root 112 9月 12 08:42 dump.rdb
這時我們再set一個key并save,觀察rdb檔案的大小,變大了,查看檔案內容,雖然看不懂,但是有看到age的字樣,說明剛才那條操作被保存了
127.0.0.1:6379> set age 30
OK
127.0.0.1:6379> save
OK
[root@redis 6379]# ll
總用量 4
-rw-r--r-- 1 root root 112 9月 12 08:42 dump.rdb
[root@redis 6379]# ll
總用量 4
-rw-r--r-- 1 root root 119 9月 12 08:45 dump.rdb
[root@redis 6379]# vim dump.rdb
REDIS0009ú redis-ver^E5.0.7ú
redis-bitsà@ú^Ectime?;^Z\_ú^Hused-mem?¨^E^M^@ú^Laof-preambleà^@t^@?^B^@^@^Cageà^^^@^Dname^Hzhangsan?ù?3?ú5^A
組態檔中rdb相關引數,默認都是設定好的
242 rdbcompression yes <----是否壓縮
251 rdbchecksum yes <----是否校驗,檢查保存的資料是否收到損壞,會消耗一定性能
254 dbfilename dump.rdb <----默認的rdb檔案名,可以自定義但是必須.rdb結尾
但生產環境不建議用save指令,會拉性能,因為一旦save的時間過長,會阻塞redis服務器,因為它是單執行緒作業的,一個指令完成才執行下個指令,所以為了解決這個問題,出現了在后臺save的方式
(2)后臺命令方式(bgsave)
現在定義一個key,然后執行bgsave,顯示在后臺運行了,不占用前臺資源,你可以做其他的操作
127.0.0.1:6379> set address nanjing
OK
127.0.0.1:6379> bgsave
Background saving started
[root@redis 6379]# ll
總用量 4
-rw-r--r-- 1 root root 136 9月 12 09:03 dump.rdb
[root@redis 6379]# vim dump.rdb
REDIS0009ú redis-ver^E5.0.7ú
redis-bitsà@ú^Ectime?O^^\_ú^Hused-mem??^E^M^@ú^Laof-preambleà^@t^@?^C^@^@^Gaddress^Gnanjing^@^Dname^Hzhangsan^@^Cageà^^??<82>?F)ê.s
bgsave不是立即執行,它是針對save阻塞問題做的優化
236 stop-writes-on-bgsave-error yes <-----后臺存盤程序中如果出現錯誤現象是否停止保存操作
(3)自動執行(組態檔)
Redis 會將資料集的快照 dump 到 dump.rdb 檔案中,此外,也可以通過組態檔來修改 Redis 服務器 dump 快照的頻率,這種方式本質還是用的bgsave指令操作的
格式:
save second changes 在多長時間以內,只要是這么多的key發生變化了它就執行save指令
219 save 900 1 在 900 秒(15 分鐘)之后,如果至少有 1 個 key 發生變化,則 dump 記憶體快照
220 save 300 10 在 300 秒(5 分鐘)之后,如果至少有 10 個 key 發生變化,則 dump
記憶體快照,
221 save 60 10000 在 60 秒(1 分鐘)之后,如果至少有 10000 個 key 發生變化,則 dump 記憶體快照
為了觀察實驗現象,設定10s內2個操作就保存一次
219 #save 900 1
220 #save 300 10
221 #save 60 10000
222 save 10 2
連接到資料庫,10s內設定兩個key
[root@redis ~]# redis-cli
127.0.0.1:6379> set name chenyan
OK
127.0.0.1:6379> set age 40
OK
因為一開始將dump.rdb刪掉了,所以目錄是空的,2個操作之后就出現dump.rdb了
[root@redis 6379]# ll
總用量 0
[root@redis 6379]# ll
總用量 4
-rw-r--r-- 1 root root 135 9月 12 14:17 dump.rdb
再get一下兩個的值
127.0.0.1:6379> get name
"chenyan"
127.0.0.1:6379> get age
"40"
可以看到因為get沒有對資料進行實質的操作,資料沒有任何改變,所以rdb檔案是不存盤的,所以檔案大小沒有變化
[root@redis 6379]# ll
總用量 4
-rw-r--r-- 1 root root 135 9月 12 14:17 dump.rdb
- 具體save的頻率最侄訓是要根據業務需要設定
- get指令是不會變化的,因為key沒有改變
- set同一個key值,也不會改變,因為資料沒有發生變化
2、AOF配置(默認關閉)
在 Redis 的組態檔中存在三種同步方式,它們分別是
- appendfsync always:每次有資料修改發生時都會寫入 AOF 檔案
- appendfsynceverysec:每秒鐘同步一次,該策略為 AOF 的預設策略
- appendfsync no:系統控制
本例我們設定第一種方式aof
首先需要在組態檔里開啟aof,如下所示,然后重啟服務
700 appendonly yes <---開啟aof持久化
704 appendfilename "appendonly.aof"
729 appendfsync always
730 #appendfsync everysec
731 # appendfsync no
[root@redis ~]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...
這時我們發現在資料目錄里已經有了一個aof檔案,但此時檔案大小為0,在資料庫中set一個key,aof檔案就記錄資料了
[root@redis 6379]# ll
總用量 4
-rw-r--r-- 1 root root 0 9月 12 14:33 appendonly.aof
-rw-r--r-- 1 root root 135 9月 12 14:33 dump.rdb
127.0.0.1:6379> set id 1
OK
[root@redis 6379]# ll
總用量 8
-rw-r--r-- 1 root root 51 9月 12 14:33 appendonly.aof
-rw-r--r-- 1 root root 135 9月 12 14:33 dump.rdb
再次set一個key,觀察aof的檔案大小,又變大了,因為又執行了一次操作
127.0.0.1:6379> set hobby game
OK
[root@redis 6379]# ll
總用量 8
-rw-r--r-- 1 root root 85 9月 12 14:34 appendonly.aof
-rw-r--r-- 1 root root 135 9月 12 14:33 dump.rdb
我們來get一下key,發現aof檔案大小是沒有改變的,因為資料沒有改變
127.0.0.1:6379> get id
"1"
[root@redis 6379]# ll
總用量 8
-rw-r--r-- 1 root root 85 9月 12 14:34 appendonly.aof
-rw-r--r-- 1 root root 135 9月 12 14:33 dump.rdb
1、重寫功能
Redis 會不斷地將被執行的命令記錄到 AOF 檔案里面,所以隨著 Redis 不斷運行,AOF 檔案的體積也會不斷增長,在極端情況下,體積不斷增大的 AOF 檔案甚至可能會用完硬碟 的所有可用空間,Redis 在重啟之后需要通過重新執行 AOF 檔案記錄的所有寫命令來還原資料集,所以如果 AOF 檔案的體積非常大,那么還原操作執行的時間就可能會非常長,
(1)手動重寫bgrewriteaof
為了解決 AOF 檔案體積不斷增大的問題,用戶可以向 Redis 發送 BGREWRITEAOF 命令,BGREWRITEAOF 命令會通過移除 AOF 檔案中的冗余命令來重寫(rewrite)AOF 檔案,使 AOF 檔案的體積盡可能地變小,
為了測驗,洗掉原來的aof檔案然后重啟服務
[root@redis 6379]# rm -rf appendonly.aof
[root@redis 6379]# ll
總用量 4
-rw-r--r-- 1 root root 135 9月 12 14:33 dump.rdb
[root@redis ~]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...
登入資料庫執行以下操作,查看aof檔案的大小
127.0.0.1:6379> set name shengjie
OK
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> set name wangwu
OK
[root@redis 6379]# ll
總用量 8
-rw-r--r-- 1 root root 165 9月 12 14:43 appendonly.aof
-rw-r--r-- 1 root root 122 9月 12 14:43 dump.rdb
然后執行重寫命令,再次觀察aof檔案的大小
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
[root@redis 6379]# ll
總用量 8
-rw-r--r-- 1 root root 110 9月 12 14:44 appendonly.aof
-rw-r--r-- 1 root root 122 9月 12 14:43 dump.rdb
檔案變小了,查看aof檔案的內容,發現只有最后一條name的記錄,因為前面修改的記錄沒有意義
[root@redis 6379]# vim appendonly.aof
REDIS0009ú redis-ver^E5.0.7ú
redis-bitsà@ú^Ectime?Qn\_ú^Hused-mem?e^E^M^@ú^Laof-preambleà^At^@?^A^@^@^Dname^Fwangwu??@yCj<87>y?
BGREWRITEAOF 的作業原理和 BGSAVE 創建快照的作業原理非常相似:Redis 會創 建一個子行程,然后由子行程負責對 AOF 檔案進行重寫,因為 AOF 檔案重寫也需要用到 子行程,所以快照持久化因為創建子行程而導致的性能問題和記憶體占用問題,在 AOF 持久 化中也同樣存在,
(2)自動重寫
與快照持久化通過設定 save 選項來自動執行 BGSAVE 一樣,AOF 持久化也可以通過設定 auto-aof-rewrite-percentage 選 項 和 auto-aof-rewrite-min-size 選項來自動執行 BGREWRITEAOF
771 auto-aof-rewrite-percentage 100
772 auto-aof-rewrite-min-size 64mb
舉個例子,假設用戶對 Redis 設定了配置選項 auto-aof-rewrite-percentage 100 和 auto-aof-rewrite-min-size 64mb,并且啟動了 AOF 持久化,那么當 AOF 檔案的體積大于 64MB,并且 AOF 檔案的體積比上一次重寫之后的體積大了至少一倍(100%)的時候,Redis 將執行 BGREWRITEAOF 命令,如果 AOF 重寫執行的過于頻繁的話,用戶可以考慮將 auto-aof-rewrite-percentage 選項的值設定為 100 以上,這種做法可以讓 Redis 在 AOF 檔案的體積變得更大之后才執行重寫操作,不過也會讓 Redis 在啟動時還原資料集所需的時間變得更長
總結:官方建議同時開啟RDS和AOF,更加安全
持久化的時機:如果同時開啟,那么redis宕機重啟后,會優先選擇AOF檔案,降低丟失資料的量
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/41659.html
標籤:其他
