Redis持久化:AOF模式
來自專欄 Java之鏈
AOF是append-only file的簡稱。
當redis server啟動時,如果沒有開啟AOF模式,則載入AOF文件,否則將載入RDB文件。
如果redis中數據發生變化,那麼不會直接寫到硬碟里,而是先寫到AOF緩衝區aof_buf中。
一 原理
AOF持久化需要三個過程:
1)命令追加:寫到aof_buf中;
2)寫入文件:執行write操作;
3)同步文件:同步到磁碟中。
while(1){ processFileEvents(); // 處理文件事件 processTimeEvents(); // 處理時間事件 flushAppendOnlyFile(); // 是否將aof_buf中的內容寫入和同步到AOF文件裡面}
redis進程是一個死循環,如果發現有寫命令,那麼這些命令會以Redis通信協議的格式添加到aof_buf中(命令追加),並執行appendfsync策略(寫入和同步),這種策略一共有三種:
1)always:將aof_buf中的內容寫入並同步到AOF文件中。
2)everysec:將aof_buf中內容寫如AOF文件中,如果上次同步AOF文件的時間距離現在超過1s,那麼再次同步AOF文件。這個操作是由一個線程專門負責執行的。
3)no:將aof_buf中的內容寫入到AOF文件中,但並不對AOF同步,何時同步交給OS。
用戶調用write函數,並不會直接寫入磁碟,而是將數據暫存在內存緩衝區中,等緩衝區被填滿或者超過指定時限後,會將數據同步到磁碟中(flush).
1的優點是數據安全,效率太低,因為過於頻繁的調用系統;只有在這種策略下,redis的事務是滿足持久化的。
3的優點是效率較高,但是不夠安全,因為buf中的數據可能因為宕機而丟失;
2介於兩者之間,在效率和安全之間達到一個平衡。這裡我們又一次看到折中思想在計算機中的應用。
二 AOF文件重寫
AOF模式的一個問題是AOF文件可能會變得非常大。
通過分析AOF文件,往往發現裡面有太多的重複和冗餘數據,可以生成一個新的AOF文件來代替舊的AOF文件,這就是AOF重寫。這個操作滿足一定條件是,Redis會自動觸發。
AOF重新通過bgRewriteAOF命令來完成,這時會fork一個子進程,這樣主進程還可以繼續處理命令。除此之外,子進程帶有主進程的數據副本,可以在避免鎖的情況下,保證數據的安全性。
AOF重寫面臨的一個問題是:在重寫期間,主進程繼續處理命令,而新的命令有可能還會對現在有數據進行修改,這會導致當前資料庫中的數據和生成的AOF文件不一致。
為了解決上述問題,Redis增加了一個AOF重寫緩衝區rewrite_buf,主進程接收到新的寫命令之後,會把這個命令的協議內容追到rewrite_buf中。這樣主進程在處理命令的時候,一面將命令追加到aof_buf中,一面將寫命令追加到rewrite_buf中。也就是說在重寫的時候,也會更新舊文件,這是為了防止重寫AOF失敗。
當子進程重寫完畢之後,會給父進程發送一個信號,父進程接受到這個信號以後,會調用一個信號處理函數,完成以下工作:
1)將rewrite_buf中的數據全部寫到新的AOF文件中。
2)修改新的AOF文件的文件名(主進程會短暫阻塞),覆蓋舊的文件。
2017-12-27閱:
數據持久化的路徑:內存->buf->文件,分別對應了AOF的三個步驟。
appendfsync策略以時間作為折中的標準。
推薦閱讀:
※如何評價360開源的pika項目?
※SpringBoot集成Redis來實現緩存技術方案
※SSDB 和 Redis 的優缺點各位哪些?
※集群環境中資料庫與緩存的三板斧
※redis的初級使用
TAG:Redis |