redis 持久化和主從複製

原文鏈接:https://blog.csdn.net/wanchaopeng

1.什麼是持久化

Redis作爲一個鍵值對內存數據庫(NoSQL),數據都存儲在內存當中,在處理客戶端請求時,所有操作都在內存當中進行,如下所示:

其實,只要稍微有點計算機基礎知識的人都知道,存儲在內存當中的數據,只要服務器關機(各種原因引起的),內存中的數據就會消失了,不僅服務器關機會造成數據消失,Redis服務器守護進程退出,內存中的數據也一樣會消失。

      對於只把Redis當緩存來用的項目來說,數據消失或許問題不大,重新從數據源把數據加載進來就可以了,但如果直接把用戶提交的業務數據存儲在Redis當中,把Redis作爲數據庫來使用,在其放存儲重要業務數據,那麼Redis的內存數據丟失所造成的影響也許是毀滅性。

      爲了避免內存中數據丟失,Redis提供了對持久化的支持,我們可以選擇不同的方式將數據從內存中保存到硬盤當中,使數據可以持久化保存。

Redis提供了RDB和AOF兩種不同的數據持久化方式,下面我們就來詳細介紹一下這種不同的持久化方式吧。

RDB

RDB是一種快照存儲持久化方式,具體就是將Redis某一時刻的內存數據保存到硬盤的文件當中,默認保存的文件名爲dump.rdb,而在Redis服務器啓動時,會重新加載dump.rdb文件的數據到內存當中恢復數據。

開啓RDB持久化方式

開啓RDB持久化方式很簡單,客戶端可以通過向Redis服務器發送save或bgsave命令讓服務器生成rdb文件,或者通過服務器配置文件指定觸發RDB條件。

1. save命令

save命令是一個同步操作。

#同步數據到磁盤上
> save

當客戶端向服務器發送save命令請求進行持久化時,服務器會阻塞save命令之後的其他客戶端的請求,直到數據同步完成。

如果數據量太大,同步數據會執行很久,而這期間Redis服務器也無法接收其他請求,所以,最好不要在生產環境使用save命令。

2. bgsave

與save命令不同,bgsave命令是一個異步操作。

# 異步保存數據集到磁盤上
> bgsave

當客戶端發服務發出bgsave命令時,Redis服務器主進程會forks一個子進程來數據同步問題,在將數據保存到rdb文件之後,子進程會退出。

所以,與save命令相比,Redis服務器在處理bgsave採用子線程進行IO寫入,而主進程仍然可以接收其他請求,但forks子進程是同步的,所以forks子進程時,一樣不能接收其他請求,這意味着,如果forks一個子進程花費的時間太久(一般是很快的),bgsave命令仍然有阻塞其他客戶的請求的情況發生。

3. 服務器配置自動觸發

除了通過客戶端發送命令外,還有一種方式,就是在Redis配置文件中的save指定到達觸發RDB持久化的條件,比如【多少秒內至少達到多少寫操作】就開啓RDB數據同步。

例如我們可以在配置文件redis.conf指定如下的選項:

# 900s內至少達到一條寫命令
save 900 1
# 300s內至少達至10條寫命令
save 300 10
# 60s內至少達到10000條寫命令
save 60 10000

之後在啓動服務器時加載配置文件。

# 啓動服務器加載配置文件
redis-server redis.conf

        這種通過服務器配置文件觸發RDB的方式,與bgsave命令類似,達到觸發條件時,會forks一個子進程進行數據同步,不過最好不要通過這方式來觸發RDB持久化,因爲設置觸發的時間太短,則容易頻繁寫入rdb文件,影響服務器性能,時間設置太長則會造成數據丟失。

rdb文件

前面介紹了三種讓服務器生成rdb文件的方式,無論是由主進程生成還是子進程來生成,其過程如下:

  1. 生成臨時rdb文件,並寫入數據。

  2. 完成數據寫入,用臨時文代替代正式rdb文件。

  3. 刪除原來的db文件。

RDB默認生成的文件名爲dump.rdb,當然,我可以通過配置文件進行更加詳細配置,比如在單機下啓動多個redis服務器進程時,可以通過端口號配置不同的rdb名稱,如下所示:

# 是否壓縮rdb文件
rdbcompression yes

# rdb文件的名稱
dbfilename redis-6379.rdb

# rdb文件保存目錄
dir ~/redis/

RDB的幾個優點

  1. 與AOF方式相比,通過rdb文件恢復數據比較快。

  2. rdb文件非常緊湊,適合於數據備份。

  3. 通過RDB進行數據備,由於使用子進程生成,所以對Redis服務器性能影響較小。

RDB的幾個缺點

  1. 如果服務器宕機的話,採用RDB的方式會造成某個時段內數據的丟失,比如我們設置10分鐘同步一次或5分鐘達到1000次寫入就同步一次,那麼如果還沒達到觸發條件服務器就死機了,那麼這個時間段的數據會丟失。

  2. 使用save命令會造成服務器阻塞,直接數據同步完成才能接收後續請求。

  3. 使用bgsave命令在forks子進程時,如果數據量太大,forks的過程也會發生阻塞,另外,forks子進程會耗費內存。

AOF

聊完了RDB,來聊聊Redis的另外一個持久化方式:AOF(Append-only file)。
與RDB存儲某個時刻的快照不同,AOF持久化方式會記錄客戶端對服務器的每一次寫操作命令,並將這些寫操作以Redis協議追加保存到以後綴爲aof文件末尾,在Redis服務器重啓時,會加載並運行aof文件的命令,以達到恢復數據的目的。

開啓AOF持久化方式

Redis默認不開啓AOF持久化方式,我們可以在配置文件中開啓並進行更加詳細的配置,如下面的redis.conf文件:

# 開啓aof機制
appendonly yes

# aof文件名
appendfilename "appendonly.aof"

# 寫入策略,always表示每個寫操作都保存到aof文件中,也可以是everysec或no
appendfsync always

# 默認不重寫aof文件
no-appendfsync-on-rewrite no

# 保存目錄
dir ~/redis/

三種寫入策略

在上面的配置文件中,我們可以通過appendfsync選項指定寫入策略,有三個選項。

appendfsync always
# appendfsync everysec
# appendfsync no

1. always

客戶端的每一個寫操作都保存到aof文件當,這種策略很安全,但是每個寫請注都有IO操作,所以也很慢。

2. everysec

appendfsync的默認寫入策略,每秒寫入一次aof文件,因此,最多可能會丟失1s的數據。

3. no

Redis服務器不負責寫入aof,而是交由操作系統來處理什麼時候寫入aof文件。更快,但也是最不安全的選擇,不推薦使用。

AOF文件重寫

AOF將客戶端的每一個寫操作都追加到aof文件末尾,比如對一個key多次執行incr命令,這時候,aof保存每一次命令到aof文件中,aof文件會變得非常大。

incr num 1
incr num 2
incr num 3
incr num 4
incr num 5
incr num 6
...
incr num 100000

aof文件太大,加載aof文件恢復數據時,就會非常慢,爲了解決這個問題,Redis支持aof文件重寫,通過重寫aof,可以生成一個恢復當前數據的最少命令集,比如上面的例子中那麼多條命令,可以重寫爲:

set num 100000

aof文件是一個二進制文件,並不是像上面的例子一樣,直接保存每個命令,而使用Redis自己的格式,上面只是方便演示。

兩種重寫方式

通過在redis.conf配置文件中的選項no-appendfsync-on-rewrite可以設置是否開啓重寫,這種方式會在每次fsync時都重寫,影響服務器性以,因此默認值爲no,不推薦使用。

# 默認不重寫aof文件
no-appendfsync-on-rewrite no

客戶端向服務器發送bgrewriteaof命令,也可以讓服務器進行AOF重寫。

# 讓服務器異步重寫追加aof文件命令
> bgrewriteaof

重寫aof文件的好處

  1. 壓縮aof文件,減少磁盤佔用量。

  2. 將aof的命令壓縮爲最小命令集,加快了數據恢復的速度。

AOF文件損壞

在寫入aof日誌文件時,如果Redis服務器宕機,則aof日誌文件文件會出格式錯誤,在重啓Redis服務器時,Redis服務器會拒絕載入這個aof文件,可以通過以下步驟修復aof並恢復數據。

  1. 備份現在aof文件,以防萬一。

  2. 使用redis-check-aof命令修復aof文件,該命令格式如下:

# 修復aof日誌文件
$ redis-check-aof -fix file.aof
  1. 重啓Redis服務器,加載已經修復的aof文件,恢復數據。

AOF的優點

AOF只是追加日誌文件,因此對服務器性能影響較小,速度比RDB要快,消耗的內存較少。

AOF的缺點

  1. AOF方式生成的日誌文件太大,即使通過AFO重寫,文件體積仍然很大。

  2. 恢復數據的速度比RDB慢。

選擇RDB還是AOF呢?

通過上面的介紹,我們瞭解了RDB與AOF各自的優點與缺點,到底要如何選擇呢?

通過下面的表示,我們可以從幾個方面對比一下RDB與AOF,在應用時,要根本自己的實際需求,選擇RDB或者AOF,其實,如果想要數據足夠安全,可以兩種方式都開啓,但兩種持久化方式同時進行IO操作,會嚴重影響服務器性能,因此有時候不得不做出選擇。

當RDB與AOF兩種方式都開啓時,Redis會優先使用AOF日誌來恢復數據,因爲AOF保存的文件比RDB文件更完整。

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