1. 程式人生 > >redis實戰--redis兩種持久化方式

redis實戰--redis兩種持久化方式

前言:

說到redis的持久化,大家可能就想到了RDB和AOF兩種方式; 下面就這兩種方案的意義以及兩種持久化方案的工作原理。

持久化的意義

  1. redis的持久化意義在於故障恢復,資料恢復。 如果redis伺服器掛了,遇到了災難性的故障,redis不可用了;如果只是放在記憶體中,那麼資料可能就沒有了;如果我們通過持久化將資料持久化到磁碟中,然後定期同步到雲端儲存伺服器中,那麼可以儘可能保證資料不會全部丟失,能夠恢復一部分的資料。
  2. 還有一點,如果你的redis整個叢集掛了,如果沒有做持久化,資料沒有備份,那麼大量的其你去過來,快取全部不能命中,也就是說在redis中找不到資料,這個時候可能就會出現快取的雪崩問題,所有的請求直接打到資料庫中。如果我們做了持久化,redis掛了,我們就可以恢復一部分redis中的資料,也就可以避免快取雪崩的問題。
  3. 當然如果想要redis僅僅作為純記憶體的快取來用,就不需要持久化了。

RDB持久化機制介紹

優勢:
1.對資料執行週期性的進行持久化。RDB會生成多個數據檔案,每個資料檔案都代表了某一個時刻中redis的資料,這種多個數據檔案的方式,適合做冷備,可以將這種完整的資料檔案傳送到一些遠端的安全儲存上去,比如說Amazon的S3雲服務上去,在國內可以是阿里雲的ODPS分散式儲存上,以預定好的備份策略來定期備份redis中的資料。
2.對redis對外提供的讀寫服務,影響非常小,可以讓redis保持高效能;因為redis主程序只需要fork一個子程序,讓子程序執行磁碟IO操作來進行RDB持久化即可。
3.相比對AOF機制,如果資料量比較大,RDB的啟動效率會更好。
劣勢:


由於是週期性的持久化,所以如果要求數量完整性要求高的場景,可能使用AOF比較好一點。另外如果在生成快照的時候,檔案比較大的時候,可能會導致本身提供的服務有停頓。

AOF持久化機制介紹

優勢:
資料的安全性高,AOF機制對每條寫入命令作為日誌,以append-only的模式寫入一個日誌檔案中,在redis重啟的時候,可以通過回放AOF日誌中的寫入指令來重新構建整個資料集
AOF可以更好的保護資料的完整性,一般是每個一秒就會有後臺程序執行一次fsync操作;日誌檔案以append-only的模式寫入,沒有磁碟定址的開銷,寫入效能高。

劣勢:
因為AOF記得是指令日誌,AOF的日誌檔案比RDB的快照會更大一點,不過這點可以忽略不計,因為現在儲存的成本越來越低了。
AOF 可能比 RDB 慢,這取決於準確的 fsync 策略。通常 fsync 設定為每秒一次的話效能仍然很高,如果關閉 fsync,即使在很高的負載下也和 RDB 一樣的快。

RDB和AOF如何取捨
1.通常來說,你應該同時使用這兩種持久化方法。綜合使用AOF和RDB兩種持久化機制,用AOF來保證資料不丟失,作為資料恢復的第一選擇; 用RDB來做不同程度的冷備,在AOF檔案都丟失或損壞不可用的時候,還可以使用RDB來進行快速的資料恢復
2.如果你很關注你的資料,但是仍然可以接受災難時有幾分鐘的資料丟失,你可以單獨使用 RDB。

如何配置RDB持久化機制

在redis.conf檔案中配置持久化策略;
根據檢查點去check是否又變更,如果有,就生成一個新的dump.rdb檔案;每次生成一個新的快照,都會覆蓋之前的老快照。
主要引數解釋如下:
save 900 1
每隔900s,如果有超過1key發生了變更,那麼就生成一個新的dump.rdb檔案
save 300 10
每隔300s,如果有超過10key發生了變更,那麼就生成一個新的dump.rdb檔案
save 60 10000
每隔60s,如果有超過10000個key發生了變更,那麼就生成一個新的dump.rdb檔案

那我們就可以手動去配置檢查點:
save 3 1 我們設定一個每隔3秒鐘。 我們可以看到如果我們設定了檢查點,過了3秒就會在伺服器自動生成dump.rdb; 異常關掉任務之後(kill程序),資料會自動恢復。

如果我們沒有配置這個檢查點,用預設的檢查點,資料則會丟失。

注:如果是正常shutdown,redis會自動生成一份rdb的dump檔案。

如何配置AOF策略

AOF持久化,預設是關閉的,預設開啟RDB持久化
appendonly yes,可以開啟AOF持久化機制;AOF持久化機制之後,redis每次接收到一條寫命令,就會寫入日誌檔案中,當然是先寫入os cache的,然後每隔一定時間再fsync一下

fsync總共有三種策略可以選擇:
always: 每次寫入一條資料,立即將這個資料對應的寫日誌fsync到磁碟上去,效能非常非常差,吞吐量很低;
everysec: 每秒將os cache中的資料fsync到磁碟,這個最常用的,生產環境一般都這麼配置,效能很高
no: redis負責將資料寫入os cache就不管了,然後後面os自己會時不時有自己的策略將資料刷入磁碟,不可控

AOF rewrite:
redis中的資料會不斷的被淘汰掉,但是對應的寫入日誌還在AOF中,AOF就一個,所以會越來越大。基於以上原因,AOF會在後臺每隔一定的時間做rewrite操作;

在redis.conf中,可以配置rewrite策略
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
假設上次AOF rewirte之後為100Mb,然後接著寫AOF的操作日誌,如果發現增長的比例超過100% ,並且比64Mb大的話,則會再做一個rewrite,否則不會觸發。
具體rewrite步驟:
(1)redis fork一個子程序
(2)子程序基於當前記憶體中的資料,構建日誌,開始往一個新的臨時的AOF檔案中寫入日誌
(3)redis主程序,接收到client新的寫操作之後,在記憶體中寫入日誌,同時新的日誌也繼續寫入舊的AOF檔案
(4)子程序寫完新的日誌檔案之後,redis主程序將記憶體中的新日誌再次追加到新的AOF檔案中
(5)用新的日誌檔案替換掉舊的日誌檔案

AOF檔案修復
如果機器宕機了,我們可以用redis-check-aof –fix命令來修復破損的AOF檔案

AOF和RDB同時工作

(1)如果RDB在執行snapshotting操作,那麼redis不會執行AOF rewrite; 如果redis再執行AOF rewrite,那麼就不會執行RDB snapshotting
(2)如果RDB在執行snapshotting,此時使用者執行BGREWRITEAOF命令,那麼等RDB快照生成之後,才會去執行AOF rewrite
(3)同時有RDB snapshot檔案和AOF日誌檔案,那麼redis重啟的時候,會優先使AOF進行資料恢復,因為其中的日誌更完整