Redis基礎(六)—— 持久化

這是我參與8月更文挑戰的第9天,活動詳情查看:8月更文挑戰redis

Redis 是內存數據庫,若是不將內存中的數據庫狀態保存到磁盤中,那麼一旦服務器進程退出,服務器中的數據庫狀態也會消失,因此Redis提供了持久化功能。數據庫

持久化就是把內存中的數據寫到磁盤中去,防止服務器宕機了內存數據丟失;緩存

Redis 提供了兩種持久化方式:RDB(默認)和 AOF安全

RDB(默認)

RDB 是 Redis Database的縮寫服務器

把當前數據生成快照保存在硬盤上markdown

功能核心函數 rdbSave(生成RDB文件)和 rdbLoad(從文件加載到內存)兩個函數併發

image-20210729185754324

快照是默認的持久化方式,這種方式就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名爲 dump.rdbapp

RDB持久化能夠手動觸發,也能夠自動觸發函數

1. 手動觸發

savebgsave命令均可以手動觸發RDB持久化。高併發

save命令

執行save命令會手動觸發RDB持久化,可是save命令會阻塞Redis服務,直到RDB持久化完成。

當Redis服務儲存大量數據時,會形成較長時間的阻塞,不建議使用。

  1. 執行
 127.0.0.1:6379> save
複製代碼
  1. 日誌文件
 20947:M 29 Jul 2021 23:28:56.615 * DB loaded from disk: 0.000 seconds
 20947:M 29 Jul 2021 23:28:56.615 * Ready to accept connections
 20947:M 29 Jul 2021 23:29:11.551 * DB saved on disk
複製代碼

** ps:日誌文件查看

(1). 查看 redis.conf 文件中 logfile 屬性對應的文件位置;(我這裏原本沒有,本身寫上想要保存日誌的位置)

 logfile "/usr/local/redis/log/redis.log"
複製代碼

(2). 重啓 redis 服務端

bgsave

執行bgsave命令也會手動觸發RDB持久化,和save命令不一樣是:Redis服務通常不會阻塞。

Redis進程會執行fork操做建立子進程,RDB持久化由子進程負責,不會阻塞Redis服務進程。

Redis服務的阻塞只發生在fork階段,通常狀況時間很短。

  1. 執行

     127.0.0.1:6379> bgsave
     Background saving started
    複製代碼
  2. 日誌文件

     20947:M 29 Jul 2021 23:30:52.144 * Background saving started by pid 21044
     21044:C 29 Jul 2021 23:30:52.148 * DB saved on disk
     21044:C 29 Jul 2021 23:30:52.149 * RDB: 0 MB of memory used by copy-on-write
     20947:M 29 Jul 2021 23:30:52.193 * Background saving terminated with success
    複製代碼

bgsave執行流程

image-20210809081510265
  1. 執行bgsave命令,Redis進程先判斷當前是否存在正在執行的RDB或AOF子線程,若是存在就是直接結束。
  2. Redis進程執行fork操做建立子線程,在fork操做的過程當中Redis進程會被阻塞。
  3. Redis進程fork完成後,bgsave命令就結束了,自此Redis進程不會被阻塞,能夠響應其餘命令。
  4. 子進程根據Redis進程的內存生成快照文件,並替換原有的RDB文件。
  5. 子進程經過信號量通知Redis進程已完成。

2. 自動觸發

自動觸發的RDB持久化都是採用bgsave的方式,減小Redis進程的阻塞。

那麼,在什麼場景下會自動觸發呢?

觸發場景
  1. 在配置文件中設置了save的相關配置,如save m n,它表示在m秒內數據被修改過n次時,自動觸發bgsave操做;

     save 900 1      # 每 900 秒(15分鐘)至少 1 個key發生變化,產生快照
     save 300 10     # 每 300 秒(5分鐘)至少 10 個key發生變化,產生快照
     save 60 10000   # 每 60 秒(1分鐘)至少 10000 個key發生變化,產生快照
    複製代碼
  2. 當從節點作全量複製時,主節點會自動執行bgsave操做,而且把生成的RDB文件發送給從節點;

  3. 執行debug reload命令時,也會自動觸發bgsave操做;

  4. 執行shutdown命令時,若是沒有開啓AOF持久化也會自動觸發bgsave操做。

優勢:

  • 快照保存數據極快、還原數據極快;
  • 適用於災難備份

缺點:

  • 小內存及其不適合使用,RDB機制符合要求就會照快照;
  • 頻繁執行成本太高,因此沒法作到實時持久化,或者秒級持久化;
  • fork進程會消耗必定內存空間;
  • 另外,因爲Redis版本的不斷迭代,存在不一樣格式的RDB版本,有可能出現低版本的RDB格式沒法兼容高版本RDB文件的問題。

AOF

AOF(Append Only File)持久化是把每次寫命令追加寫入日誌中,當須要恢復數據時從新執行AOF文件中的命令就能夠了。

AOF解決了數據持久化的實時性,也是目前主流的Redis持久化方式。

流程圖

image-20210730145125360

  1. 命令追加(append):全部寫命令都會被追加到AOF緩存區(aof_buf)中。
  2. 文件同步(sync):根據不一樣策略將AOF緩存區同步到AOF文件中。
  3. 文件重寫(rewrite):按期對AOF文件進行重寫,以達到壓縮的目的。
  4. 數據加載(load):當須要恢復數據時,從新執行AOF文件中的命令。

配置

AOF持久化默認是不開啓的,須要修改 redis.conf 配置文件,如:

 # appendonly改成yes,開啓AOF
 appendonly yes
 # AOF文件的名字
 appendfilename "appendonly.aof"
 ​
 # AOF文件的寫入方式
 # everysec 每一個一秒將緩存區內容寫入文件 默認開啓的寫入方式
 # appendfsync always
 appendfsync everysec
 # appendfsync no
 ​
 # 運行AOF重寫時AOF文件大小的增加率的最小值
 auto-aof-rewrite-percentage 100
 # 運行AOF重寫時文件大小的最小值
 auto-aof-rewrite-min-size 64mb
複製代碼

文件同步(sync)策略

  1. always:每次寫入緩存區都要同步到AOF文件中,硬盤的操做比較慢,限制了Redis高併發,不建議配置。
  2. no:每次寫入緩存區後不進行同步,同步到AOF文件的操做由操做系統負責,每次同步AOF文件的週期不可控,並且增大了每次同步的硬盤的數據量。
  3. eversec (默認) :每次寫入緩存區後,由專門的線程每秒鐘同步一次,作到了兼顧性能和數據安全。是建議的同步策略,也是默認的策略。

觸發文件重寫

文件重寫:由於若是重寫寫入命令,aof文件會愈來愈大,經過讀取數據庫的鍵值,來完成重寫。

是爲了合併多餘命令,減少文件大小;

例如:對一個字符串進行四次操做,我只須要讀取最終的值,最後用一條命令來寫入;

fork 一個新的進程進行文件重寫。

  1. 手動觸發:使用 bgrewriteaof 命令

     127.0.0.1:6379> bgrewriteaof
     Background append only file rewriting started
    複製代碼

    日誌

     20947:M 30 Jul 2021 15:04:54.888 * Background append only file rewriting started by pid 6083
    複製代碼
  2. 自動觸發

    根據 auto-aof-rewrite-min-sizeauto-aof-rewrite-percentage配置肯定自動觸發的時機。

    auto-aof-rewrite-min-size表示運行AOF重寫時文件大小的最小值,默認爲64MB;

    auto-aof-rewrite-percentage表示當前AOF文件大小和上一次重寫後AOF文件大小的比值的最小值,默認爲100。

    只用前二者同時超過期纔會自動觸發 文件重寫。

優勢:

  • 數據實時同步,根據 AOF 默認文件同步策略,當服務器宕機時,最多會丟失一秒鐘的數據;

缺點:

  • 對於相同的數據集來講,AOF 文件的體積一般要大於 RDB 文件體積;
  • AOF運行效率低於 RDB
相關文章
相關標籤/搜索