Redis数据持久化
總的來說有兩種持久化方案: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的默認配置如下:
關于配置參數的詳細信息可參閱redis.conf中的說明。
除了通過配置文件進行設置外也可以通過手工執行命令來創建快照
SAVE命令執行一個同步操作,以RDB文件的方式保存實例中所有數據的快照。一般不在生產環境直接使用SAVE 命令,因為會阻塞所有的客戶端的請求,可以使用BGSAVE命令代替。BGSAVE后臺創建數據快照。命名執行結果的狀態碼會立即返回。Redis開辟一個子進程,父進程繼續相應客戶端請求,子進程保存DB到磁盤后退出。客戶端可通過執行LASTSAVE命令檢查操作是否成功。
創建RDB快照的工作流程
Redis需dump數據集到磁盤時會執行下列過程:
Redis forks一個子進程;
子進程寫數據集到臨時的RDB文件;
子進程寫完新的RDB文件后替換舊的RDB文件。
該方式使Redis可以利用copy-on-write機制的好處。
AOF持久化設置
利用快照的持久化方式不是非??煽?#xff0c;當運行Redis的計算機停止工作、意外掉電、意外殺掉了Redis進程那么最近寫入Redis的數據將會丟。對于某些應用這或許不成問題,但對于持久化要求非常高的應用場景快照方式不是理想的選擇。AOF文件是一個替代方案,用以最大限度的持久化數據。同樣,可以通過配置文件來開閉AOF:
當設置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時開始自動重寫AOF auto-aof-rewrite-percentage 100 auto-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或其它類似服務是很好的選擇??蓪⒚刻鞎啃r的RDB快照以加密的方式(可使用gpg -c加密)傳輸到S3。確保將密碼存儲在不同的安全的地方。建議使用不同的存儲服務以提高數據安全性。
使用SCP命令將快照傳輸到遠程服務器。最簡單和安全的方式:獲取一個小的遠程VPS,在其上安裝ssh,生成無密碼的ssh client key添加到VPS的authorized_keys文件,此后便可使用SCP傳輸備份到VPS了。建議搞兩個不同的VPS以提高安全性。
需要注意的是,文件傳輸完成后一定要校驗文件的完整性正確性。可通過MD5或SHA1進行驗證。另外需要搭建一套告警系統,當備份傳輸發生問題時能及時的告知。
轉載于:https://my.oschina.net/vshcxl/blog/869074
總結
以上是生活随笔為你收集整理的Redis数据持久化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android AsyncTask 的分
- 下一篇: MySQL 架构组成—存储引擎