redis(11)--AOF持久化
目錄
持久化實現
命令追加
寫入與同步
載入與數據還原
還原步驟
AOF重寫
AOF重寫實現
AOF 后臺重寫
AOF 后臺重寫的觸發條件
Redis 分別提供了 RDB 和 AOF 兩種持久化機制:
- RDB 將數據庫的快照(snapshot)以二進制的方式保存到磁盤中。
- AOF 則以協議文本的方式,將所有對數據庫進行過寫入的命令(及其參數)記錄到 AOF 文件,以此達到記錄數據庫狀態的目的。
被寫入AOF文件的所有命令都是以協議文本方式保存,SELECT命令是服務器自動添加。
持久化實現
命令追加
當AOF功能打開時,服務器執行完一個寫入命令后,會以協議格式將命令寫入aof_buf緩沖區。
寫入與同步
Redis服務器的一個事件循環(loop)中,每次結束循環前,都會判斷是否需要把aof_buf緩沖區的內容寫入到AOF文件。然后再把文件保存(同步)到磁盤。
為了提供文件效率,現代操作系統,當寫數據到文件時,通常會將數據保存在一個內存緩沖區,等待內存緩沖區被寫滿或超過指定時限,才將緩沖區數據寫入磁盤。
其行為由配置appendfsync決定:
- always:所有aof_buf內容寫入AOF,并同步。
- everysec:默認值。所有aof_buf內容寫入AOF,如果上次同步已超過1秒,則再次同步(同步操作由一個線程專門負責)。
- no:所有aof_buf內容寫入AOF。同步由操作系統控制。
載入與數據還原
還原步驟
為了避免對數據的完整性產生影響, 在服務器載入數據的過程中, 只有和數據庫無關的訂閱與發布功能可以正常使用, 其他命令一律返回錯誤。
AOF重寫
AOF 文件通過同步 Redis 服務器所執行的命令, 從而實現了數據庫狀態的記錄, 但是, 這種同步方式會造成一個問題: 隨著運行時間的流逝, AOF 文件會變得越來越大。
為了解決以上的問題, Redis 需要對 AOF 文件進行重寫(rewrite): 創建一個新的 AOF 文件(當前狀態快照)來代替原有的 AOF 文件, 新 AOF 文件和原有 AOF 文件保存的數據庫狀態完全一樣, 但新 AOF 文件的體積小于等于原有 AOF 文件的體積。
AOF重寫實現
所謂的“重寫”其實是一個有歧義的詞語, 實際上, AOF 重寫并不需要對原有的 AOF 文件進行任何寫入和讀取, 它針對的是數據庫中鍵的當前值。
AOF 后臺重寫
AOF 重寫程序可以很好地完成創建一個新 AOF 文件的任務, 但是, 在執行這個程序的時候, 調用者線程會被阻塞。
很明顯, 作為一種輔佐性的維護手段, Redis 不希望 AOF 重寫造成服務器無法處理請求, 所以 Redis 決定將 AOF 重寫程序放到(后臺)子進程里執行, 這樣處理的最大好處是:
子進程進行 AOF 重寫期間,主進程可以繼續處理命令請求。
子進程帶有主進程的數據副本,使用子進程而不是線程,可以在避免鎖的情況下,保證數據的安全性。
不過, 使用子進程也有一個問題需要解決: 因為子進程在進行 AOF 重寫期間, 主進程還需要繼續處理命令, 而新的命令可能對現有的數據進行修改, 這會讓當前數據庫的數據和重寫后的 AOF 文件中的數據不一致。
為了解決這個問題, Redis 增加了一個 AOF 重寫緩存, 這個緩存在 fork 出子進程之后開始啟用, Redis 主進程在接到新的寫命令之后, 除了會將這個寫命令的協議內容追加到現有的 AOF 文件之外, 還會追加到這個緩存中。
換言之, 當子進程在執行 AOF 重寫時, 主進程需要執行以下三個工作:
處理命令請求。
將寫命令追加到現有的 AOF 文件中。
將寫命令追加到 AOF 重寫緩存中。
這樣一來可以保證:
當子進程完成 AOF 重寫之后, 它會向父進程發送一個完成信號, 父進程在接到完成信號之后, 會調用一個信號處理函數, 并完成以下工作:
當步驟 1 執行完畢之后, 現有 AOF 文件、新 AOF 文件和數據庫三者的狀態就完全一致了。
當步驟 2 執行完畢之后, 程序就完成了新舊兩個 AOF 文件的交替。
這個信號處理函數執行完畢之后, 主進程就可以繼續像往常一樣接受命令請求了。 在整個 AOF 后臺重寫過程中, 只有最后的寫入緩存和改名操作會造成主進程阻塞, 在其他時候, AOF 后臺重寫都不會對主進程造成阻塞, 這將 AOF 重寫對性能造成的影響降到了最低。
AOF 后臺重寫的觸發條件
AOF 重寫可以由用戶通過調用 BGREWRITEAOF 手動觸發。
另外, 服務器在 AOF 功能開啟的情況下, 會維持以下三個變量:
- 記錄當前 AOF 文件大小的變量 aof_current_size 。
- 記錄最后一次 AOF 重寫之后, AOF 文件大小的變量 aof_rewrite_base_size 。
- 增長百分比變量 aof_rewrite_perc 。
每次當 serverCron 函數執行時, 它都會檢查以下條件是否全部滿足, 如果是的話, 就會觸發自動的 AOF 重寫:
默認情況下, 增長百分比為 100% , 也即是說, 如果前面三個條件都已經滿足, 并且當前 AOF 文件大小比最后一次 AOF 重寫時的大小要大一倍的話, 那么觸發自動 AOF 重寫。
?
?
總結
以上是生活随笔為你收集整理的redis(11)--AOF持久化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis(10)--RDB持久化
- 下一篇: redis(12)--事件,客户端,服务