1. 程式人生 > >Redis 持久化RDB和AOF原理

Redis 持久化RDB和AOF原理

Redis持久化是如何工作的?

持久化就是把資料放到斷電後資料不會丟失的裝置中,也就是我們通常理解的磁碟上。資料庫在進行寫操作時,有以下五個過程:

  • 1) 客戶端往伺服器傳送寫操作(資料在客戶端的記憶體中)
  • 2) 資料庫服務端接受到寫請求的資料(資料在服務端的記憶體中)
  • 3) 服務端呼叫write這個系統呼叫,把資料往磁碟寫(資料在系統記憶體的快取區中)
  • 4) 作業系統把緩衝區中的資料轉移到磁碟控制器上(資料在磁碟快取中)
  • 5) 磁碟控制器把資料寫到磁碟的物理介質中(資料真正儲存到磁碟中)

故障分析

結合上面的5個流程檢視各種級別的故障:

  • 當資料庫系統故障時,這時候系統核心還是完好的。那麼此時只要我們執行完了第3步,那麼資料就是安全的,因為後續作業系統會來完成後面幾步,保證資料最終會落到磁碟上。
  • 當系統斷電時,這時候上面5項中提到的所有快取都會失效,並且資料庫和作業系統都會停止工作。所以只有當資料在完成第5步後,才能保證在斷電後資料不丟失。

因此需要考慮的問題是:

  • 資料庫多長時間呼叫一次write,把資料寫到核心緩衝區?
    • 通常資料庫層面會進行全面控制
  • 核心多長時間會把系統緩衝區上的資料寫到磁碟控制器?
    • 作業系統有預設的策略,也可以通過POSIX API提供的fsync系統命令強制作業系統把資料從核心寫到磁碟控制器
  • 磁碟控制器又在什麼時候把快取中的資料寫到磁碟介質?
    • 建議的做法是僅僅當磁碟裝置有備用電池時才開啟寫快取

資料損壞

資料損壞就是資料無法回覆,寫道磁碟上並不意味著資料不會損壞,比如我們可能一次寫請求會進行兩次不同的寫操作,當意外發生時,可能會導致一次寫操作完成,但是另外一次還沒有執行。如果資料庫的資料檔案結構組織不合理,就會導致資料不能完全恢復。

有三種策略來組織資料來防止資料損壞到無法恢復的情況

  • 不通過資料的組織形式保證資料的可恢復性,而是通過配置資料同步備份的方式,在資料檔案損壞後通過資料備份來進行恢復。實際上MongoDB在不開啟操作日誌,通過配置Replica Sets時就是這種情況。
  • 在上面的基礎上新增一個操作日誌,每次操作時記一下操作的行為,這樣可以通過操作日誌來進行資料恢復。因為操作日誌是順序追加的方式寫的,所以不會出現操作日誌也無法恢復的情況
  • 資料庫不進行舊資料的修改,只用追加的方式完成寫操作,這樣資料本身就是一份日誌,這樣就永遠不會出現資料無法恢復的情況了。實際上CouchDB就是此做法的優秀範例。

RDB快照

Redis支援把當前資料的快照存成一個數據檔案的持久化機制。而一個持續寫入的資料庫如何生成快照呢。Redis藉助了fork命令的copy on write機制。在生成快照時,將當前程序fork出一個子程序,然後在子程序中迴圈所有的資料,將資料寫成為RDB檔案。

我們可以通過Redis的save指令來配置RDB快照生成的時機,比如你可以配置當10分鐘以內有100次寫入就生成快照,也可以配置當1小時內有1000次寫入就生成快照,也可以多個規則一起實施。這些規則的定義就在Redis的配置檔案中

這裡寫圖片描述

下面可以看到備份檔案的檔名和存放目錄

這裡寫圖片描述

這裡寫圖片描述

也可以通過Redis的CONFIG SET命令在Redis執行時設定規則,不需要重啟Redis

Redis的RDB檔案不會壞掉,因為其寫操作是在一個新程序中進行的,當生成一個新的RDB檔案時,Redis生成的子程序會先將資料寫到一個臨時檔案中,然後通過原子性rename系統呼叫將臨時檔案重新命名為RDB檔案,這樣在任何時候出現故障,Redis的RDB檔案都總是可用的。

同時,Redis的RDB檔案也是Redis主從同步內部實現中的一環。

但是,我們可以很明顯的看到,RDB有它的不足,就是一旦資料庫出現問題,那麼我們的RDB檔案中儲存的資料並不是全新的,從上次RDB檔案生成到 Redis停機這段時間的資料全部丟掉了。在某些業務下,這是可以忍受的,而且開啟RDB的代價並不高。 但是對於另外一些對資料安全性要求極高的應用,無法容忍資料丟失的應用,RDB就無能為力了,所以Redis引入了另一個重要的持久化機制:AOF日誌

AOF日誌

AOF日誌的全稱是Append Only File,從名字上我們就能看出來,它是一個追加寫入的日誌檔案。與一般資料庫不同的是,AOF檔案是可識別的純文字,它的內容就是一個個的Redis標準命令。比如我們進行如下實驗,在啟動命令引數中設定開啟AOF功能:

這裡演示的是使用命令列引數開啟AOF日誌的方式,後面會記錄如何使用配置檔案開啟AOF日誌

[root@VM_75_51_centos redis]# ./bin/redis-server ./redis.conf --appendonly yes
13336:C 28 Sep 15:00:30.750 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
13336:C 28 Sep 15:00:30.750 # Redis version=4.0.2, bits=64, commit=00000000, modified=0, pid=13336, just started
13336:C 28 Sep 15:00:30.750 # Configuration loaded
[root@VM_75_51_centos redis]# ls              
appendonly.aof  bin  dump.rdb  redis.conf

我們在資料庫新增一些key再全部刪除

[[email protected]_75_51_centos redis]# ./bin/redis-cli 
127.0.0.1:6379> set key1 hello
OK
127.0.0.1:6379> set key2 world
OK
127.0.0.1:6379> set key3 redis
OK
127.0.0.1:6379> keys *
1) "key1"
2) "key3"
3) "key2"
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)

此時關閉redis伺服器,開啟AOF日誌檔案appendonly.aof

127.0.0.1:6379> shutdown
not connected> exit
[root@VM_75_51_centos redis]# ls 
appendonly.aof  bin  dump.rdb  redis.conf
[root@VM_75_51_centos redis]# vi appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$4
key1
$5
hello
*3
$3
set
$4
key2
$5
world
*3
$3
set
$4
key3
$5
redis
*1
$8
flushall  

可以看到日誌是明文儲存的,我們把最後一行flushall刪除再重新啟動伺服器

[root@VM_75_51_centos redis]# ./bin/redis-server ./redis.conf --appendonly yes
13686:C 28 Sep 15:04:54.120 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
13686:C 28 Sep 15:04:54.120 # Redis version=4.0.2, bits=64, commit=00000000, modified=0, pid=13686, just started
13686:C 28 Sep 15:04:54.120 # Configuration loaded
[root@VM_75_51_centos redis]# ./bin/redis-cli 
127.0.0.1:6379> keys *
1) "key2"
2) "key1"
3) "key3"
127.0.0.1:6379> 

可以看到資料恢復了

此外注意AOF日誌也不是完全按客戶端的請求來生成日誌的,比如命令 INCRBYFLOAT 在記AOF日誌時就被記成一條SET記錄,因為浮點數操作可能在不同的系統上會不同,所以為了避免同一份日誌在不同的系統上生成不同的資料集,所以這裡只將操作後的結果通過SET來記錄。

前面是使用命令列引數開啟AOF日誌,也可以在redis.conf中配置

找到appendonly no改成appendonly yes

這裡寫圖片描述

再選擇合適的持久化策略

這裡寫圖片描述

  • appendfsync always 每次修改都會進行持久化
  • appendfsync everysec 每秒進行持久化
  • appendfsync no 不主動進行持久化 依賴作業系統

這裡選擇第一個 修改完畢再啟動伺服器就可以了

AOF重寫

每一條寫命令都生成一條日誌,那麼AOF檔案是不是會很大?答案是肯定的,AOF檔案會越來越大,所以Redis又提供了一個功能,叫做AOF rewrite。其功能就是重新生成一份AOF檔案,新的AOF檔案中一條記錄的操作只會有一次,而不像一份老檔案那樣,可能記錄了對同一個值的多次操作。其生成過程和RDB類似,也是fork一個程序,直接遍歷資料,寫入新的AOF臨時檔案。在寫入新檔案的過程中,所有的寫操作日誌還是會寫到原來老的 AOF檔案中,同時還會記錄在記憶體緩衝區中。當重完操作完成後,會將所有緩衝區中的日誌一次性寫入到臨時檔案中。然後呼叫原子性的rename命令用新的 AOF檔案取代老的AOF檔案。

持久化效能是否可靠

從上面的流程中可以看出,RDB是順序IO,效能很高。而同時在通過RDB檔案進行資料恢復的時候也是順序的讀取資料載入到記憶體中,所以不會造成磁碟的隨機讀取錯誤

而AOF是一個寫檔案操作,其目的是將操作日誌寫到磁碟上,所以它也同樣會遇到上面說的寫操作的5個流程。那麼寫AOF的操作安全性又有多高呢?實際上這是可以設定的,在Redis中對AOF呼叫write寫入後,何時再呼叫fsync將其寫到磁碟上,通過appendfsync選項來控制,下面appendfsync的三個設定項,安全強度逐漸變強。

1、appendfsync no

當設定appendfsync為no的時候,Redis不會主動呼叫fsync去將AOF日誌內容同步到磁碟,所以這一切就完全依賴於作業系統的除錯了。對大多數Linux作業系統,是每30秒進行一次fsync,將緩衝區中的資料寫到磁碟上。

2、appendfsync everysec

當設定appendfsync為everysec的時候,Redis會預設每隔一秒進行一次fsync呼叫,將緩衝區中的資料寫到磁碟。但是當這一 次的fsync呼叫時長超過1秒時。Redis會採取延遲fsync的策略,再等一秒鐘。也就是在兩秒後再進行fsync,這一次的fsync就不管會執行多長時間都會進行。這時候由於在fsync時檔案描述符會被阻塞,所以當前的寫操作就會阻塞。

所以,結論就是:在絕大多數情況下,Redis會每隔一秒進行一次fsync。在最壞的情況下,兩秒鐘會進行一次fsync操作。

這一操作在大多數資料庫系統中被稱為group commit,就是組合多次寫操作的資料,一次性將日誌寫到磁碟。

3、appednfsync always

當設定appendfsync為always時,每一次寫操作都會呼叫一次fsync,這時資料是最安全的,當然,由於每次都會執行fsync,所以其效能也會受到影響。

對於pipelining有什麼不同?

對於pipelining的操作,其具體過程是客戶端一次性發送N個命令,然後等待這N個命令的返回結果被一起返回。通過採用pipilining 就意味著放棄了對每一個命令的返回值確認。由於在這種情況下,N個命令是在同一個執行過程中執行的。所以當設定appendfsync為everysec 時,可能會有一些偏差,因為這N個命令可能執行時間超過1秒甚至2秒。但是可以保證的是,最長時間不會超過這N個命令的執行時間和。

和其他資料庫的比較

1.在資料匯入方面的比較

持久化的資料用於重啟後的資料恢復。Redis是一個記憶體資料庫,無論是RDB還是AOF,都只是其保證資料恢復的措施。所以 Redis在利用RDB和AOF進行恢復的時候,都會讀取RDB或AOF檔案,重新載入到記憶體中。相對於MySQL等資料庫的啟動時間來說,會長很多,因為MySQL本來是不需要將資料載入到記憶體中的。

但是相對來說,MySQL啟動後提供服務時,其被訪問的熱資料也會慢慢載入到記憶體中,通常我們稱之為預熱,而在預熱完成前,其效能都不會太高。而Redis的好處是一次性將資料載入到記憶體中,一次性預熱。這樣只要Redis啟動完成,那麼其提供服務的速度都是非常快的。

而在利用RDB和利用AOF啟動上,其啟動時間有一些差別。RDB的啟動時間會更短,原因有兩個

  • 一是RDB檔案中每一條資料只有一條記錄,不會像 AOF日誌那樣可能有一條資料的多次操作記錄。所以每條資料只需要寫一次就行了。
  • 另一個原因是RDB檔案的儲存格式和Redis資料在記憶體中的編碼格式是一致的,不需要再進行資料編碼工作。在CPU消耗上要遠小於AOF日誌的載入。

參考文章

相關推薦

Redis 持久化RDBAOF原理

Redis持久化是如何工作的? 持久化就是把資料放到斷電後資料不會丟失的裝置中,也就是我們通常理解的磁碟上。資料庫在進行寫操作時,有以下五個過程: 1) 客戶端往伺服器傳送寫操作(資料在客戶端的記憶體中) 2) 資料庫服務端接受到寫請求的資料(資料在服務端

Redis持久化RDBAOF原理及區別

一、RDB快照模式RDB方式原理:當redis需要做持久化時(執行SAVA或者BGSAVA命令,或者是達到配置條件時執行),redis會fork一個子程序,子程序將資料寫到磁碟上一個臨時RDB檔案中,當子程序完成寫臨時檔案後,將原來的RDB替換掉(預設檔名為dump.rdb)RDB備份條件和命令:1、執行SA

Redis持久化RDBAOF

Redis RDB AOF 1、Redis簡介Redis是一種高級key-value數據庫。它跟memcached類似,不過數據可以持久化,而且支持的數據類型很豐富。有字符串,鏈表,集 合和有序集合。支持在服務器端計算集合的並,交和補集(difference)等,還支持多種排序功能。所以Redis

Redis持久化----RDBAOF 的區別

        關於Redis說點什麼,目前都是使用Redis作為資料快取,快取的目標主要是那些需要經常訪問的資料,或計算複雜而耗時的資料。快取的效果就是減少了資料庫讀的次數,減少了複雜資料的計算次

圖解分析redisRDBAOF這兩種持久化機制的工作原理

▌大綱 RDB和AOF兩種持久化機制的介紹 RDB持久化機制的優點 RDB持久化機制的缺點 AOF持久化機制的優點 AOF持久化機制的缺點 RDB和AOF到底該如何選擇   ▌RDB和AOF兩種持久化機制的介紹 1、

20-02、圖解分析redisRDBAOF兩種持久化機制的工作原理

分析redis的RDB和AOF兩種持久化機制的工作原理 我們已經知道對於一個企業級的redis架構來說,持久化是不可減少的。 企業級redis叢集架構:海量資料、高併發、高可用。 持久化主要是做災難恢復,資料恢復,也可以歸類到高可用的一個環節裡面去。 比如你redis整個掛了,然後red

RedisRDBAOF持久化

一、RDB機制的優勢和略施 RDB持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟。 也是預設的持久化方式,這種方式是就是將記憶體中資料以快照的方式寫入到二進位制檔案中,預設的檔名為dump.rdb。   可以通過配置設定自動做快照持久化的方式。我們可以配置redis

Redis學習筆記——持久化RDBAOF

RDB(Redis DataBase) 在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,也就是行話講的Snapshot快照,它恢復時是將快照檔案直接讀入到記憶體裡。 Redis會單獨建立(fork)一個子程序來進行持久化,會先將資料寫入到一個臨時檔案中,待持久

redisrdb aof 持久化的區別,效能對比

1). 該機制可以帶來更高的資料安全性,即資料永續性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事實上,每秒同步也是非同步完成的,其 效率也是非常高的,所差的是一旦系統出現宕機現象,那麼這一秒鐘之內修改的資料將會丟失。而每修改同步,我們可以將其視為同步持久化,即每次發生的資料變 化都會被

深入RedisRDBAOF兩種持久化方式以及AOF重寫機制的分析

快取伺服器有一個很重要的指標就是能否持久化,如果快取伺服器不支援持久化的話,一些相對重要的資料都不能存在快取伺服器中了,畢竟誰也不能保證服務百分百可用,一旦快取伺服器宕機,所有資料就都丟失了。 今天來分享一下Redis的持久化兩種持久化方式RDB和AOF。

對比 RedisRDB AOF 持久化

![](http://cdn.chaohang.top/20200915140846.jpg) ## 概念 Redis 是記憶體資料庫,資料儲存在記憶體中,一旦伺服器程序退出,資料就丟失了,所以 Redis 需要想辦法將儲存在記憶體中的資料持久化到磁碟。 Redis 提供了兩種持久化功能: 1.

RedisRDBAOF

copy redis tar too 重寫 過程 rand pen 127.0.0.1 1.數據快照RDB1.1原理(1)RDB是將某一時刻的數據持久化到磁盤中,是一種快照的方式。(2)redis在進行數據持久化的過程中,會先將數據寫入到一個臨時文件中,待持久化過程都結束了

Redis持久化-RDBAOF

RDB:Redis Data Base 是什麼 在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,它恢復時是將快照檔案直接讀到記憶體裡 Redis會單獨建立(fork)一個子程序來進行持久化,會先將資料寫入到一個臨時檔案中,待持久化過程都結束了,再用這個臨時檔案替換上次

redis持久化 RDB & AOF

Redis   提供了兩種不同形式的持久化方式 RDB     (Redis   Data Base) AOF     (Append   of   File)    

redis 持久化 RDBAOF

- redis持久化    - redis是一種記憶體型資料庫,一旦伺服器程序退出,資料庫資料就會丟失,為了解決這個問題,redis提供了兩種持久化的方案,將記憶體中的資料儲存到磁碟中,避免資料的丟失。  - RDB持久化    - 這個功能可以將redis在記憶體中的狀

redis持久化EDBAOF

什麼是redis的持久化?   redis是一種記憶體型的資料庫,一旦伺服器的程序退出或者掛掉,資料庫中的資料就會消失,為了解決這種問題,redis提供了兩種持久化的方案,將記憶體中的資料存到磁碟中,避免資料丟失。 RDB持久化 redis提供了RDB持久化的功能,這個功能可以將redis在記憶體中的的

redis持久化RDBAOF

緩存 point 服務端 oot 分享圖片 配置參數 文件存儲 web 文件 Redis是一種內存型數據庫,一旦服務器進程退出,數據庫的數據就會丟失,為了解決這個問題,Redis提供了兩種持久化的方案,將內存中的數據保存到磁盤中,避免數據的丟失。 RDB持

Redis持久化方案RDBAOF(理論)

redis持久化 RDB AOF redis和memcache的區別是什麽? 簡單來說,如果沒有持久化的redis,就和memcache一樣了,相當於一個緩存數據庫。redis是如何解決數據持久化的? redis有兩種持久化方案:RDB(Redis DataBases)和AOF(App

開啟運維之路之第 8 篇——Redis持久化rdb aof

Redis所有的資料都存在記憶體中,從記憶體當中同步到硬碟上,這個過程叫做持久化過程。 持久化操作,兩種方式:rdb方式、aof方式,可以單獨使用或者結合使用。 rdb持久化方法:在指定的時間間隔寫入硬碟; aof方式:將以日誌,記錄每一個操作,伺服器啟動後就構建資料庫。 1、R

Redis持久化RDBAOF

Redis:持久化之RDB和AOF RDB(Redis DataBase)   在指定的時間間隔內將記憶體中的資料集快照寫入硬碟   也就是行話講的Snapshot快照,它恢復時是將快照檔案直接讀到記憶體裡。   Redis會單獨建立(fork)一個子程序來進行持久化,會先將資料寫入到一個臨時檔案中,