1. 程式人生 > >【redis】-- redis的持久化(作為資料庫)

【redis】-- redis的持久化(作為資料庫)

目錄

  • 1.RDB
    • rdb持久化的方式
    • rdb方式的優點:
    • aof的優點
  • 3.持久化的其他特性
    • 日誌重寫
    • 工作原理
    • rdb和aof混合使用

redis是一個基於記憶體的資料庫,故在redis正在執行的資料都在記憶體中,而記憶體掉電,記憶體上所以資料都會消失。故把redis當成資料庫使用時就需要對redis進行持久化。

在說redis持久化的時候,我們先來聊聊其他的知識。linux的父子程序。在Linux中使用fork()函式會給當前正在執行的程序建立一個子程序。那麼現在問題就來了,fork時父子程序中的資料有什麼關係呢?一般說到程序我們都會知道程序間彼此是資料隔離的。然而實際上,子程序在剛建立時,可以看到子程序中的資料。而在修改該資料時,卻不會對父程序造成影響。同樣子程序也不會受到父程序修改資料的影響。而造成這種現象的,正是因為linux的copy on write機制。

copy on write:是一種核心機制,通俗來講就是寫時複製。及建立子程序並不發生複製,建立子程序後父子程序共用資料。只有在修改資料是才會建立新的空間。

這樣做的好處是建立程序變快了。而且根據開發經驗,我們建立子程序後不可能父子程序把所有資料都改一遍。而這套機制就是指標支撐的。玩的是指標

redis中有兩種資料到儲存方式,rdb和aof。下面我們來著重講一下這兩種持久化方式:

1.RDB

rdb持久化的方式

RDB持久化方式能夠在指定的時間間隔能對你的資料進行快照儲存.

redis的rdb持久化方式有儲存的是時點資料即某一個時間點的資料。因為如果儲存實時更新的資料的話,如果一直有資料寫入會導致,持久化過程一直進行,降低了redis的快捷的特性。因此redis有兩種持久化資料的方式

  • save:前臺更新資料,如果使用這種方法持久化,那麼只能在伺服器停機維護時,發生因為它會阻塞redis程序造成redis的服務不可用。
  • bgsave:後臺執行,該命令的原理是,建立一個子程序來進行redis的持久化,而redis依然提供服務。此時就用到了剛才講到的copy on write機制,父子程序共用了一套資料。

以上兩個命令直接可以在redis的客戶端執行。

注意如果使用配置檔案的方式配置資料持久化,配置檔案中給出bgsave的規則: save這個標識。配置的規則:(要修改的檔案是dbfilename dump.rdb,檔案一般儲存在var/lib/redis/6379)

save 900 1
save 300 10
save 60 10000

該規則意味著,在每60秒檢測一次redis的資料量,如果達到10000就進行持久化,否則不持久化。在每300秒檢測一次redis的資料量,如果達到10就進行持久化,否則不持久化。在每900秒檢測一次redis的資料量,如果達到1就進行持久化,否則不持久化。

rdb方式的優點:

  • RDB是一個非常緊湊的檔案,它儲存了某個時間點得資料集,非常適用於資料集的備份,比如你可以在每個小時報儲存一下過去24小時內的資料,同時每天儲存過去30天的資料,這樣即使出了問題你也可以根據需求恢復到不同版本的資料集.
  • RDB是一個緊湊的單一檔案,很方便傳送到另一個遠端資料中心或者亞馬遜的S3(可能加密),非常適用於災難恢復.
  • RDB在儲存RDB檔案時父程序唯一需要做的就是fork出一個子程序,接下來的工作全部由子程序來做,父程序不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的效能.
  • 與AOF相比,在恢復大的資料集的時候,RDB方式會更快一些.

    rdb的缺點

  • 如果你希望在redis意外停止工作(例如電源中斷)的情況下丟失的資料最少的話,那麼RDB不適合你.雖然你可以配置不同的save時間點(例如每隔5分鐘並且對資料集有100個寫的操作),是Redis要完整的儲存整個資料集是一個比較繁重的工作,你通常會每隔5分鐘或者更久做一次完整的儲存,萬一在Redis意外宕機,你可能會丟失幾分鐘的資料.
  • RDB 需要經常fork子程序來儲存資料集到硬碟上,當資料集比較大的時候,fork的過程是非常耗時的,可能會導致Redis在一些毫秒級內不能響應客戶端的請求.如果資料集巨大並且CPU效能不是很好的情況下,這種情況會持續1秒,AOF也需要fork,但是你可以調節重寫日誌檔案的頻率來提高資料集的耐久度.
  • 不支援拉鍊化,只有一個rdb檔案
  • 丟失資料相對多一些時點與時點之間視窗資料容易丟失。8點得到一個rdb,9點剛要寫一個rdb,掛機了。那麼8~9之間的資料就會丟失。

    2.AOF

    AOF實際是把對redis操作的操作記錄,通過日誌的方式記錄下來,這樣想要恢復資料庫檔案,只需要把所以指令執行一遍就行。

需要開啟aof只需要把dump修改appendonly該為yes即可。

appendonly yes

aof的優點

  • 使用AOF 會讓你的Redis更加耐久: 你可以使用不同的fsync策略:無fsync,每秒fsync,每次寫的時候fsync.使用預設的每秒fsync策略,Redis的效能依然很好(fsync是由後臺執行緒進行處理的,主執行緒會盡力處理客戶端請求),一旦出現故障,你最多丟失1秒的資料.
  • AOF檔案是一個只進行追加的日誌檔案,所以不需要寫入seek,即使由於某些原因(磁碟空間已滿,寫的過程中宕機等等)未執行完整的寫入命令,你也也可使用redis-check-aof工具修復這些問題.
  • Redis 可以在 AOF 檔案體積變得過大時,自動地在後臺對 AOF 進行重寫: 重寫後的新 AOF 檔案包含了恢復當前資料集所需的最小命令集合。 整個重寫操作是絕對安全的,因為 Redis 在建立新 AOF 檔案的過程中,會繼續將命令追加到現有的 AOF 檔案裡面,即使重寫過程中發生停機,現有的 AOF 檔案也不會丟失。 而一旦新 AOF 檔案建立完畢,Redis 就會從舊 AOF 檔案切換到新 AOF 檔案,並開始對新 AOF 檔案進行追加操作。
  • AOF 檔案有序地儲存了對資料庫執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式儲存, 因此 AOF 檔案的內容非常容易被人讀懂, 對檔案進行分析(parse)也很輕鬆。 匯出(export) AOF 檔案也非常簡單: 舉個例子, 如果你不小心執行了 FLUSHALL 命令, 但只要 AOF 檔案未被重寫, 那麼只要停止伺服器, 移除 AOF 檔案末尾的 FLUSHALL 命令, 並重啟 Redis , 就可以將資料集恢復到 FLUSHALL 執行之前的狀態

    aof的缺點

    弊端,體量無線變大, 恢復慢

為解決aof的弊端日誌,優點如果能保住,還是可以用的。就有一個方案:設計一個方案讓日誌,AOF足夠小

就是hdfs,fsimage+edits.log 。讓日誌只記錄增量,合併操作的中間過程。

而4.0版本也是這項技術的分界點

  • 4.0以前進行重寫時,刪除抵消的命令合併重複的命令。這樣最終也是一個純指令的日誌檔案
  • 4.0以後將老的資料RDB到aof檔案中,將增量的以指令的方式Append到AOFAOF是一個混合體。其利用了RDB的快,利用了日誌的全量

從這點可以看出,aof和rdb是可以共存的。

3.持久化的其他特性

日誌重寫

Redis 支援一種有趣的特性: 可以在不打斷服務客戶端的情況下, 對 AOF 檔案進行重建(rebuild)。執行 BGREWRITEAOF 命令, Redis 將生成一個新的 AOF 檔案, 這個檔案包含重建當前資料集所需的最少命令。Redis 2.2 需要自己手動執行 BGREWRITEAOF 命令; Redis 2.4 則可以自動觸發 AOF 重寫, 具體資訊請檢視 2.4 的示例配置檔案。

工作原理

AOF 重寫和 RDB 建立快照一樣,都巧妙地利用了寫時複製機制:

  • Redis 執行 fork() ,現在同時擁有父程序和子程序。子程序開始將新 AOF 檔案的內容寫入到臨時檔案。
  • 對於所有新執行的寫入命令,父程序一邊將它們累積到一個記憶體快取中,一邊將這些改動追加到現有 AOF 檔案的末尾,這樣樣即使在重寫的中途發生停機,現有的 AOF 檔案也還是安全的。
  • 當子程序完成重寫工作時,它給父程序傳送一個訊號,父程序在接收到訊號之後,將記憶體快取中的所有資料追加到新 AOF 檔案的末尾。

搞定!現在 Redis 原子地用新檔案替換舊檔案,之後所有命令都會直接追加到新 AOF 檔案的末尾。

redis的持久化想要開啟其實挺簡單的只需要,修改conf配置檔案的幾個配置項即可。

rdb和aof混合使用

當二者混合使用時,如果redis伺服器停止後重新執行,那麼redis恢復資料只會從aof中同步,而不會去向rdb同步。而且在主從複製時,rdb會記錄上一次連線的埠,而aof不會。所以主從複製時,如果沒有開啟aof,那麼從伺服器在斷開主伺服器後重新連線主伺服器,只會同步從伺服器斷開時的增量資料,而開啟aof後從伺服器需要同步主伺服器中的所有內