Redis持久化--Redis宕機或者出現意外刪庫導致資料丟失--解決方案
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 檔案儲存的資料集要完整。做一個有底線的部落格主