【redis】-- redis的持久化(做爲數據庫)

redis是一個基於內存的數據庫,故在redis正在運行的數據都在內存中,而內存掉電,內存上因此數據都會消失。故把redis當成數據庫使用時就須要對redis進行持久化。redis

在說redis持久化的時候,咱們先來聊聊其餘的知識。linux的父子進程。在Linux中使用fork()函數會給當前正在運行的進程建立一個子進程。那麼如今問題就來了,fork時父子進程中的數據有什麼關係呢?通常說到進程咱們都會知道進程間彼此是數據隔離的。然而實際上,子進程在剛建立時,能夠看到子進程中的數據。而在修改該數據時,卻不會對父進程形成影響。一樣子進程也不會受到父進程修改數據的影響。而形成這種現象的,正是由於linux的copy on write機制。數據庫

copy on write:是一種內核機制,通俗來說就是寫時複製。及建立子進程並不發生複製,建立子進程後父子進程共用數據。只有在修改數據是纔會建立新的空間。緩存

這樣作的好處是建立進程變快了。並且根據開發經驗,咱們建立子進程後不可能父子進程把全部數據都改一遍。而這套機制就是指針支撐的。玩的是指針安全

redis中有兩種數據到存儲方式,rdb和aof。下面咱們來着重講一下這兩種持久化方式:服務器

1.RDB

rdb持久化的方式

RDB持久化方式可以在指定的時間間隔能對你的數據進行快照存儲.app

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後從服務器須要同步主服務器中的全部內容。

相關文章
相關標籤/搜索