Redis-AOF日誌與RDB快照

  AOF日誌與RDB是Reids中兩大持久化機制,當服務器或者Reids宕機的時候能夠經過這兩大機制恢復Redis的數據。sql

  先說說AOF日誌吧,在執行一條操做請求時,Redis先將命令在內存中執行,以後再將命令寫到AOF日誌中,與咱們熟悉的MySQL的redo log日誌先寫日誌再執行sql的順序恰好相反。數據庫

  這麼作的好處主要有兩點:服務器

    • 先執行命令再寫入AOF日誌確保命令不存在語法錯誤能正常的被執行;
    • 不阻塞主線程;

  在Redis中AOF日誌有三種寫回的策略:性能

    • Always,同步寫回。執行完命令當即寫入AOF文件;
    • Everysec,每秒寫回。執行完命令後將命令寫入緩衝區,每秒將緩衝區命令寫入AOF文件;
    • No,由操做系統寫回。執行完命令後將命令寫入緩衝區,由操做系統決定什麼時候將緩衝區命令寫入AOF文件;

  

  因爲持續不斷的操做Redis服務,這時AOF日誌文件的將持續變大,將會帶來一些性能上的問題:spa

    • 系統沒法保存過大的文件;
    • AOF文件過大時將會影響命令寫入的效率;
    • 若是發生宕機,AOF文件過大會致使數據恢復變得緩慢;

  針對AOF文件過大問題Redis採用重寫AOF文件的方式來避免AOF文件過大帶來的性能問題。與AOF日誌由主線程寫入的方式不一樣,AOF重寫由後臺子線程bgrewriteaof 來完成的,這也是爲了不阻塞主線程,致使數據庫性能降低。操作系統

  重寫的過程主要體如今兩個方面:一個拷貝,兩處日誌。線程

  Redis中經過auto-aof-rewrite-min-size、auto-aof-rewrite-percentage來判斷是否觸發重寫機制,當AOF文件大小同時超出這兩個參數設定的值後就會觸發AOF重寫。3d

  當觸發AOF重寫後,主線程會fork一個子線程bgrewriteaof ,同時將複製一份主線程的頁表(一個拷貝)給子線程,這樣子線程就能訪問到內存中的數據了,在不影響主線程的狀況下逐一將數據轉成命令記錄重寫日誌。日誌

  在AOF日誌重寫過程當中,當有新的操做命令的時候,Redis會將命令寫入AOF緩衝區的同時也會寫入重寫AOF的緩衝區(兩處日誌),當重寫完成後,重寫緩衝區的命令會寫入新的AOF文件中。此時,新的AOF文件就能夠代替舊的AOF文件了。blog

  

  你可能會疑惑爲何重寫後的AOF文件會比較小呢?

  由於舊的AOF文件記錄着每一條操做命令,可能存在多條命令執行同一個數據的狀況,而AOF重寫是將內存中的數據轉成命令存儲這樣一條數據就只會存在一條命令,從而達到縮小AOF文件文件大小的目的。

  與AOF日誌相比RDB快照的邏輯就相對簡單一些。

  RDB快照能夠理解爲Redis數據的全量備份,Redis經過兩個命令來生成RDB文件:

    • save:在主線程中執行,會阻塞主線程;
    • bgsave:建立一個子線程去寫入RDB文件,避免了主線程阻塞,Redis默認配置;

  首先在Redis主線程會fork一個子線程bgsave,同時複製一份主線程頁表給bgsave,這樣bgsave子線程就能讀到主線程的內存中的數據了將其寫到RDB快照中,因此不會影響主線程的讀操做。

  可是,若是是一個操做請求這時Redis爲了保證正常操做請求會藉助系統的寫時複製技術(Copy-On-Write, COW),當有操做請求時,主線程會申請一份新的內存空間存放數據同時修改本身的頁表映射。

  這樣既保證了快照的完整性,也保證了主線程的正常操做。

  在Redis4.0後提出了混合使用AOF和RDB快照的方法,先經過全量備份Redis數據的RDB快照,以後經過AOF日誌文件作增量備份。

相關文章
相關標籤/搜索