【Redis】大白話聊聊Redis如何實現持久化
阿新 • • 發佈:2020-06-29
Redis兩種持久化方式:
1》RDB(snapshotting快照)
- 是Redis的預設持久化方式(把資料做一個備份,將資料存放到磁碟中)
這種方式是將記憶體中的資料,以快照的方式寫入到二進位制檔案中,存放預設檔案是【dump.rbd】。
可以通過配置檔案來配置這個持久的方式,說白了就是持久化頻率,快取資料我多久做一個持久化,每次持久化多少資料。
主要就是通過遍歷所有快取資料,通過【save】,全部持久化到一個【.rdb】格式結尾的檔案中。
- 話不多說,看看操作規則就秒懂了:
Save 900 1 //900秒後有1個key執行save Save 300 10 //300秒後有10個key執行save Save60 10000 //60秒後有10000個key執行save
- RDB持久化流程是什麼呢?
1》redis根據配置去嘗試生成一個【.rdb】快照 2》redis-server會fork一個子程序 3》子程序將資料dump到一個臨時【.rdb】檔案中 4》然後通過臨時檔案來覆蓋替換之前的持久化檔案,並且每一次生一個新的臨時檔案都會做替換
- 那麼RBD有什麼弊端呢:
如果redis服務一不小心宕掉的話,那麼最後一次save持久化之後的資料,有可能全部丟失掉。
2》AOF(Append-onlyfile)
- 簡單來說,就是把所有的寫命令儲存起來
AOF就是將Redis每一次寫命令都追加到持久化檔案中
- 當然由於os會在核心中快取寫命令,所以可以不會快取那麼快,這樣導致aof也會造成資料丟失。所以我們也可以修改配置檔案來配置aof快取機制:
// 表示Redis寫操作後不回有【fsync()】操作呼叫,而是有作業系統自動排程重新整理磁碟,效能是最好的 Appendfsync no // 表示Redis每次寫操作後都會手動呼叫【fsync()】,將資料強制寫入操盤,效能是最慢的,但是持久化效果最好 Appendfsync always // 表示每秒同步一次,即每秒強制寫一次,在效能和持久化方面做了很好的這種 Appendfsync Everysec
- AOF中有一個【AOF Rewrite】,那什麼是【AOF Rewrite】呢?
一般Redis中資料是有限的,很多資料都會自動過期,或者被使用者刪除,又或者被Redis的清除演算法清理,從而淘汰。
Redis中資料會不斷淘汰舊的,只有一部分常用的資料會存放在記憶體中。
所以可能之前很多被清理的資料,都保留在AOF日誌中,因為AOF日誌只有一個,會不斷的膨脹變大,
所以AOF會每隔一段時間,進行一次【rewrite】操作。舉個例子:
比如AOF日誌中已經存放了100w的資料指令,但我們的Redis中,由於過期或被使用者刪除,
實際上只剩下了10w資料,此時基於這10w資料我們重新構建一個新的日誌並覆蓋之前的AOF日誌,
從而確保日誌檔案不會過大,並與記憶體中儘量一致。
- 我們可以在redis配置檔案中配置rewrite策略:
/** 比如說上一次AOF rewrite之後,是128mb,然後就會接著128mb繼續寫AOF的日誌, 如果發現增長的比例,超過了之前的100%,256mb,就可能會去觸發一次rewrite 但是此時還要去跟min-size,64mb去比較,256mb > 64mb,才會去觸發rewrite **/ auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
- AOF具體過程是什麼?
1》Redis-Server先fork一個子程序; 2》子程序基於當前的記憶體資料,構建日誌,開始往新的臨時AOF檔案中寫入日誌; 3》Redis主程序,接到客服端的寫操作時,繼續往舊的AOF日誌中追加資料,此時Redis中有兩個日誌檔案,一個是子程序建立的臨時日誌,一個是主程序的AOF日誌 4》子程序寫完建立完臨時AOF日誌後,將Redis主程序新追加的日誌寫入到臨時日誌中; 5》用臨時日誌覆蓋主程序的舊AOF日誌
- AOF的有什麼弊端呢?
如果一個業務的併發上萬,那麼AOF日誌系統可以說是非常龐大的,所以恢復重建功能就會很漫長
Redis中的AOF和RDB如何選擇呢:
1》不要僅僅使用RDB,那樣會導致丟失資料; 2》也不要僅僅使用AOF,如果AOF中出現指令bug或檔案損壞,那麼可能會造成資料恢復失敗; 3》綜合使用AOF和RDB兩種持久化機制,用AOF來保證資料不丟失,作為資料恢復的第一選擇; 因為RDB更具有健壯性,用RDB來做不同程度的冷備,在AOF檔案都丟失或損壞不可用的時候,還可以使用RDB來進行快速的資料恢復