Redis資料持久化

來源:互聯網
上載者:User

標籤:redis   persistence   

總的來說有兩種持久化方案:RDB和AOF
RDB方式按照一定的時間間隔對資料集建立基於時間點的快照。
AOF方式記錄Server收到的寫操作到記錄檔,在Server重啟時通過回放這些寫操作來重建資料集。該方式類似於MySQL中基於語句格式的binlog。當日誌變大時Redis可在後台重寫日誌。
若僅期望資料在Server運行期間存在則可禁用兩種持久化方案。在同一Redis執行個體中同時開啟AOF和RDB方式的資料持久化方案也是可以的。該情況下Redis重啟時AOF檔案將用於重建未經處理資料集,因為叫RDB方式而言,AOF方式能最大限度的保證資料完整性。

兩鐘方案各自的優缺點
RDB優點
RDB是Redis資料集的基於時間點的緊湊的副本,非常適合於備份情境。比如每個小時對RDB檔案做一次小的歸檔,每天對RDB檔案做一次大的歸檔,每月對RDB檔案做一次更大的歸檔。這樣可以在必要的時刻選擇不同的備份版本進行資料恢複。
由於是一個緊湊的檔案,易於傳輸到遠端資料中心或Amazon S3,因此RDB非常適合於災難恢複。
RDB方式的開銷較低,在該種方式下Redis父進程所要做的僅是開闢一個子進程來做剩下的事情。
與AOF相比RDB在資料集較大時能夠以更快的速度恢複。

RDB缺點
若需在Redis停止工作時(例如意外斷電)儘可能保證資料不丟失,那麼RDB不是最好的方案。例如,通常會每隔5分鐘或者更長的時間來建立一次快照,如若Redis沒有被正確的關閉就可能丟失最近幾分鐘的資料。
RDB方式需經常調用fork()函數以開闢子進程來實現持久化。在資料集較大、CPU效能不夠強悍時fork()調用可能很耗時從而會導致Redis在幾毫秒甚至一秒中的時間內不能服務clients。AOF也需要調用fork()但卻可以在不影響資料持久性的條件下調整重寫logs的頻率。

AOF優點
使用AOF方式時Redis持久化更可靠:有三種不同的fsync策略供選擇:no fsync at all、fsync every second、 fsync at every query。預設為fsync every second此時的寫效能仍然很好,且最壞的情況下可能丟失一秒鐘的寫操作。
AOF日誌是append only方式產生的日誌,因此不存在隨機訪問問題以及意外斷電時造成的損毀問題。即使出於某種原因(如磁碟滿)日誌以一個寫了一半的命令結尾,仍可以使用redis-check-aof工具快速進行修複。
當AOF日誌逐漸層大後,Redis可在後台自動的重寫AOF日誌。當Redis在繼續追加舊的AOF記錄檔時重寫日誌是完全安全的。Redis利用可以重建當前資料集的最少的命令產生一個全新的記錄檔,一旦新的記錄檔建立完成Redis開始向新的記錄檔追加日誌。
AOF日誌的格式易於理解易於解析。這在某些情境非常有用。比如,不下心使用FLUSHALL命令清空了所有的資料,同時AOF日誌沒有發生重寫操作,那麼就可以簡單的通過停止Redis Server移除日誌中的最後一條FLUSHALL命令重啟Redis Server來恢複資料。

AOF缺點
同樣的資料集AOF檔案要比RDB檔案大很多。
根據使用的fsync方式不同AOF可能比RDB慢很多。在使用no fsync at all時AOF的效能基本與RDB持平,在使用fsync every second時效能有所下降但仍然較高,在使用 fsync at every query時效能較低。然而RDB方式卻能在高負載的情況下保證延遲儘可能小。
一些特定的命令可能存在bug從而導致重載AOF日誌時不能重建出完全一樣的資料集。這樣的bugs非常非常罕見,已經通過測試套件做了充分的測試。這種類型的bugs對於RDB來說幾乎是不可能的。說的更清晰一點:Redis AOF增量的更新既存的狀態而RDB快照每次都重新建立,從概念上講RDB方式更加健壯。然而,需要注意兩點:每次AOF日誌被Redis重寫的時候日誌由包含資料集的實際資料重建,與追加AOF檔案的方式相比該方式能有效減少bugs出現的機率;現實的應用情境中還未收到過任何使用者關於AOF損毀的報告。

如何選擇持久化方式?
取決於具體的應用情境,通常,兩種方式可同時使用。若比較關心資料但仍能忍受幾分鐘的資料丟失,那麼可以簡單的使用RDB方式。有許多使用者只使用AOF方式,不建議這種做法,一方面以一定時間間隔建立RDB快照是建立資料備份並快速恢複資料的極好的辦法,一方面可以避免AOF方式可能存在的bugs。出於上述原因,將來可能將AOF和RDB方式合二為一。

RDB持久化設定
預設情況下Redis在磁碟上建立二進位格式的命名為dump.rdb的資料快照。可以通過設定檔配置每隔N秒且資料集上至少有M個變化時建立快照、是否對資料進行壓縮、快照名稱、存放快照的工作目錄。redis 2.4.10的預設配置如下:
#900秒後且至少1個key發生變化時建立快照save 900 1#300秒後且至少10個key發生變化時建立快照save 300 10#60秒後且至少10000個key發生變化時建立快照save 60 10000#可通過注釋所有save開頭的行來禁用RDB持久化#建立快照時對資料進行壓縮rdbcompression yes#快照名稱dbfilename dump.rdb#存放快照的目錄(AOF檔案也會被存放在此目錄)dir /var/lib/redis/
關於配置參數的詳細資料可參閱redis.conf中的說明。

除了通過設定檔進行設定外也可以通過手工執行命令來建立快照
SAVE命令執行一個同步操作,以RDB檔案的方式儲存執行個體中所有資料的快照。一般不在生產環境直接使用SAVE 命令,因為會阻塞所有的用戶端的請求,可以使用BGSAVE命令代替。BGSAVE後台建立資料快照。命名執行結果的狀態代碼會立即返回。Redis開闢一個子進程,父進程繼續相應用戶端請求,子進程儲存DB到磁碟後退出。用戶端可通過執行LASTSAVE命令檢查操作是否成功。

建立RDB快照的工作流程
Redis需dump資料集到磁碟時會執行下列過程:
Redis forks一個子進程;
子進程寫資料集到臨時的RDB檔案;
子進程寫完新的RDB檔案後替換舊的RDB檔案。
該方式使Redis可以利用copy-on-write機制的好處。

AOF持久化設定
利用快照的持久化方式不是非常可靠,當運行Redis的電腦停止工作、意外掉電、意外殺掉了Redis進程那麼最近寫入Redis的資料將會丟。對於某些應用這或許不成問題,但對於持久化要求非常高的應用情境快照方式不是理想的選擇。AOF檔案是一個替代方案,用以最大限度的持久化資料。同樣,可以通過設定檔來開閉AOF:
#關閉AOFappendonly no#開啟AOFappendonly yes
當設定appendonly為yes後,每次Redis接收到的改變資料集的命令都會被追加到AOF檔案。重啟Redis後會重放AOF檔案來重建資料。

還可以通過設定檔配置AOF檔案名稱、調用fsync的頻率、調用fsync的行為、重寫AOF的條件。redis 2.4.10的預設配置如下:
#預設AOF檔案名稱appendfilename appendonly.aof#每秒調用一次fsync重新整理資料到磁碟appendfsync everysec#當進程中BGSAVE或BGREWRITEAOF命令正在執行時不阻止主進程中的fsync()調用(預設為no,當存在延遲問題時需調整為yes)no-appendfsync-on-rewrite no#當AOF增長率為100%且達到了64mb時開始自動重寫AOFauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb
各參數含義可參閱redis.conf中詳細說明。

幾點說明
日誌重寫
隨著Redis接收到的命令的增加AOF檔案會變得越來越大。Redis支援日誌重寫特性,可以在不影響響應用戶端的前提下在後台重構AOF檔案。當在Redis中執行BGREWRITEAOF後Redis將使用構建資料集所需的最少的命令來重構記錄檔。Redis2.2中需要經常手動運行BGREWRITEAOF,Redis2.2開始支援自動觸發日誌重寫。

日誌重寫同樣使用copy-on-write機制,流程大致如下:
Redis開闢一個子進程;
子進程在臨時檔案中寫新的AOF檔案;
父進程將所有新的更改緩衝在memory中(同時新更改被寫入舊的AOF,這樣即使重寫操作失敗了也是安全的);
在子進程重寫好臨時AOF後父進程收到一個訊號並追加memory中緩衝的更改到子進程產生的臨時檔案的末尾;
Redis進行檔案重新命名用新的檔案替換舊的檔案並開始追加新的資料到新檔案。

fsync調用模式

該模式決定了Redis重新整理資料到磁碟的頻率,有三個可選項:
no fsync at all 全由作業系統決定刷資料的時機。最快但最不安全。
fsync every second 每秒一次重新整理。足夠快,最多可丟失一秒的資料。
fsync at every query 每次記錄一條新的命令到AOF便刷一次資料到磁碟。最慢但最安全。
預設策略(也是預設策略)為fsync every second

AOF損壞時的對策
若在寫AOF檔案時Server崩潰則可能導致AOF檔案損壞而不能被Redis載入。可通過如下步驟修複:
建立一個AOF檔案的備份;
使用redis-check-aof工具修複原始的AOF檔案;
$ redis-check-aof --fix
使用diff -u 檢查備份檔案和修複後檔案的異同(可選步驟);
使用修複後的AOF檔案重啟Redis。

如何由RDB持久化轉換到AOF持久化?
Redis >=2.2時
建立最近的RDB檔案的備份;
將備份儲存在安全的位置;
發起如下命令;
$redis-cli config set appendonly yes
$redis-cli config set save ""(可選,若不執行RDB和AOF方式將並存)
確認資料庫包含相同的keys;
確認write操作被正確追加到了AOF檔案。
注意事項:記得修改redis.conf中對應的配置以免Redis Server重啟後通過命令進行的配置更新丟失而重新使用舊的設定檔中配置。

Redis2.0時
建立最近的RDB檔案的備份;
將備份存放在安全的位置;
停止資料庫上的所有寫操作;
發起 redis-cli bgrewriteaof命令建立AOF檔案;
當AOF檔案產生後停止Redis Server;
編輯redis.conf開啟AOF持久化;
重啟Redis Server;
確認資料庫包含相同的keys;
確認write操作被正確追加到了AOF檔案。

AOF與RDB之間的相互影響
Redis2.4以上的版本會確保在RDB快照建立時不觸發AOF重寫或者在AOF重寫時不允許BGSAVE操作,以避免Redis後台進程同時做繁重的磁碟I/O操作。
當建立RDB快照時對於使用者使用BGREWRITEAOF明確發起的日誌重寫操作server會立刻回應一個ok狀態代碼告知使用者操作將回被執行,若且唯若快照建立完成後重寫操作開始被執行。
在同時使用了AOF和RDB方式的情況下,Redis重啟後會優先使用AOF檔案來重構未經處理資料集。

備份Redis 資料

務必做好資料備份以防意外丟失。Redis是備份友好的,可在資料庫運行時拷貝RDB檔案。建議的備份方案:
建立一個cron作業在一個目錄中每小時建立一次RDB快照在另一目錄中每天建立一次RDB快照;
cron作業每次啟動並執行時候使用find命令確保過時的RDB快照檔案被清理掉(可以通過在快照命中包含資料和時間資訊來進行標記);
確保將RDB快照轉移到外部的資料中心或者至少是運行Redis執行個體的物理機之外的機器(至少每天一次)。

災難恢複
在Redis中災難恢複和資料備份基本上是同樣的過程。可考慮將備份分布到不同的遠端資料中心以最大限度的避免資料丟失。幾種低成本的災難恢複計劃:
Amazon S3或其它類似服務是很好的選擇。可將每天會每小時的RDB快照以加密的方式(可使用gpg -c加密)傳輸到S3。確保將密碼儲存在不同的安全的地方。建議使用不同的儲存服務以提高資料安全性。
使用SCP命令將快照傳輸到遠程伺服器。最簡單和安全的方式:擷取一個小的遠程VPS,在其上安裝ssh,產生無密碼的ssh client key添加到VPS的authorized_keys檔案,此後便可使用SCP傳輸備份到VPS了。建議搞兩個不同的VPS以提高安全性。
需要注意的是,檔案傳輸完成後一定要校正檔案的完整性正確性。可通過MD5或SHA1進行驗證。另外需要搭建一套警示系統,當備份傳輸發生問題時能及時的告知。

Redis資料持久化

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.