前言
Redis的資料正常都是存儲在記憶體内,如果當機突然發生,資料就會全部丢失,是以需要提供一種方式保證redis的資料不會因為故障而丢失,這種機制就是redis的持久化機制。
redis的持久化機制分為:
快照 snapshot模式 全量模式
快照,是一次全量的備份,是記憶體資料二進制序列化形式,在存儲上非常緊湊
AOF日志模式 增量模式
AOF日志是連續的增量備份,長期運作過程中,會變得無比龐大,而且,如果發生當機,需要讀取所有的日志檔案,進行恢複,需要大量的時間,是以需要定期對AOF重寫,瘦身日志檔案

快照原理
正如我們之前,聊過的,redis是一款單線程程式,該線程要同時負責多個用戶端的并發讀寫操作和記憶體資料結構的邏輯讀寫。
在服務線上請求的同時,Redis需要進行記憶體快照,記憶體快照要求Redis必須進行檔案IO操作,因為是單線程,是以檔案IO操作就不能使用多路複用API。
意味着,Redis在進行完成服務線上請求的同時,還要進行檔案IO操作,會嚴重影響伺服器的性能,
同時,Redis不能阻塞用戶端的請求,導緻線上業務不可用,那麼Redis就需要一邊持久化,一邊進行響應用戶端請求。
針對以上問題難點,Redis采用多線程COW(Copy On write)機制來實作快照持久化。
fork(多線程)
Redis是有狀态的節點,每次用戶端請求服務端對資料的寫操作,都會觸發狀态的改變。基于全量模式的持久化,通過在狀态改變的瞬間,觸發snapshot進行儲存。
Redis的全量寫入包含兩種方式:SAVE BGSAVE
save可以通過用戶端顯式觸發,也可以在redis shutdown時觸發,save本身通過redis指令,單線程串行化執行儲存。阻塞其他的操作。
bgsave可以通過用戶端顯式觸發,也可以通過定時任務觸發,也可以在主從模式下,由從節點觸發。
對于bgsave,redis在持久化時,調用glibc函數fork産生一個子程序,快照持久化,完全交給子程序處理,父程序繼續處理用戶端請求。
子程序做資料持久化,不會修改現有的記憶體資料結構,隻是對資料結構進行周遊讀取,序列化,寫入到磁盤中。
相比save,bgsave不會影響父程序執行處理用戶端請求,但是産生子程序,增加伺服器記憶體的開銷。産生fork程序,會造成在複制父程序中,存在秒級的不可用
AOF原理
在Redis中,增量持久化稱為AOF(Append-only file)方式。Redis僅對資料的變化進行存儲,類似于日志檔案。
AOF日志檔案存儲的是Redis伺服器的順序指令序列,AOF日志隻記錄記憶體改變的指令。
Redis的增量持久化,存在于每次處理完寫指令之後,通過propagate函數觸發。
Redis的AOF包含三種同步政策:
always 每次執行完指令,直接同步觸發fsync方法,強制資料落地磁盤。會降低redis的吞吐量,每次當落地成功,才響應給用戶端,是以此種方式,很大程度的有很好的容錯能力
every second 每秒異步觸發一次fsync方法。
no 不顯式調用fsync方法,由作業系統決定什麼時候落地。
對于Redis資料的回放,即對資料的重寫,全量和增量,觸發時機一緻。
Redis 4.0 混合持久化
重新開機redis時,很少使用rdb即快照方式進行恢複資料,因為會丢失大量資料,通常采用AOF才進行重放。但是AOF日積月累會很龐大,是以會花費很長時間進行重放。
Redis 4.0為解決上述問題,采用混合持久化。在重新開機redis時,進行先加載rdb内容,然後重放增量AOF檔案,此時,重新開機效率會優化很多。
更多的,可以參考下官方介紹。