1. 程式人生 > >一篇文章徹底理解Redis持久化:RDB和AOF

一篇文章徹底理解Redis持久化:RDB和AOF

![](https://img2020.cnblogs.com/blog/145687/202005/145687-20200511084924277-945052264.jpg) ### 為什麼需要持久化? Redis對資料的操作都是基於記憶體的,當遇到了程序退出、伺服器宕機等意外情況,如果沒有持久化機制,那麼Redis中的資料將會丟失無法恢復。有了持久化機制,Redis在下次重啟時可以利用之前持久化的檔案進行資料恢復。理解和掌握Redis的持久機制,對於Redis的日常開發和運維都有很大幫助,也是在大廠面試經常被問到的知識點。Redis支援的兩種持久化機制: 1. RDB:把當前資料生成快照儲存在硬碟上。 2. AOF:記錄每次對資料的操作到硬碟上。 接下來,我們詳細瞭解一下這兩種持久化機制。 歡迎關注微信公眾號:萬貓學社,每週一分享Java技術乾貨。 ### RDB持久化 RDB(Redis DataBase)持久化是把當前Redis中全部資料生成快照儲存在硬碟上。RDB持久化可以手動觸發,也可以自動觸發。 #### 手動觸發 `save`和`bgsave`命令都可以手動觸發RDB持久化。 ##### save命令 執行`save`命令會手動觸發RDB持久化,但是`save`命令會阻塞Redis服務,直到RDB持久化完成。當Redis服務儲存大量資料時,會造成較長時間的阻塞,不建議使用。 ``` > save OK ``` 執行後,Redis的日誌中記錄: ``` * DB saved on disk ``` ##### bgsave命令 執行`bgsave`命令也會手動觸發RDB持久化,和`save`命令不同是:Redis服務一般不會阻塞。Redis程序會執行fork操作建立子程序,RDB持久化由子程序負責,不會阻塞Redis服務程序。Redis服務的阻塞只發生在fork階段,一般情況時間很短。 ``` >
bgsave Background saving started ``` 執行後,Redis的日誌中記錄: ``` * Background saving started by pid 2645 * DB saved on disk * RDB: 0 MB of memory used by copy-on-write * Background saving terminated with success ``` `bgsave`命令的具體流程如下圖: ![bgsave命令流程](https://img-blog.csdnimg.cn/20200405214335983.jpg#pic_center) 1. 執行`bgsave`命令,Redis程序先判斷當前是否存在正在執行的RDB或AOF子執行緒,如果存在就是直接結束。 2. Redis程序執行fork操作建立子執行緒,在fork操作的過程中Redis程序會被阻塞。 3. Redis程序fork完成後,`bgsave`命令就結束了,自此Redis程序不會被阻塞,可以響應其他命令。 4. 子程序根據Redis程序的記憶體生成快照檔案,並替換原有的RDB檔案。 5. 子程序通過訊號量通知Redis程序已完成。 歡迎關注微信公眾號:萬貓學社
,每週一分享Java技術乾貨。 #### 自動觸發 除了執行以上命令手動觸發以外,Redis內部可以自動觸發RDB持久化。自動觸發的RDB持久化都是採用`bgsave`的方式,減少Redis程序的阻塞。那麼,在什麼場景下會自動觸發呢? 1. 在配置檔案中設定了save的相關配置,如`sava m n`,它表示在m秒內資料被修改過n次時,自動觸發`bgsave`操作。 2. 當從節點做全量複製時,主節點會自動執行`bgsave`操作,並且把生成的RDB檔案傳送給從節點。 3. 執行`debug reload`命令時,也會自動觸發`bgsave`操作。 4. 執行`shutdown`命令時,如果沒有開啟AOF持久化也會自動觸發`bgsave`操作。 #### RDB優點 RDB檔案是一個緊湊的二進位制壓縮檔案,是Redis在某個時間點的全部資料快照。所以使用RDB恢復資料的速度遠遠比AOF的快,非常適合備份、全量複製、災難恢復等場景。 #### RDB缺點 每次進行`bgsave`操作都要執行fork操作建立子經常,屬於重量級操作,頻繁執行成本過高,所以無法做到實時持久化,或者秒級持久化。 另外,由於Redis版本的不斷迭代,存在不同格式的RDB版本,有可能出現低版本的RDB格式無法相容高版本RDB檔案的問題。 歡迎關注微信公眾號:萬貓學社
,每週一分享Java技術乾貨。 ### AOF持久化 AOF(Append Only File)持久化是把每次寫命令追加寫入日誌中,當需要恢復資料時重新執行AOF檔案中的命令就可以了。AOF解決了資料持久化的實時性,也是目前主流的Redis持久化方式。 #### AOF持久化流程 AOF流程如下圖: ![AOF流程](https://img-blog.csdnimg.cn/20200406103514987.jpg#pic_center) 1. 命令追加(append):所有寫命令都會被追加到AOF快取區(aof_buf)中。 2. 檔案同步(sync):根據不同策略將AOF快取區同步到AOF檔案中。 3. 檔案重寫(rewrite):定期對AOF檔案進行重寫,以達到壓縮的目的。 4. 資料載入(load):當需要恢復資料時,重新執行AOF檔案中的命令。 #### 檔案同步策略 AOF持久化流程中的檔案同步有以下幾個策略: 1. **always**:每次寫入快取區都要同步到AOF檔案中,硬碟的操作比較慢,限制了Redis高併發,不建議配置。 2. **no**:每次寫入快取區後不進行同步,同步到AOF檔案的操作由作業系統負責,每次同步AOF檔案的週期不可控,而且增大了每次同步的硬碟的資料量。 3. **eversec**:每次寫入快取區後,由專門的執行緒每秒鐘同步一次,做到了兼顧效能和資料安全。是建議的同步策略,也是預設的策略。 #### 觸發檔案重寫 AOF持久化流程中的檔案重寫可以手動觸發,也可以自動觸發。 1. 手動觸發:使用`bgrewriteaof`命令。 2. 自動觸發:根據auto-aof-rewrite-min-size和auto-aof-rewrite-percentage配置確定自動觸發的時機。auto-aof-rewrite-min-size表示執行AOF重寫時檔案大小的最小值,預設為64MB;auto-aof-rewrite-percentage表示當前AOF檔案大小和上一次重寫後AOF檔案大小的比值的最小值,預設為100。只用前兩者同時超過時才會自動觸發檔案重寫。 歡迎關注微信公眾號:萬貓學社,每週一分享Java技術乾貨。 #### AOF持久化配置 對AOF持久化的具體流程有了瞭解後,我們來看一下如何配置AOF。AOF持久化預設是不開啟的,需要修改配置檔案,如: ``` # appendonly改為yes,開啟AOF appendonly yes # AOF檔案的名字 appendfilename "appendonly.aof" # AOF檔案的寫入方式 # everysec 每個一秒將快取區內容寫入檔案 預設開啟的寫入方式 appendfsync everysec # 執行AOF重寫時AOF檔案大小的增長率的最小值 auto-aof-rewrite-percentage 100 # 執行AOF重寫時檔案大小的最小值 auto-aof-rewrite-min-size 64mb ```

微信公眾號:萬貓學社

微信掃描二維碼

獲得更多Java技術乾貨