Redis系列之----Redis的兩種持久化機制(RDB和AOF)

Redis的兩種持久化機制(RDB和AOF)

什麼是持久化

   Redis的數據是存儲在內存中的,內存中的數據隨着服務器的重啓或者宕機便會不復存在,在生產環境,服務器宕機更是家常便飯,因此,咱們但願Redis可以將數據從內存中以某種形式保存到磁盤中,使得重啓的時候能夠加載磁盤中的文件記錄恢復數據,這一過程即是Redis的持久化。
   Redis支持兩種持久化機制,一種是RDB,另外一種是AOF。Redis默認狀況下使用RDB方式進行持久化。兩種持久化能夠單獨使用其中的一種,也能夠兩者結合使用,下面便來分別介紹下這兩種持久化機制。html

RDB方式

   RDB方式的持久化是經過快照(snapshotting)方式完成的,當符合必定條件的時候redis會自動將內存中的數據生成一份副本存儲在磁盤中,這個過程即爲「快照」。
Redis會根據如下幾種狀況對數據進行快照:redis

  • 根據配置規則自動進行快照
  • 用戶執行SAVE或者BGSAVE命令;
  • 執行FLUSHALL命令;
  • 執行復制時;

1)根據規則自定義快照條件

用戶能夠自定義快照條件,當符合快照條件,Redis便會執行快照操做,在redis.conf配置文件中,有這麼一段配置及說明:數據庫

It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

save 900 1
save 300 10
save 60 10000

# By default Redis will stop accepting writes if RDB snapshots are enabled
# (at least one save point) and the latest background save failed.
# This will make the user aware (in a hard way) that data is not persisting
# on disk properly, otherwise chances are that no one will notice and some
# disaster will happen.

在save命令後面加上兩個數字,save <指定時間間隔> <執行指定次數更新操做> 。例如:save 900 1 表示在900秒內有一個或者一個以上的鍵被更改時即執行快照操做。 promise

2)執行SAVE或者BGSAVE命令

一、save命令
   執行save命令時redis會同步執行快照操做,這將會阻塞全部來自客戶端的請求,服務器沒法響應其餘的處理,直到執行完成爲止。若是數據量小,用此命令可能感受不出有什麼區別,可是當數據量很大的時候,就須要謹慎使用這個命令。
二、bgasve命令
執行bgsave命令時,redis會fork出一個子進程去完成備份的操做,不會影響redis處理其餘的請求。緩存

3)執行FLUSHALL命令

   執行FLUSHALL命令時,Redis會清除數據庫中的全部數據,不論清空數據庫的過程是否觸發了自動快照條件,只要快照條件存在,就會執行快照操做,當沒有快照條件時,執行FLUSHALL不會進行快照。安全

4)執行復制時

當設置了主從模式時,Redis會在複製初始化時進行自動快照,即便沒有設置自動快照條件時,也會執行快照操做。服務器

存儲路徑:
   Redis默認將快照文件保存在Redis當前進程的工做目錄中的dump.rdb文件中,能夠經過配置dir和dbfilename兩個參數分別制定快照文案件的存儲路徑和文件名。如redis.conf文件中的配置和註釋:數據結構

# The filename where to dump the DB
dbfilename dump.rdb

# The working directory.
# DB將以dbfilename指定文件名被寫入這個目錄中,
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
# Note that you must specify a directory here, not a file name.
dir ./

執行快照的過程

  1. Redis使用fork函數複製一份當前進程(父進程)的副本(子進程);
  2. 父進程繼續接受來自客戶端的請求,子進程開始將內存中的數據寫入到硬盤中的臨時文件;
  3. 當子進程寫入完以後會用該臨時文件替換舊的rdb文件。

   redis在執行快照的過程當中不會修改RDB文件,在快照結束後纔會進行替換。所以RDB文件一般也用來實現Redis的數據備份,而且RDB文件是通過壓縮的二進制格式,因此佔用空間比內存中的數據小。app

   Redis啓動後會讀取RDB文件,將數據從磁盤加載到內存,一般將一個記錄了1000萬字符串類型鍵、大小爲1GB的快照文件載入內存須要20~30秒,載入的時間根據不一樣的服務器性能和Redis的數據結構而不一樣。ide

RDB 的優缺點
優勢:
1 適合大規模的數據恢復。
2 若是業務對數據完整性和一致性要求不高,RDB是很好的選擇。

缺點:
1 數據的完整性和一致性不高,由於RDB可能在最後一次備份時宕機了。
2 備份時佔用內存,由於Redis 在備份時會獨立建立一個子進程,將數據寫入到一個臨時文件(此時內存中的數據是原來的兩倍哦),最後再將臨時文件替換以前的備份文件。


AOF方式

   爲了下降由於進程終止致使的數據丟失的風險,Redis還提供了AOF的方式來進行持久化,AOF能夠將Redis執行的每一條命令追加到硬盤文件中,這一過程會下降redis的性能,但從數據的安全性來講,這個影響是能夠接受的。

AOF文件的保存地址和RDB文件位置相同,都是經過dir參數設置,默認文件名爲appendonly.aof。
以下所示:

appendonly no

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

appendfilename "appendonly.aof"

默認狀況下,Redis沒有開啓AOF的方式,可經過修改redis.conf配置文件中的appendonly參數爲yes進行啓動。

若是尚未生成aof文件的話,可使用命令設置:

./redis-cli config set appendonly yes

aof文件打開是這樣的:

*2
$6
SELECT
$1
0
*3
$3
SET
$3
age
$2
28
*3
$3
SET
$2
cc
$2
vv

   AOF文件以純文本的形式記錄了Redis的執行命令,AOF文件中的內容是Redis客戶端向Redis發送的原始通訊協議的內容,當對相同key進行屢次賦值操做時,aof也會將這些命令記錄下來,但其實咱們只但願它記錄最後一次的值,爲此Redis在redis.conf文件中提供了這樣的參數來自動重寫AOF文件:

# 當目前的AOF文件大小超過上一次重寫的AOF文件大小的百分之多少進行重寫
auto-aof-rewrite-percentage 100
# 容許重寫的AOF的最小AOF文件大小
auto-aof-rewrite-min-size 64mb

Redis在啓動的時候會逐條執行AOF文件中的命令來將硬盤中的文件寫入到內存中,所以載入的速度相對慢些。

# The fsync() call tells the Operating System to actually write data on disk
# instead of waiting for more data in the output buffer. Some OS will really flush
# data on disk, some other OS will just try to do it ASAP.
#
# Redis supports three different modes:
#
# no: don't fsync, just let the OS flush the data when it wants. Faster.
# always: fsync after every write to the append only log. Slow, Safest.
# everysec: fsync only one time every second. Compromise.
# The default is "everysec", as that's usually the right compromise between
# speed and data safety. It's up to you to understand if you can relax this to
# "no" that will let the operating system flush the output buffer when
# it wants, for better performances (but if you can live with the idea of
# some data loss consider the default persistence mode that's snapshotting),
# or on the contrary, use "always" that's very slow but a bit safer than
# everysec.
#
# More details please check the following article:
# http://antirez.com/post/redis-persistence-demystified.html
#
# If unsure, use "everysec".

# appendfsync always
appendfsync everysec
# appendfsync no

而且咱們須要注意的是下面這段描述:

The fsync() call tells the Operating System to actually write data on disk
# instead of waiting for more data in the output buffer. Some OS will really flush
# data on disk, some other OS will just try to do it ASAP.

   雖然每次更改數據庫內容的操做時,redis都會把更新記錄在AOF文件中,可是因爲操做系統的緩存機制,數據並無真正的寫入磁盤,而是進入了系統硬盤緩存。在默認狀況下會每30秒執行一次同步操做,若是在這30秒以內系統異常會致使硬盤緩存中的數據丟失,咱們使用AOF命令的方式就是爲了儘量的減小數據的丟失,因此redis提供了appendfsync參數來設置同步機制。默認狀況下使用everysec,即每秒執行一次同步操做,將數據從緩存更新到磁盤中。always表示每次執行寫入都會執行同步操做,這是最慢也是最安全的方式。no表示不主動執行,交由操做系統執行,這是最不安全的方式。通常狀況下兼顧系統性能,使用everysec的方式便可。

優勢:數據的完整性和一致性更高
缺點:由於AOF記錄的內容多,文件會愈來愈大,數據恢復也會愈來愈慢。

   RDB和AOF能夠同時存在,這樣既保證了數據安全又使得進行備份操做十分容易,Redis會使用AOF文件來恢復數據,由於AOF的方式持久化丟失的數據會更少。

參考書籍:《Redis入門指南》

相關文章
相關標籤/搜索