1. 程式人生 > 資料庫 >終於搞定出Redis的RDB和AOF了

終於搞定出Redis的RDB和AOF了

今天我們來講Redis的持久化。

一、為什麼Redis要持久化?

我們都知道,Redis執行時是將資料儲存在記憶體中的,如果伺服器宕機或者重啟,記憶體中的資料必然會丟失。所以,必須要把資料持久化到磁碟,以便伺服器故障時進行資料恢復。

二、Redis持久化的兩種方式

Redis持久化提供了兩種方式,RDB(RedisDB)和AOF(appendonly File)。

1. RDB

RDB即RedisDB的縮寫,即將整個Redis記憶體資料持久化到一個檔案。
有小夥伴可能會問,Redis在做持久化的同時,記憶體資料被修改了怎麼辦。

在這裡插入圖片描述

如上圖,Redis持久化操作前a的值是1,持久化過程當中a變為2。

請問在持久化結束時,持久化檔案中a的值記的是多少?

這裡,必須要提到一個知識點:linux的子程序建立函式:fork

[root@localhost ~]# man fork

fork() creates a new process by duplicating the calling process. The new process is referred to as the child process. The calling process is referred to as the parent process.
The child process and the parent process run in separate memory spaces

. At the time of fork() both memory spaces have the same content. Memory writes, file mappings (mmap(2)), and unmappings (munmap(2)) performed by one of the processes do not affect the other.

通過檢視linux手冊發現,fork函式會通過複製主程序的方式快速建立一個新的程序:子程序。在fork呼叫發生時,子程序和主程序有相同的資料內容,主子程序執行在各自的記憶體空間,互不影響。

Redis就是通過呼叫fork方式建立子程序進行資料的持久化,所以會保留了持久化開始時刻的資料狀況。

所以,上面那個問題,a的值還是1。

當子程序在進行資料持久化時,redis主程序會繼續對外提供服務,不受影響。

關於RDB,Redis提供了2種方式:命令和配置檔案。
可以通過 save (阻塞)和 bgsave 命令,觸發持久化寫檔案操作。

127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> 

另外一種方式就是配置檔案,Redis預設開啟。

 save 900 1  //900s有一個key被修改時儲存
 save 300 10  //300s內有10個key被修改時儲存
 save 60 10000 //60s內有10000個key被修改時儲存

執行持久化之後,會在指定的目錄下生成一個 dump.rdb 二進位制檔案。

[root@localhost ~]# cd /var/lib/redis/6379
[root@localhost 6379]# ll 
總用量 8
-rw-r--r--. 1 root root 176 12月 28 20:34 dump.rdb

RDB生成目錄以及檔名配置:

# The filename where to dump the DB
dbfilename dump.rdb
# Note that you must specify a directory here, not a file name.
dir /var/lib/redis/6379
[root@localhost 6379]# vi dump.rdb 
REDIS0009ú      redis-ver^E6.0.9ú
redis-bitsÀ@ú^EctimeÂÅÞé_ú^Hused-memÂØ<93>^L^@ú^Laof-preambleÀ^@þ^@û^B^@^@À^AÀ^A^@^AaÀ^Cÿ<9d>Uî;hÕà<9d>

所以,一句話總結,RDB就是在特定的條件下,將Redis的記憶體資料快照以二進位制的方式儲存到磁碟。

RBD的優點是,全量資料二進位制檔案,資料恢復快
缺點是,可能會丟資料

2. AOF

顧名思義,AOF會將redis中每一步對資料修改的操作記錄(日誌)append到相應的檔案中。

在redis中配置如下:

appendonly yes
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"

為了降低IO消耗,AOF寫檔案時,會先將資料寫到緩衝區,然後再把緩衝區的內容 flush 到磁碟,這個過程叫做 fsync。

AOF的flush頻率有三種:

appendfsync always //每次寫操作都flush,影響效能
appendfsync everysec //每秒flush
appendfsync no //消極等待OS重新整理(一般30s),可能丟失資料

相比於always的激進和no的消極,everysec在效能和資料完整性上取了一個折中。

bgrewirteaof

隨著伺服器執行時間越來越長,AOF檔案也勢必會越來越大,bgrewirteaof(AOF重寫)就是為了解決這個問題。

拆開來看 bgrewirteaof = bg(background)+rewrite+aof, 即 bgrewirteaof 會在後臺起子程序,對aof檔案進行rewrite操作。重寫時,aof檔案中的命令會被整理(命令相互抵消、整合等),重寫後的aof會變小。

來,我們實踐一下。

[root@localhost 6379]# redis-cli
127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> set a 2
OK
127.0.0.1:6379> set a 3
OK
[root@localhost 6379]# ll
總用量 8
-rw-r--r--. 1 root root 258 12月 28 21:19 appendonly.aof
[root@localhost 6379]# vi appendonly.aof 
SELECT
$1
0
*3
$3
set
$1
a
$1
1
*3
$3
set
$1
a
$1
2
*3
$3
set
$1
a
$1
3
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
[root@localhost 6379]# ll
總用量 8
-rw-r--r--. 1 root root  77 12月 28 21:25 appendonly.aof
[root@localhost 6379]# vi appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
SET
$1
a
$1
3
~

可以看到,在對變數a進行三次賦值操作後,appendonly.aof記錄下了每次執行的命令,檔案大小是 258 位元組。執行 bgrewirteof 之後,檔案大小變為77位元組,命令被合併成一條,即 set a 3。

但是,這裡又會有新的問題,bgrewirteof 對歷史命令的合併是非常耗費效能的,尤其是資料量非常大的情況下。

此時,便產生了持久化的混合模式。在redis 4.0之後,開始支援。即執行bgrewirteof之後,將當前資料全量以RDB的方式寫入appendonly檔案的前半部分,之後的命令再以 append 的方式進行追加。

REDIS0009ú      redis-ver^E6.0.9ú
redis-bitsÀ@ú^EctimeÂ<90>âé_ú^Hused-memÂø3^M^@ú^Laof-preambleÀ^Aþ^@û^B^@^@^AaÀ^C^@À^AÀ^AÿFlÜ»CÖ:¦*2^M
$6^M
SELECT^M
$1^M
0^M
*3^M
$3^M
set^M
$1^M
a^M
$1^M
1^M
~

混合模式開關設定:

aof-use-rdb-preamble yes

混合模式兼顧了RDB資料恢復快以及AOF資料完整性的優點。

bgrewirteof的觸發機制是怎樣的呢?

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

即Redis會在 appendonly.aof 到達64M(rewrite最小大小),128M(64M+64*100%),192M…時,自動執行bgrewriteof。

所以,一句話總結: AOF會詳細記錄Redis的每一步寫操作。由於AOF檔案的資料可靠性,Redis恢復資料時,會使用AOF(若有)。

Redis原話:

AOF and RDB persistence can be enabled at the same > time without problems.
If the AOF is enabled on startup Redis will load t> he AOF, that is the file
with the better durability guarantees.

三、總結

稍微總結一下,今天我們分享了redis的兩種持久化方式,RDB和AOF。

RDB的優點是:

  • 二進位制壓縮檔案,恢復速度快

RDB缺點是:

  • 可能丟失資料

AOF的優點是:

  • 不易丟失資料,資料完整性好

AOF的缺點是:

  • 每一步操作都記錄,相對影響效能
  • 資料恢復慢,檔案較大

具體使用場景上,資料重要性不高,且要求效能,可以使用Redis預設的RDB方式。如果資料完整性要求較高,則可以使用AOF和RDB結合的方式。

最後,簡單整理了個腦圖,方便記憶。

在這裡插入圖片描述

好了,今天分享就是這樣,如果覺得有用,歡迎三連(點贊、在看、轉發)。

在這裡插入圖片描述