Redis持久化–Redis宕機或者出現意外刪庫導致數據丟失–解決方案

  • 2019 年 11 月 11 日
  • 筆記

echo編輯整理,歡迎轉載,轉載請聲明文章來源。歡迎添加echo微信(微訊號:t2421499075)交流學習。 百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這才是真正的堪稱強大!!!


Redis持久化的方案其實是很多人接觸的比較少的,因為相對應的數據故障不會很多,一次初始化的設置就能保證後續故障的全部順利解決。本文講述一下該機制的主要設置方法和持久化方案的對比,同時也會講述一些持久化的原理。如果對於Redis持久化比較熟悉的希望能夠給到你幫助,如果不熟悉的,你大可參考本文對你的Redis進行設置。

什麼是Redis的持久化?

可能很多人很少接觸這個詞,總覺的我們Redis的所有數據都是全部能夠永久存儲的。然而你可能不知道的是,Redis的數據都是在記憶體當中的,如果沒有持久化策略,你關閉Redis或者之後,你的數據有可能全部都丟失了。我們每再一次登錄Redis訪問上一次數據的時候,我們都看到了原來的數據,就是得益於Redis的持久化。Redis的持久化簡單說就是,將Redis存在記憶體中的值存儲到可以永久存儲的地方(磁碟等)

Redis的持久化方案

  • RDB Redis DataBase
  • AOF Append Only File

RDB [Redis DataBase]

RDB 是 Redis 默認的持久化方案。當滿足一定條件的時候,會把當前記憶體中的數據寫入磁碟,生成一個快照文件 dump.rdb。Redis 重啟會通過載入 dump.rdb 文件恢複數據。dump.rdb是我們redis文件當中的一個,位置如下圖:
在這裡插入圖片描述

RDB是怎麼實現持久化的

RDB是按照規則來觸發持久化存儲的,在我們的redis.conf中我們可以看到如下的幾個配置:

save 900 1 # 900 秒內至少有一個 key 被修改(包括添加)  save 300 10 # 300 秒內至少有 10 個 key 被修改  save 60 10000 # 60 秒內至少有 10000 個 key 被修改

在這裡插入圖片描述

這幾個配置是不衝突的,只要滿足任意一個都會觸發。

  • RDB方式的優點
    • RDB 是一個緊湊的單一文件,很方便傳送到另一個遠端數據中心,非常適用於災難恢復。
    • 與AOF相比,在恢復大的數據集的時候,RDB 方式會更快一些。
  • RDB方式的缺點
    • RDB 方式數據沒辦法做到實時持久化/秒級持久化。因為 bgsave 每次運行都要
      執行 fork 操作創建子進程,頻繁執行成本過高。
    • 在一定間隔時間做一次備份,所以如果 redis 意外 down 掉的話,就會丟失最後
      一次快照之後的所有修改(數據有丟失)。如果數據相對來說比較重要,希望將損失降到最小,則可以使用 AOF 方式進行持久化。

RDB持久化的演示

如果我們都按照正常程式走的話,我們是很難看到沒有持久化,或者出現持久化問題的故障現場的。所以我們要學會持久化操作,或者只管看到持久化就需要手動觸發持久化問題。這裡主要演示兩種情況,一種是數據正常備份,一種是數據丟失,我們恢復備份數據。

注意

這兩個操作都算是危險操作,我們需要在操作之前進行一下設置一下Redis快照,Redis
提供了兩條命令:

  • save: 在生成快照的時候會阻塞當前 Redis 伺服器, Redis 不能處理其他命令。如果
    記憶體中的數據比較多,會造成Redis長時間的阻塞。生產環境不建議使用這個命令。為了解決這個問題,Redis 提供了第二種方式。
  • bgsave:執行 bgsave 時,Redis 會在後台非同步進行快照操作,快照同時還可以響應客戶端請
    求。具體操作是 Redis 進程執行fork操作創建子進程(copy-on-write),RDB持久化過程由子進程負責,完成後自動結束。它不會記錄fork之後後續的命令。阻塞只發生在fork階段,一般時間很短。用 lastsave 命令可以查看最近一次成功生成快照的時間。

使用shutdown 持久化

我們先在Redis庫中設置如下幾個值

set k1 1  set k2 2  set k3 3  set k4 4  set k5 5    # 操作完成上面的步驟之後我們停止伺服器,觸發RDB的自動保存save  shutdown    # 然後再次啟動Redis服務  redis-server redis.conf    # 啟動完成,查看我們那些剛剛保存的數據是否被持久化了  keys *

執行完上面的步驟之後,我們可以看到我們的數據都在,就說明我們的觸發備份是成功的。

使用flushall模擬數據丟失

該操作有一定的風險性,如果是演示練習按照操作來基本不會出現問題,但是生產上慎重操作。我們做該操作之前,一定要注意先備份RDB對應的持久化問題dump.rdb

# 先備份dump.rdb  cp dump.rdb dump.rdb.bak    # 備份完成之後我們確定備份成功在進行下一步操作---清空庫  flushall    # 清空之後我們停止伺服器  shutdown    # 再次啟動伺服器,查看之前存儲的kye  keys *  

再次啟動查看的時候,我們發現我們的數據丟失了
在這裡插入圖片描述

恢復丟失的數據

# 停伺服器  shutdown    # 刪除我們現有dump.rdb  rm -rf ./dump.rdb    # 刪除成功之後,將我們的備份的dump.rdb.bak重新命名成為dump.rdb  mv dump.rdb.bak dump.rdb    # 確定之後我們再次啟動redis服務  redis-server redis.conf    # 檢查我們之前丟失的數據是否存在  keys * 

完成之後我們查看的數據就出現啦!

在這裡插入圖片描述

AOF [Append Only File]

AOF:Redis 默認不開啟。AOF採用日誌的形式來記錄每個寫操作,並追加到文件中。開啟後,執行更改 Redis 數據的命令時,就會把命令寫入到AOF文件中。Redis重啟時會根據日誌文件的內容把寫指令從前到後執行一次以完成數據的恢復工作。

該方式默認關閉,需要使用我們需要修改如下配置

# 開關 Redis 默認只開啟 RDB 持久化,開啟 AOF 需要修改為 yes  appendonly no  # 文件名 路徑也是通過 dir 參數配置 config get dir  appendfilename "appendonly.aof"

數據都是實時持久化到磁碟嗎?

由於作業系統的快取機制,AOF數據並沒有真正地寫入硬碟,而是進入了系統的硬碟快取。什麼時候把緩衝區的內容寫入到 AOF 文件?

AOF的保存規則有三種

在這裡插入圖片描述
AOF 持久化策略(硬碟快取到磁碟),默認 everysec

  • no 表示不執行 fsync,由作業系統保證數據同步到磁碟,速度最快,但是不太安全;
  • always 表示每次寫入都執行 fsync,以保證數據同步到磁碟,效率很低;
  • everysec 表示每秒執行一次 fsync,可能會導致丟失這 1s 數據。通常選擇 everysec ,
    兼顧安全性和效率。

文件越來越大,怎麼辦?

由於 AOF 持久化是 Redis 不斷將寫命令記錄到 AOF 文件中,隨著 Redis 不斷的進行,AOF 的文件會越來越大,文件越大,佔用伺服器記憶體越大以及 AOF恢復要求時間越長。
可以使用命令 bgrewriteaof來重寫。AOF文件重寫並不是對原文件進行重新整理,而是直接讀取伺服器現有的鍵值對,然後用一條命令去代替之前記錄這個鍵值對的多條命令,生成一個新的文件後去替換原來的 AOF 文件。

AOF指定大小開始重寫

在這裡插入圖片描述

  • auto-aof-rewrite-percentage:默認值為100。aof自動重寫配置,當目前aof文件大小超過上一次重寫的aof文件大小的百分之多少進行重寫,即當aof文件增長到一定大小的時候,Redis能夠調用bgrewriteaof對日誌文件進行重寫。當前AOF文件大小是上次日誌重寫得到AOF文件大小的二倍(設置為100)時,自動啟動新的日誌重寫過程。
  • auto-aof-rewrite-min-size:默認64M。設置允許重寫的最小aof文件大小,避免了達到約定百分比但尺寸仍然很小的情況還要重寫。

  • AOF方式的優點
    • AOF 持久化的方法提供了多種的同步頻率,即使使用默認的同步頻率每秒同步一次,Redis最多也就丟失 1 秒的數據而已。
  • AOF方式的缺點
    • 對於具有相同數據的的Redis,AOF文件通常會比RDF文件體積更大(RDB存的是數據快照)。
    • 雖然 AOF 提供了多種同步的頻率,默認情況下,每秒同步一次的頻率也具有較高的性能。在高並發的情況下,RDB 比 AOF 具好更好的性能保證。

兩種方案比較

那麼對於AOF和RDB兩種持久化方式,我們應該如何選擇呢?
如果可以忍受一小段時間內數據的丟失,毫無疑問使用 RDB 是最好的,定時生成RDB 快照(snapshot)非常便於進行資料庫備份, 並且 RDB 恢複數據集的速度也要比 AOF 恢復的速度要快。否則就使用AOF重寫。但是一般情況下建議不要單獨使用某一種持久化機制,而是應該兩種一起用,在這種情況下,當 redis 重啟的時候會優先載入 AOF文件來恢復原始
的數據,因為在通常情況下 AOF 文件保存的數據集要比 RDB 文件保存的數據集要完整。

做一個有底線的部落格主