Reids 持久化AOF 重寫實現原理


AOF重寫

AOF重寫並不需要對原有AOF文件進行任何的讀取,寫入,分析等操作,這個功能是通過讀取服務器當前的數據庫狀態來實現的。(auto-aof-rewrite-percentage和auto-aof-rewrite-min-size配置觸發AOF重寫的條件。       )

然后用一條RPUSH list "3" "4" "1" "3" "4"代替前面的5條命令。

AOF重寫功能的實現原理

  • 首先從數據庫中讀取鍵現在的值,然后用一條命令去記錄鍵值對,代替之前記錄該鍵值對的多個命令;

AOF后台重寫

  • aof_rewrite函數可以創建新的AOF文件,但是這個函數會進行大量的寫入操作,所以調用這個函數的線程將被長時間的阻塞,因為Redis服務器使用單線程來處理命令請求;所以如果直接是服務器進程調用AOF_REWRITE函數的話,那么重寫AOF期間,服務器將無法處理客戶端發送來的命令請求;
  • Redis不希望AOF重寫會造成服務器無法處理請求,所以Redis決定將AOF重寫程序放到子進程(后台)里執行。這樣處理的最大好處是:
    • 子進程進行AOF重寫期間,主進程可以繼續處理命令請求;
    • 子進程帶有主進程的數據副本,使用子進程而不是線程,可以避免在鎖的情況下,保證數據的安全性

使用子進程進行AOF重寫的問題

  • 子進程在進行AOF重寫期間,服務器進程還要繼續處理命令請求,而新的命令可能對現有的數據進行修改,這會讓當前數據庫的數據和重寫后的AOF文件中的數據不一致。

如何修正

  • 為了解決這種數據不一致的問題,Redis增加了一個AOF重寫緩存,這個緩存在fork出子進程之后開始啟用,Redis服務器主進程在執行完寫命令之后,會同時將這個寫命令追加到AOF緩沖區和AOF重寫緩沖區
  • 即子進程在執行AOF重寫時,主進程需要執行以下三個工作:
    • 執行client發來的命令請求;
    • 將寫命令追加到現有的AOF文件中;
    • 將寫命令追加到AOF重寫緩存中。

 

效果

    • 可以保證: 
      • AOF緩沖區的內容會定期被寫入和同步到AOF文件中,對現有的AOF文件的處理工作會正常進行
      • 從創建子進程開始,服務器執行的所有寫操作都會被記錄到AOF重寫緩沖區中

 

完成AOF重寫之后

  • 當子進程完成對AOF文件重寫之后,它會向父進程發送一個完成信號,父進程接到該完成信號之后,會調用一個信號處理函數,該函數完成以下工作:

    • 將AOF重寫緩存中的內容全部寫入到新的AOF文件中;這個時候新的AOF文件所保存的數據庫狀態和服務器當前的數據庫狀態一致;
    • 對新的AOF文件進行改名,原子的覆蓋原有的AOF文件;完成新舊兩個AOF文件的替換。
  • 當這個信號處理函數執行完畢之后,主進程就可以繼續像往常一樣接收命令請求了。在整個AOF后台重寫過程中,只有最后的“主進程寫入命令到AOF緩存”和“對新的AOF文件進行改名,覆蓋原有的AOF文件。”這兩個步驟(信號處理函數執行期間)會造成主進程阻塞,在其他時候,AOF后台重寫都不會對主進程造成阻塞,這將AOF重寫對性能造成的影響降到最低。

觸發AOF后台重寫的條件

  • AOF重寫可以由用戶通過調用BGREWRITEAOF手動觸發。
  • 服務器在AOF功能開啟的情況下,會維持以下三個變量:

    • 記錄當前AOF文件大小的變量aof_current_size
    • 記錄最后一次AOF重寫之后,AOF文件大小的變量aof_rewrite_base_size
    • 增長百分比變量aof_rewrite_perc
  • 每次當serverCron(服務器周期性操作函數)函數執行時,它會檢查以下條件是否全部滿足,如果全部滿足的話,就觸發自動的AOF重寫操作:

    • 沒有BGSAVE命令(RDB持久化)/AOF持久化在執行;
    • 沒有BGREWRITEAOF在進行;
    • 當前AOF文件大小要大於server.aof_rewrite_min_size(默認為1MB),或者在redis.conf配置了auto-aof-rewrite-min-size大小;
    • 當前AOF文件大小和最后一次重寫后的大小之間的比率等於或者等於指定的增長百分比(在配置文件設置了auto-aof-rewrite-percentage參數,不設置默認為100%)

如果前面三個條件都滿足,並且當前AOF文件大小比最后一次AOF重寫時的大小要大於指定的百分比,那么觸發自動AOF重寫。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM