聊聊Redis的持久化

redis:我的數據不僅可以放在內存中,照樣可以持久化到硬盤中。所以我也是一種數據庫。

我們都知道,redis就是靠快而出名,而它的快則是因爲數據全部在內存中操作。

但是如果數據僅僅只放在內存中的話,還是有問題的,比如服務宕機、機器重啓等都會造成內存數據丟失,因此,必須使用某種方法將redis數據持久化到硬盤中。

redis採用了兩種持久化方式:「RDB和AOF」

RDB

「RDB是一種快照技術,快照是一次全量備份」,它是將內存數據全部以二進制形式保存下來,且內容非常緊湊。

我們都知道,redis的快還有一個原因是它是單線程(至於redis單線程爲啥比多線程快,網上有很多解釋,這裏不再贅述),這個線程既負責所有客戶端套接字的併發讀寫,也負責數據在內存中的邏輯讀寫。如果再加入RDB持久化,這個線程肯定是喫不消的,因爲持久化是將數據寫入到硬盤中,這就牽扯到IO操作,IO操作的耗時和內存操作的耗時根本不是一個量級的。因此這個單線程肯定不能用來負責RDB持久化。

那要怎樣進行RDB持久化呢?再起一個線程來負責?那redis就不是單線程了。爲了解決這個問題,redis採用多進程來實現持久化。

「redis在持久化的時候會fork出一個子進程」,後續的持久化操作都會交給這個子進程來處理,而父進程則繼續處理客戶端的請求。這樣既保證了快速處理客戶端請求,又能進行數據持久化。

AOF

「AOF是一種指令日誌,裏面記錄着內存數據修改的所有指令」。每一次修改數據的指令都會增量的寫入到AOF日誌中,這就導致了此日誌隨着時間會變得特別龐大。

想象一下,如果AOF日誌中記錄了redis中所有的修改指令,那拿着這個指令在一個空的redis實例中順序執行,就會重現原redis,同樣起到持久化的作用。

但是,「AOF日誌文件很大」,如果執行整個AOF日誌,將會非常耗時,導致redis卡頓,這樣肯定是不行的。這時候我們就需要對AOF進行“瘦身”。

AOF日誌怎麼瘦身呢?redis同樣使用一個新的進程來處理,這個進程對內存數據進行遍歷,然後轉換成一系列redis的操作指令,序列化到一個新的AOF中,然後將AOF瘦身操作期間產生的增量AOF日誌再寫入到新AOF日誌中,最後將新AOF日誌替換原AOF日誌,這樣瘦身工作就完成了。

這種做法爲啥能起到瘦身的作用呢?比如redis曾經有這樣的操作:先增加了一條數據,然後又刪除了這條數據。在原AOF日誌中記錄着兩條指令,一條新增、一條刪除。而轉換成新的AOF日誌中,對內存數據遍歷時,沒有發現這條數據,因此對應的是一條指令都沒有。這樣就起到了瘦身的作用。

兩者優缺點

最終的選擇

當我們redis掛了重啓時,一般不會選擇RDB來加載持久化數據,因爲會有部分數據丟失。但是選擇AOF日誌的話,它會比RDB慢很多,啓動redis實例會花費很長時間。爲了解決這個問題,redis4.0提供了一個新的持久化選項--「混合持久化」,這種方式是將RDB持久化開始到結束這段時間內會丟失的數據交給AOF日誌來記錄,這樣大部分數據都交給RDB來恢復,而小部分數據交給AOF日誌,從而「保證了數據恢復速度,而且數據也基本不會丟失」,兩全其美。


掃一掃,關注我

徹底搞懂這煩人的編碼與亂碼!

2020-09-10

Java面試系列-線程相關(一)

2020-09-03

Java到底是引用傳遞還是值傳遞

2020-08-07

數據是怎麼一步一步到服務器的

2020-06-18

redis分佈式鎖

2020-06-05


本文分享自微信公衆號 - pipi蛋(pipidan_fuyun)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章