一、RDB:redis
RDB是在指定時間間隔內生成數據集的時間點快照(point-in-time snapshot)持久化,它是記錄一段時間內的操做,一段時間內操做超過多少次就持久化。
默認是會以快照的形式將數據持久化到磁盤的(一個二進制文件,dump.rdb,這個文件名字能夠指定),在配置文件中的格式是:save N M表示在N秒以內,redis至少發生M次修改則redis抓快照到磁盤。固然也能夠手動執行save或者bgsave(異步)作快照。
工做原理:
當redis須要作持久化時,redis會fork一個子進程;子進程將數據寫到磁盤上一個臨時RDB文件中;當子進程完成寫臨時文件後,將原來的RDB替換掉,這樣的好處就是能夠copy-on-write(寫時複製技術)數據庫
二、AOF:安全
AOF持久化記錄服務器執行的全部寫操做命令,並在服務器啓動時,經過從新執行這些命令來還原數據集,它能夠實現每次操做都持久化。
AOF文件中的命令所有以redis協議的格式來保存,新命令會被追加到文件的末尾。 redis還能夠在後臺對AOF文件進行重寫(rewrite),使得AOF文件的體積不會超出保存數據集狀態所需的實際大小。redis還能夠同時使用AOF持久化和RDB持久化。在這種狀況下,當redis重啓時,它會優先使用AOF文件來還原數據集, 由於AOF文件保存的數據集一般比RDB文件所保存的數據集更完整。也能夠關閉持久化功能,讓數據只在服務器運行時存在。服務器
RDB方法在redis異常死掉時,最近的數據會丟失(丟失數據的多少視你save策略的配置),因此這是它最大的缺點,當業務量很大時,丟失的數據是不少的。
Append-only方法能夠作到所有數據不丟失,但redis的性能就要差些。AOF就能夠作到全程持久化,只須要在配置文件中開啓(默認是no),appendonly yes開啓AOF以後,redis每執行一個修改數據的命令,都會把它添加到aof文件中,當redis重啓時,將會讀取AOF文件進行「重放」以恢復到redis關閉前的最後時刻。網絡
redis啓動裝載:
AOF優先於RDB
RDB性能優於AOF,由於裏面沒有重複
Redis一次性將數據加載到內存中,一次性預熱架構
LOG Rewriting(重寫)隨着修改數據的執行AOF文件會愈來愈大,其中不少內容記錄某一個key的變化狀況。所以redis有了一種比較有意思的特性:在後臺重建AOF文件,而不會影響client端操做。在任什麼時候候執行bgrewriteaof命令,都會把當前內存中最短序列的命令寫到磁盤,這些命令能夠徹底構建當前的數據狀況,而不會存在多餘的變化狀況(好比狀態變化,計數器變化等),縮小的AOF文件的大小。因此當使用AOF時,redis推薦同時使用bgrewriteaof。AOF 重寫和 RDB 建立快照同樣,都巧妙地利用了寫時複製機制。app
爲了壓縮AOF的持久化文件,Redis提供了bgrewriteaof命令。
收到此命令後Redis將使用與快照相似的方式將內存中的數據以命令的方式保存到臨時文件中,最後替換原來的文件,以此來實現控制AOF文件的增加。
因爲是模擬快照的過程,所以在重寫AOF文件時並無讀取舊的AOF文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的AOF文件。異步
AOF文件刷新的方式,有三種,參考配置參數appendfsync :
appendfsync always: 每提交一個修改命令都調用fsync刷新到AOF文件,很是很是慢,但也很是安全;
appendfsync everysec: 每秒鐘都調用fsync刷新到AOF文件,很快,但可能會丟失一秒之內的數據;
appendfsync no: 依靠OS進行刷新,redis不主動刷新AOF,這樣最快,但安全性就差。默認並推薦每秒刷新,這樣在速度和安全上都作到了兼顧。工具
redis默認的持久化方式是RDB。性能
可能因爲系統緣由致使了AOF損壞,redis沒法再加載這個出錯的AOF文件,能夠按照下面步驟來修復:
一、首先作一個AOF文件的備份,複製到其餘地方;
二、修復原始AOF文件,執行命令redis-check-aof –fix ;
三、能夠經過diff –u命令來查看修復先後文件不一致的地方;
四、重啓redis服務。
LOG Rewrite的工做原理:
一樣用到了copy-on-write:首先redis會fork一個子進程;子進程將最新的AOF寫入一個臨時文件;父進程增量的把內存中的最新執行的修改寫入(這時仍寫入舊的AOF,rewrite若是失敗也是安全的);當子進程完成rewrite臨時文件後,父進程會收到一個信號,並把以前內存中增量的修改寫入臨時文件末尾;這時redis將舊AOF文件重命名,臨時文件重命名,開始向新的AOF中寫入。
爲以防萬一(機器壞掉或磁盤壞掉),最好按期把使用filesnapshotting 或 Append-only 生成的*rdb *.aof文件備份到遠程機器上,而後能夠用crontab定時(好比每半小時)scp一次。若是沒有使用redis的主從功能 ,半小時備份一次應該是能夠了;而且若是應用數據量不大的話,能夠單機部署,作主從有點浪費。具體仍是要根據應用而定。
接着具體解說下這兩種持久化:
若是的內存中的數據量很是大的時候,rdb持久化的臨時文件就會很是大,幾乎是原文件的1倍,性能有所下降。 若是當寫操做要馬上持久化的時候,能夠執行命令:save save是全阻塞的,bgsave是異步的。 snapshot快照首先將數據寫入臨時文件,當成功結束後,將臨時文件重名爲dump.rdb 使用RDB恢復數據: 自動的持久化數據存儲到dump.rdb後。實際只要重啓redis服務便可完成(啓動redis的server時會從dump.rdb中先同步數據) 客戶端使用命令進行持久化save存儲: redis-cli -h ip -p port save redis-cli -h ip -p port bgsave 一個是在前臺進行存儲,一個是在後臺進行存儲。個人client就在server這臺服務器上,因此不須要連其餘機器,直接./redis-cli bgsave。 因爲redis是用一個主線程來處理全部 client的請求,這種方式會阻塞全部client請求。因此不推薦使用。另外一點須要注意的是,每次快照持久 化都是將內存數據完整寫入到磁盤一次,並非增量的只同步髒數據。若是數據量大的話,並且寫操做比較多,必然會引發大量的磁盤io操做,可能會嚴重影響性能 若是aof或rdb文件語法有誤,可使用下面兩條命令來修復。 1)aof修復命令: redis-check-aof --fix appendonlly.aof 2)rdb修復命令: redis-check-rdb --fix dump.rdb aof是採用文件追加方式,將全部的寫操做保存在aof文件中,當文件愈來愈大時,有可能存在相同的寫操做,這些相同的操做能夠將他濃縮爲一條操做,這樣能夠減小aof文件的容量。 redis對aof新增了一種重寫機制,當aof文件大小超過所設定的閾值時,redis會啓動aof文件的內容壓縮,只保留能夠恢復數據的最小指令集,可使用命令bgrewriteaof。
RDB和AOF各自的優缺點:
一、RDB持久化優勢
RDB 是一個很是緊湊(compact)的文件,它保存了Redis在某個時間點上的數據集。 這種文件很是適合用於進行備份的,好比說,能夠在最近的24小時內,每小時備份一次RDB文件,而且在每月的每一天,也備份一個 RDB 文件。這樣的話,即便趕上問題,也能夠隨時將數據集還原到不一樣的版本。RDB 很是適用於災難恢復(disaster recovery):它只有一個文件,而且內容都很是緊湊,能夠(在加密後)將它傳送到別的數據中心,或者亞馬遜 S3 中。RDB能夠最大化 Redis 的性能:父進程在保存RDB文件時惟一要作的就是fork出一個子進程,而後這個子進程就會處理接下來的全部保存工做,父進程無須執行任何磁盤 I/O 操做。RDB在恢復大數據集時的速度比AOF的恢復速度要快。
二、RDB持久化缺點
若是須要儘可能避免在服務器故障時丟失數據,那麼RDB不適合這種狀況。 雖然Redis容許設置不一樣的保存點(save point)來控制保存RDB文件的頻率,可是由於RDB文件須要保存整個數據集的狀態,因此它並非一個輕鬆的操做。所以你可能會至少5分鐘才保存一次RDB文件。在這種狀況下, 一旦發生故障停機,就可能會丟失好幾分鐘的數據。每次保存RDB的時候,Redis都要 fork() 出一個子進程,並由子進程來進行實際的持久化工做。在數據集比較龐大時, fork() 可能會很是耗時,形成服務器在某某毫秒內中止處理客戶端; 若是數據集很是巨大,而且 CPU 時間很是緊張的話,那麼這種中止時間甚至可能會長達整整一秒。 雖然 AOF 重寫也須要進行 fork() ,但不管 AOF 重寫的執行間隔有多長,數據的耐久性都不會有任何損失。
三、AOF持久化優勢
使用AOF持久化會讓Redis變得很是耐久(much more durable):你能夠設置不一樣的fsync 策略,好比無fsync ,每秒鐘一次 fsync ,或者每次執行寫入命令時fsync 。AOF的默認策略爲每秒鐘fsync 一次,在這種配置下,Redis 仍然能夠保持良好的性能,而且就算髮生故障停機,也最多隻會丟失一秒鐘的數據( fsync 會在後臺線程執行,因此主線程能夠繼續努力地處理命令請求)。AOF 文件是一個只進行追加操做的日誌文件(append only log), 所以對 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文件的體積一般要大於RDB文件的體積。根據所使用的fsync策略,AOF的速度可能會慢於RDB 。在通常狀況下,每秒 fsync 的性能依然很是高,而關閉fsync可讓AOF的速度和 RDB 同樣快, 即便在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 能夠提供更有保證的最大延遲時間(latency)。AOF 在過去曾經發生過這樣的 bug : 由於個別命令的緣由,致使 AOF 文件在從新載入時,沒法將數據集恢復成保存時的原樣。 (舉個例子,阻塞命令BRPOPLPUSH就曾經引發過這樣的 bug 。)測試套件裏爲這種狀況添加了測試:它們會自動生成隨機的、複雜的數據集,並經過從新載入這些數據來確保一切正常。 雖然這種 bug 在 AOF 文件中並不常見, 可是對比來講, RDB 幾乎是不可能出現這種 bug 的。
RDB持久化和AOF持久化,應該用哪個?
通常來講,若是想達到足以媲美PostgreSQL的數據安全性,應該同時使用兩種持久化功能。
若是很是關心數據,但仍然能夠承受數分鐘之內的數據丟失, 那麼能夠只使用RDB持久化。
不推薦只使用AOF持久化:由於定時生成RDB快照(snapshot)很是便於進行數據庫備份,而且RDB恢復數據集的速度也要比 AOF 恢復的速度要快,除此以外,使用RDB還能夠避免以前提到的AOF程序的bug。
2、線上redis主從環境下的持久化策略
描述:
以前線上項目使用redis,部署了redis主從環境。redis的主從複製功能很是強大,一個master能夠擁有多個slave,而一個slave又能夠擁有多個slave,如此下去,造成了強大的多級服務器集羣架構。因爲主redis採用了AOF和save快照的持久化,長時間下去,aof文件不斷增大,磁盤空間使用率逐漸暴增。
考慮到性能問題,須要對redis持久化作些調整,調整以下:
一、主庫不開啓AOF持久化,並關閉save快照功能(即註釋默認的三個save設置),只在每晚12點定時手動作一次bgsave快照,並將快照文件轉移到異地。即主庫上不產生appendonly.aof持久化文件,作的快照數據放在.rdb文件裏(如dump.rdb,因爲是壓縮配置(rdbcompression yes表示快照文件要壓縮),因此快照文件要比aof文件小),而後將這個快照文件dump.rdb轉移到其餘的服務器上,防止主服務器宕機形成的損失!
二、從庫開啓AOF持久化並1秒落地,一樣不作快照save。並在每晚12點作一次bgrewriteaof壓縮appendonly.aof持久化文件,壓縮前先對aof文件進行備份。
--------------------------------------------------------------------------------------------------------------------------------------------
按照這種方法進行redis持久化調整,因爲線上redis的主庫以前採用了AOF和save快照的持久化,以後將這兩種都關閉,從庫採用AOF持久化。出現了下面的現象:
就是主庫關閉AOF和save快照後,主redis上的appendonly.aof持久化文件在一段時間內還在刷,在增大,這是正常的,因爲以前開啓的緣故,刷過一段時間,主redis的appendonly.aof持久化文件就不刷了,只有從redis的appendonly.aof持久化文件在刷了
--------------------------------------------------------------------------------------------------------------------------------------------
主從redis部署的主要目的:數據持久化,災難恢復,冗餘。主庫不落地,減小消耗。
一、主庫不作AOF,不作快照,容許從庫訪問便可。
二、從庫開啓AOF,不作save
配置:
1、主庫配置: 關閉save開展,aof默認不開啓: #save 900 1 #save 300 10 #save 60 10000 容許從庫訪問: #bind 192.168.71.229 主庫設置了密碼訪問: requirepass password 2、從庫配置: 開啓AOF持久化: appendonly yes appendfsync everysec appendfilename appendonly.aof 設置主庫密碼: slaveof <masterip> <masterport>
驗證:
主節點: ./redis-benchmark -c 100 -n 100000 -r 10000 -q -a password ./redis-cli -a password dbsize 從節點: ./redis-cli dbsize
數量同樣就是同步成功
災難恢復:
一、主庫故障,快速恢復到最近狀態描述:主庫掛了(redis程序掛了/機器宕機了),從庫正常,
恢復到主庫掛掉的時間點:去從庫手動作一次快照,拷貝快照到主庫相應目錄,啓動,OK。
注意:
一、若主庫掛了,不能直接開啓主庫程序。若直接開啓主庫程序將會沖掉從庫的AOF文件,這樣將致使只能恢復到前一天晚上12的備份。
二、程序在跑時,不能重啓網絡(程序是經過網絡接口的端口進行讀寫的)。網絡中斷將致使中斷期間數據丟失。
三、肯定配置文件所有正確才啓動(尤爲不能有數據文件名相同),不然會沖掉原來的文件,可能形成沒法恢復的損失。