前言
Redis是一個基于記憶體的資料庫,資料是保存在記憶體中的,我們都知道,從資料庫中讀取資料是需要經過磁盤IO的,這樣就導致它的速度遠不及記憶體中讀取來的快,雖然記憶體中讀取資料回應速度提升了,但是伴隨著的是資料容易發生丟失,Redis為我們提供了持久化的機制,分別是RDB(Redis DataBase)和AOF(Append Only File),來保證一定情況下的資料安全,
一、Redis的資料持久化流程
既然Redis的資料可以保存在磁盤上,那么這個流程是什么樣子的呢?
(1)客戶端向服務端發送寫操作(資料在客戶端的記憶體中),
(2)資料庫服務端接收到寫請求的資料(資料在服務端的記憶體中),
(3)服務端呼叫write這個系統呼叫,將資料往磁盤上寫(資料在系統記憶體的緩沖區中),
(4)作業系統將緩沖區中的資料轉移到磁盤控制器上(資料在磁盤快取中),
(5)磁盤控制器將資料寫到磁盤的物理介質中(資料真正落到磁盤上),
這5個程序是在理想條件下一個正常的保存流程,但是在大多數情況下,我們的機器等等都會有各種各樣的故障,這里劃分了兩種情況:
(1)Redis資料庫發生故障,只要在上面的第三步執行完畢,那么就可以持久化保存,剩下的兩步由作業系統替我們完成,
(2)作業系統發生故障,必須上面5步都完成才可以,
在這里只考慮了保存的程序可能發生的故障,其實保存的資料也有可能發生損壞,需要一定的恢復機制,那么Redis是如何實作上面五個保存磁盤的步驟呢?它提供了兩種策略機制,也就是RDB和AOF,
二、RDB機制
RDB其實就是把資料以快照的形式保存在磁盤上,那么什么是快照呢?通俗易懂的理解就是把當前時刻的資料拍成一張照片保存下來,
RDB持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁盤,也是默認的持久化方式,這種方式是就是將記憶體中資料以快照的方式寫入到二進制檔案中,默認的檔案名為dump.rdb,
在我們安裝了redis之后,所有的配置都是在redis.conf檔案中,里面保存了RDB和AOF兩種持久化機制的各種配置,
既然RDB機制是通過把某個時刻的所有資料生成一個快照來保存,那么就應該有一種觸發機制,是實作這個程序,對于RDB來說,提供了三種機制:save、bgsave、自動化,
1、save觸發方式
該命令會阻塞當前Redis服務器,執行save命令期間,Redis不能處理其他命令,直到RDB程序完成為止,具體流程如下:

執行完成時候如果存在老的RDB檔案,就把新的替代掉舊的,我們的客戶端可能都是幾萬或者是幾十萬,這種方式顯然不可取,
2、bgsave觸發方式
執行該命令時,Redis會在后臺異步進行快照操作,快照同時還可以回應客戶端請求,具體流程如下:

具體操作是Redis行程執行fork操作創建子行程,RDB持久化程序由子行程負責,完成后自動結束,阻塞只發生在fork階段,一般時間很短,基本上 Redis 內部所有的RDB操作都是采用 bgsave 命令,
3、自動觸發
自動觸發是由我們的組態檔來完成的,在redis.conf組態檔中,里面有如下配置,我們可以去設定:
①save:這里是用來配置觸發 Redis的 RDB 持久化條件,也就是什么時候將記憶體中的資料保存到硬碟,比如“save m n”,表示m秒內資料集存在n次修改時,自動觸發bgsave,
默認如下配置:
#表示900秒內如果至少有1個key的值變化,則保存
save9001
#表示300秒內如果至少有10個key的值變化,則保存
save30010
#表示60秒內如果至少有10000個key的值變化,則保存
save6010000
不需要持久化,那么你可以注釋掉所有的 save 行來停用保存功能,
②stop-writes-on-bgsave-error :默認值為yes,當啟用了RDB且最后一次后臺保存資料失敗,Redis是否停止接收資料,這會讓用戶意識到資料沒有正確持久化到磁盤上,否則沒有人會注意到問題發生了,如果Redis重啟了,那么又可以重新開始接收資料了
③rdbcompression ;默認值是yes,對于存盤到磁盤中的快照,可以設定是否進行壓縮存盤,
④rdbchecksum :默認值是yes,在存盤快照后,我們還可以讓redis使用CRC64演算法來進行資料校驗,但是這樣做會增加大約10%的性能消耗,如果希望獲取到最大的性能提升,可以關閉此功能,
⑤dbfilename :設定快照的檔案名,默認是 dump.rdb
⑥dir:設定快照檔案的存放路徑,這個配置項一定是個目錄,而不能是檔案名,
我們可以修改這些配置來實作我們想要的效果,因為第三種方式是配置的,所以我們對前兩種進行一個對比:

4、RDB 的優勢和劣勢
① 優勢
(1)RDB檔案緊湊,全量備份,非常適合用于進行備份和災難恢復,
(2)生成RDB檔案的時候,redis主行程會fork()一個子行程來處理所有保存作業,主行程不需要進行任何磁盤IO操作,
(3)RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快,
② 劣勢
RDB快照是一次全量備份,存盤的是記憶體資料的二進制序列化形式,存盤上非常緊湊,當進行快照持久化時,會開啟一個子行程專門負責快照持久化,子行程會擁有父行程的記憶體資料,父行程修改記憶體子行程不會反應出來,所以在快照持久化期間修改的資料不會被保存,可能丟失資料,
三、AOF機制
全量備份總是耗時的,有時候我們提供一種更加高效的方式AOF,作業機制很簡單,Redis會將每一個收到的寫命令都通過write函式追加到檔案中,通俗的理解就是日志記錄,
1、持久化原理

每當有一個寫命令過來時,就直接保存在我們的AOF檔案中,
2、檔案重寫原理
AOF的方式也同時帶來了另一個問題,持久化檔案會變的越來越大,為了壓縮AOF的持久化檔案,Redis提供了bgrewriteaof命令,將記憶體中的資料以命令的方式保存到臨時檔案中,同時會fork出一條新行程來將檔案重寫,

重寫AOF檔案的操作,并沒有讀取舊的AOF檔案,而是將整個記憶體中的資料庫內容用命令的方式重寫了一個新的AOF檔案,這點和快照有點類似,
3、AOF也有三種觸發機制
(1)每修改同步always:同步持久化 每次發生資料變更會被立即記錄到磁盤 性能較差但資料完整性比較好
(2)每秒同步everysec:異步操作,每秒記錄 如果一秒內宕機,有資料丟失
(3)不同no:從不同步

4、優點
(1)AOF可以更好的保護資料不丟失,一般AOF會每隔1秒,通過一個后臺執行緒執行一次fsync操作,最多丟失1秒鐘的資料,
(2)AOF日志檔案沒有任何磁盤尋址的開銷,寫入性能非常高,檔案不容易破損,
(3)AOF日志檔案即使過大的時候,出現后臺重寫操作,也不會影響客戶端的讀寫,
(4)AOF日志檔案的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤洗掉的緊急恢復,比如某人不小心用flushall命令清空了所有資料,只要這個時候后臺rewrite還沒有發生,那么就可以立即拷貝AOF檔案,將最后一條flushall命令給刪了,然后再將該AOF檔案放回去,就可以通過恢復機制,自動恢復所有資料
5、缺點
(1)對于同一份資料來說,AOF日志檔案通常比RDB資料快照檔案更大
(2)AOF開啟后,支持的寫QPS會比RDB支持的寫QPS低,因為AOF一般會配置成每秒fsync一次日志檔案,當然,每秒一次fsync,性能也還是很高的
(3)以前AOF發生過bug,就是通過AOF記錄的日志,進行資料恢復的時候,沒有恢復一模一樣的資料出來,
四、RDB和AOF的實際應用
兩者各自的原理已經介紹過了,接下來具體的使用就是根據自己的實際需求了,不同的需求選擇不同的持久化機制,通常都是結合使用,

以上內容是本人在日常生活中的總結,希望大家互相學習0.0
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/104210.html
標籤:其他
上一篇:nacos與zookeeper、consul、eureka之間的對比
下一篇:單片機仿真實體70套
