1. 程式人生 > >redis(11)——redis的持久化機制

redis(11)——redis的持久化機制

redis有兩種持久化機制。分別是RDB和AOF機制。

redis RDB的持久化機制

配置redis RDB的持久化機制

修改redis的配置檔案
vim /etc/redis/6379.conf
以下是預設的快照儲存配置:

save 900 1  
save 300 10
save 60 10000

save 900 1 表示900秒內如果超過1個key被修改,則發起快照儲存。
save 300 10 表示300秒內容如超過10個key被修改,則發起快照儲存
可以在這裡新增自己覺得合適的配置。
更改配置後重新啟動redis服務即可。

RDB持久化是指用資料集快照的方式記錄redis資料庫的所有鍵值對。
RDB的工作原理是:當redis需要做持久化時,redis會fork一個子程序;子程序將資料寫到磁碟上一個臨時RDB檔案中;當子程序完成寫臨時檔案後,將原來的RDB替換掉,這樣的好處就是可以copy-on-write,
每次生成新的dump.rdb都會覆蓋掉之前的老的快照。
如果使用kill -9 來殺死redis程序,下次啟動redis的時候,就會發現redis啟動不了,提示還有pid檔案,需要將redis的pid檔案刪除掉,然後再啟動即可

cd  /var/run
rm -rf redis_6379.pid
/etc/init.d/redis_6379 start

RDB機制的優點:

一旦採用該方式,那麼你的整個Redis資料庫將只包含一個檔案dump.rdb,這樣非常方便進行持久化。比如你可能打算每小時歸檔一些資料。
方便備份,我們可以很容易的將一個一個RDB檔案移動到其他的儲存介質上。
RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快。
RDB 可以最大化 Redis 的效能:父程序在儲存 RDB 檔案時唯一要做的就是 fork 出一個子程序,然後這個子程序就會處理接下來的所有儲存工作,父程序無須執行任何磁碟 I/O 操作。
相對於資料集大時,比AOF的啟動效率更高

RDB的缺點:

資料的安全性低。如果當伺服器還在等待寫快照時出現了宕機,那麼將會丟失資料。
每次儲存 RDB 的時候,Redis 都要 fork() 出一個子程序,並由子程序來進行實際的持久化工作。 在資料集比較龐大時, fork() 可能會非常耗時,造成伺服器在某某毫秒內停止處理客戶端; 如果資料集非常巨大,並且 CPU 時間非常緊張的話,那麼這種停止時間甚至可能會長達整整一秒。

redis AOF的持久化機制

在redis中,AOF的持久化機制預設是關閉的,
appendonly yes,可以開啟AOF持久化機制,在生產環境裡面,一般來說AOF都是要開啟的,除非你說隨便丟個幾分鐘的資料也無所謂
開啟AOF持久化機制之後,redis每次接收到一條寫命令,就會寫入日誌檔案中,當然是先寫入os cache的,然後每隔一定時間再fsync一下
而且即使AOF和RDB都開啟了,redis重啟的時候,也是優先通過AOF進行資料恢復的,因為aof資料比較完整
可以配置AOF的fsync策略,有三種策略可以選擇,一種是每次寫入一條資料就執行一次fsync; 一種是每隔一秒執行一次fsync; 一種是不主動執行fsync
always: 每次寫入一條資料,立即將這個資料對應的寫日誌fsync到磁碟上去,效能非常非常差,吞吐量很低; 確保說redis裡的資料一條都不丟,那就只能這樣了

配置redis的AOF持久化機制方式

appendonly yes
# appendfsync always
appendfsync everysec
# appendfsync no

appendonly yes //啟用aof持久化方式
appendfsync always //每次收到寫命令就立即強制寫入磁碟,最慢的,但是保證完全的持久化,不推薦使用
appendfsync everysec //每秒鐘強制寫入磁碟一次,在效能和持久化方面做了很好的折中,推薦
appendfsync no //完全依賴os,效能最好,持久化沒保證

Redis當中的rewrite操作

aof 的方式也同時帶來了另一個問題。AOF日誌檔案就一個,會不斷的膨脹,持久化檔案會變的越來越大。
所以AOF會自動在後臺每隔一定時間做rewrite操作,比如日誌裡已經存放了針對100w資料的寫日誌了; redis記憶體只剩下10萬; 基於記憶體中當前的10萬。
redis 2.4之後,會自動進行rewrite操作。
在redis.conf中,可以配置rewrite策略

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

比如說上一次AOF rewrite之後,是128mb
然後就會接著128mb繼續寫AOF的日誌,如果發現增長的比例,超過了之前的100%,256mb,就可能會去觸發一次rewrite
但是此時還要去跟min-size,64mb去比較,256mb > 64mb,才會去觸發rewrite

rewrite具體過程如下:
(1)redis fork一個子程序
(2)子程序基於當前記憶體中的資料,構建日誌,開始往一個新的臨時的AOF檔案中寫入日誌
(3)redis主程序,接收到client新的寫操作之後,在記憶體中寫入日誌,同時新的日誌也繼續寫入舊的AOF檔案
(4)子程序寫完新的日誌檔案之後,redis主程序將記憶體中的新日誌再次追加到新的AOF檔案中
(5)用新的日誌檔案替換掉舊的日誌檔案

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 的。

如何修復損壞的AOF檔案:

1). 將現有已經壞損的AOF檔案額外拷貝出來一份。
2). 執行"redis-check-aof --fix "命令來修復壞損的AOF檔案。
3). 用修復後的AOF檔案重新啟動Redis伺服器。