什麼是持久化?redis
持久化(Persistence),即把數據(如內存中的對象)保存到可永久保存的存儲設備中(如磁盤)。持久化的主要應用是將內存中的對象存儲在數據庫中,或者存儲在磁盤文件中、XML數據文件中等等。
持久化是將程序數據在持久狀態和瞬時狀態間轉換的機制。 ----摘自百度百科
Redis的數據都是存儲在內存中的,因此Redis持久化也就是要把Redis存儲在內存中的數據保存到硬盤。
Redis提供了兩種持久化方式數據庫
先來看看RDB持久化緩存
RDB持久化是指在客戶端輸入save
、bgsave
或者達到配置文件自動保存快照條件時,將Redis 在內存中的數據生成快照保存在名字爲 dump.rdb(文件名可修改)的二進制文件中。服務器
save命令會阻塞Redis服務器進程,直到RDB文件建立完畢爲止,在Redis服務器阻塞期間,服務器不能處理任何命令請求。
在客戶端輸入save網絡
192.168.17.101:6379> save OK
服務端會出現下方字符app
1349:M 30 Jul 17:16:48.935 * DB saved on disk
bgsave命令的工做原理以下函數
在客戶端輸入bgsave性能
192.168.17.101:6379> bgsave Background saving started
服務端會出現下方字符spa
1349:M 30 Jul 17:14:42.991 * Background saving started by pid 1357 1357:C 30 Jul 17:14:42.993 * DB saved on disk 1357:C 30 Jul 17:14:42.993 * RDB: 4 MB of memory used by copy-on-write 1349:M 30 Jul 17:14:43.066 * Background saving terminated with success
注:bgsave命令執行期間
SAVE命令會被拒絕
不能同時執行兩個BGSAVE命令
不能同時執行BGREWRITEAOF和BGSAVE命令
這個須要在配置文件redis.conf中修改,默認的保存策略以下操作系統
save 900 1 # 900 秒內有至少有 1 個鍵被改動 save 300 10 # 300 秒內有至少有 10 個鍵被改動 save 60 10000 # 60 秒內有至少有 1000 個鍵被改動
接下來看看RBD的配置有哪些
################################ SNAPSHOTTING ################################ # 觸發自動保存快照 # save <seconds> <changes> # save <秒> <修改的次數> save 900 1 save 300 10 save 60 10000 # 設置在保存快照出錯時,是否中止redis命令的寫入 stop-writes-on-bgsave-error yes # 是否在導出.rdb數據庫文件的時候採用LZF壓縮 rdbcompression yes # 是否開啓CRC64校驗 rdbchecksum yes # 導出數據庫的文件名稱 dbfilename dump.rdb # 導出的數據庫所在的目錄 dir ./
翻譯來自 http://www.redis.cn
AOF持久化是經過保存Redis服務器所執行的寫命令來記錄數據庫狀態,也就是每當 Redis 執行一個改變數據集的命令時(好比 SET), 這個命令就會被追加到 AOF 文件的末尾。
那麼咱們如何開啓AOF持久化功能呢?
修改redis.conf配置文件,默認是appendonly no(關閉狀態),將no改成yes便可
appendonly yes
在客戶端輸入以下命令也可,可是Redis服務器重啓後會失效
192.168.17.101:6379> config set appendonly yes OK
接下來看看AOF持久化功能的實現
AOF持久化功能的實現能夠分爲命令追加(append)、文件寫入和文件同步(sync)三個步驟。下面就是三個步驟的整個過程。
在Redis客戶端輸入以下命令
192.168.17.101:6379> set learnRedis testAOF OK
appendonly.aof文件會增長以下內容
*2 $6 SELECT $1 0 *3 $3 set $10 learnRedis $7 testAOF
AOF持久化功能開啓時,服務器在執行完一個寫命令以後,會以協議格式將被執行的寫命令追加到服務器狀態的aof_buf緩衝區的末尾。此時緩衝區的記錄尚未寫入到appendonly.aof文件中。
爲何將文件寫入和文件同步合在一塊講呢?由於配置文件中提供了一個appendfsync參數,這個參數控制着文件寫入和同步的行爲。
關於文件的寫入和同步的資料以下
由於爲了提升文件的寫入效率,在現代操做系統中,當用戶調用write函數,將一些數據寫入到文件的時候,os一般會將寫入數據暫時保存在一個內存緩衝區裏面(例如,unix系統實如今內核中設有緩衝區高速緩存或頁高速緩存,當咱們向文件寫入數據時,內核一般先將數據複製到緩衝區中,而後排入隊列,晚些時候再寫入磁盤),這種方式稱爲延遲寫,等到緩衝區的空間被填滿,或者超過了指定的時限,或者內核須要重用緩衝區存放其它磁盤塊數據時,纔會真正將緩衝區中的全部數據寫入到磁盤裏面。
簡單來講就是
文件寫入:只是寫入到了內存緩衝區,可能尚未寫到文件所擁有的磁盤數據塊上
文件同步:將緩衝區中的內容沖洗到磁盤上
appendfsync參數
appendfsync選項的值 | 效果 |
---|---|
always | 每次有新命令時,就將緩衝區數據寫入並同步到 AOF 文件 |
everysec(默認) | 每秒將緩衝區的數據寫入並同步到 AOF 文件 |
no | 將緩衝區數據寫入AOF 文件,可是同步操做到交給操做系統來處理 |
讀取AOF文件並還原數據庫的步驟以下
這時可能會出現一個問題。服務器可能在程序正在對 AOF 文件進行寫入時停機,形成了 AOF 文件出錯,那麼 Redis 在重啓時會拒絕載入這個 AOF 文件,從而確保數據的一致性不會被破壞 當發生這種狀況時, 能夠用如下方法來修復出錯的 AOF 文件:
- 爲現有的 AOF 文件建立一個備份。
- 使用 Redis 附帶的 redis-check-aof 程序,對原來的 AOF 文件進行修復: redis-check-aof –fix
- (可選)使用 diff -u 對比修復後的 AOF 文件和原始 AOF 文件的備份,查看兩個文件之間的不一樣之處。
- 重啓 Redis 服務器,等待服務器載入修復後的 AOF 文件,並進行數據恢復。
另外redis.conf配置文件中還提供了一個參數來控制是否忽略最後一條可能存在問題的指令,以下
aof-load-truncated yes
因爲AOF 持久化是經過不斷地將命令追加到文件的末尾來記錄數據庫狀態的, 因此隨着寫入命令的不斷增長, AOF 文件的體積也會變得愈來愈大。 且有些命令是改變同一數據,是能夠合併成一條命令的。就比如對一個計數器調用了 100 次 INCR,AOF就會存入100 條記錄,其實存入一條數據就能夠了。
因此爲了處理這種狀況,Redis提供了AOF重寫機制。
AOF重寫機制的觸發有兩種機制,一個是經過調用命令BGREWRITEAOF
192.168.17.101:6379> BGREWRITEAOF Background append only file rewriting started
另外一種是根據配置文件中的參數觸發,參數以下
auto-aof-rewrite-percentage 100 #當前AOF文件大小和上一次重寫時AOF文件大小的比值 auto-aof-rewrite-min-size 64mb #文件的最小體積
服務端會出現以下信息
1349:M 30 Jul 17:19:25.311 * Background append only file rewriting started by pid 1392 1349:M 30 Jul 17:19:25.379 * AOF rewrite child asks to stop sending diffs. 1392:C 30 Jul 17:19:25.379 * Parent agreed to stop sending diffs. Finalizing AOF... 1392:C 30 Jul 17:19:25.380 * Concatenating 0.00 MB of AOF diff received from parent. 1392:C 30 Jul 17:19:25.380 * SYNC append only file rewrite performed 1392:C 30 Jul 17:19:25.381 * AOF rewrite: 4 MB of memory used by copy-on-write 1349:M 30 Jul 17:19:25.466 * Background AOF rewrite terminated with success 1349:M 30 Jul 17:19:25.467 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB) 1349:M 30 Jul 17:19:25.467 * Background AOF rewrite finished successfully
重寫步驟
注:AOF重寫不須要對現有的AOF文件進行任何讀取、分析和寫入操做。
############################## APPEND ONLY MODE ############################### # 是否開啓AOF功能 appendonly no # AOF文件件名稱 appendfilename "appendonly.aof" # 寫入AOF文件的三種方式 # appendfsync always appendfsync everysec # appendfsync no # 重寫AOF時,是否繼續寫AOF文件 no-appendfsync-on-rewrite no # 自動重寫AOF文件的條件 auto-aof-rewrite-percentage 100 #百分比 auto-aof-rewrite-min-size 64mb #大小 # 是否忽略最後一條可能存在問題的指令 aof-load-truncated yes
RDB和AOF都是在啓動時加載的,AOF開啓時,會優先從AOF文件從恢復數據 ,AOF關閉時纔會從RDB文件恢復數據。
注:不知從什麼版本開始,開啓AOF功能時AOF文件不存在也不會加載RDB文件了