一娩怎、RDB
1. RDB介紹
快照持久化也就做RDB持久化∫雀蹋快照持久化的實現(xiàn)方式簡單來說就是:Redis將當前內(nèi)存中存儲的數(shù)據(jù)寫入到一個文件中峦树,將這個文件作為Redis當前的一個快照,保存在磁盤中旦事。當Redis重啟時,將這個快照文件中存儲的內(nèi)容加載進內(nèi)存急灭,即可恢復Redis之前的狀態(tài)姐浮。
2. RDB的觸發(fā)方式
2.1. 手動觸發(fā)
-
save
該命令會阻塞當前Redis服務器,執(zhí)行save命令期間葬馋,Redis不能處理其他命令卖鲤,直到RDB過程完成為止。 -
bgsave
Redis進程執(zhí)行fork操作創(chuàng)建子進程畴嘶,RDB持久化過程由子進程負責蛋逾,完成后自動結(jié)束。阻塞只發(fā)生在fork階段窗悯,一般時間很短区匣。基本上 Redis 內(nèi)部所有的RDB操作都是采用 bgsave 命令蒋院。
命令 | save | bgsave |
---|---|---|
IO類型 | 同步 | 異步 |
阻塞 | 是 | fork時阻塞 |
復雜度 | O(n) | O(n) |
優(yōu)點 | 不會消耗額外內(nèi)存 | 不阻塞 |
缺點 | 阻塞客戶端命令 | 需要fork,消耗內(nèi)存 |
2.2 自動觸發(fā)
在redis.conf文件中的SNAPSHOTTING下亏钩,我們可以對RDB的自動觸發(fā)進行配置
-
save
這里是用來配置觸發(fā) Redis的 RDB 持久化條件,也就是什么時候?qū)?nèi)存中的數(shù)據(jù)保存到硬盤欺旧。比如“save m n”姑丑。表示m秒內(nèi)數(shù)據(jù)集存在n次修改時辞友,自動觸發(fā)bgsave
當然如果你只是用Redis的緩存功能,不需要持久化称龙,那么你可以注釋掉所有的 save 行來停用保存功能∫鹌伲可以直接一個空字符串來實現(xiàn)停用:save "" -
stop-writes-on-bgsave-error
默認值為yes间驮。當啟用了RDB且最后一次后臺保存數(shù)據(jù)失敗,Redis是否停止接收數(shù)據(jù)竞帽。這會讓用戶意識到數(shù)據(jù)沒有正確持久化到磁盤上,否則沒有人會注意到災難(disaster)發(fā)生了屹篓。如果Redis重啟了疙渣,那么又可以重新開始接收數(shù)據(jù)了 -
rdbcompression
默認值是yes。對于存儲到磁盤中的快照堆巧,可以設置是否進行壓縮存儲妄荔。 -
rdbchecksum
默認值是yes谍肤。在存儲快照后,我們還可以讓redis使用CRC64算法來進行數(shù)據(jù)校驗篷角,但是這樣做會增加大約10%的性能消耗系任,如果希望獲取到最大的性能提升,可以關(guān)閉此功能俩滥。 -
dbfilename
設置快照的文件名,默認是 dump.rdb -
dir
設置快照文件的存放路徑错忱,這個配置項一定是個目錄挂据,而不能是文件名
3. RDB的優(yōu)劣勢
3.1 優(yōu)勢
RDB文件緊湊,非常適合盡心備份和災難恢復
生成RDB文件時玖媚,redis主進程會fork一個子進程來處理所有的保存工作婚脱,主進程不需要進行任何磁盤IO操作
RDB 在恢復大數(shù)據(jù)集時的速度比 AOF 的恢復速度要快
3.2 劣勢
RDB方式數(shù)據(jù)沒辦法做到實時持久化/秒級持久化。因為bgsave每次運行都要執(zhí)行fork操作創(chuàng)建子進程错森,屬于重量級操作篮洁,如果不采用壓縮算法(內(nèi)存中的數(shù)據(jù)被克隆了一份,大致2倍的膨脹性需要考慮)瓦阐,頻繁執(zhí)行成本過高(影響性能)
RDB文件使用特定二進制格式保存,Redis版本演進過程中有多個格式的RDB版本踏幻,存在老版本Redis服務無法兼容新版RDB格式的問題(版本不兼容)
在一定間隔時間做一次備份戳杀,所以如果redis意外down掉的話,就會丟失最后一次快照后的所有修改(數(shù)據(jù)有丟失)
二信卡、AOF
1. AOF介紹
AOF全稱為只追加文件(append-only file)傍菇,它的實現(xiàn)方式簡單來說就是:AOF持久化機制,會將Redis執(zhí)行的所有寫指令桥嗤,追加到到AOF的末尾仔蝌,當服務器發(fā)生宕機敛惊,或者由于某些原因需要重啟時,在重啟后瞧挤,讀取AOF文件,重新執(zhí)行其中記錄的寫操作执俩,以此達到恢復數(shù)據(jù)的目的癌刽。
2.觸發(fā)方式
在APPEND ONLY MODE下對appendonly進行yes配置即可開啟AOF
-
appendfsync always
Redis每次執(zhí)行寫指令显拜,都會立即將這個寫指令同步到AOF中;使用這個選項時远荠,Redis發(fā)生異常譬淳,則最多只會丟失一次寫操作(也就是在同步的過程中宕機盹兢,沒同步完成)辰晕,但是這也會導致Redis的響應速度變慢,因為此選項會造成頻繁的IO操作 -
appendfsync everysec
每秒同步一次替裆,使用此選項窘问,速度足夠快,而且發(fā)生宕機時也只會丟失1s內(nèi)的寫操作 -
appendfsync no
讓操作系統(tǒng)來決定什么時候進行同步把鉴,這個選項速度更快儿咱,但是不安全,宕機時丟失數(shù)據(jù)的多少是不確定的
推薦(也是默認)怠缸,使用第二個選項everysec钳宪,每秒進行一次同步,因為這個選項兼顧了速度與安全性搔体,而第一個選項太慢半醉,第三個選項無法保證安全性
3. AOF重寫
AOF持久化的執(zhí)行機制就是,不斷地將寫指令追加到AOF的末尾计螺,這樣就會導致AOF越來越大瞧壮。為了解決AOF越來越大的問題,Redis實現(xiàn)了一種優(yōu)化機制——AOF重寫陈轿。當Redis檢查到AOF已經(jīng)很大時,就會觸發(fā)重寫機制麦射,優(yōu)化其中的內(nèi)容潜秋,將它優(yōu)化為能夠得到相同結(jié)果的最小的指令集合。
經(jīng)過了重寫后峻呛,AOF的大小將會大大減小钩述,而且也去除了不必要的操作,優(yōu)化了恢復數(shù)據(jù)的指令集职恳。而AOF重寫的過程與生成一個快照文件類似方面,如下:
Redis執(zhí)行fock(),創(chuàng)建一個子進程用來執(zhí)行后續(xù)操作恭金,而父進程繼續(xù)處理發(fā)送到Redis的執(zhí)行請求蔚叨;
子進程重寫舊AOF文件辙培,將重寫后的內(nèi)容寫入到一個臨時文件;
如果這個過程中搀别,有新的寫指令到達尾抑,那么Redis會將這些寫指令依舊追加到舊的AOF中,同時也會將這些指令加入到內(nèi)存的一個緩沖區(qū)中榜苫。這樣做的目的是翎冲,如果服務器發(fā)生異常,AOF重寫失敗,這些指令依然能夠保存在舊AOF钳枕,不會丟失赏壹;
當子進程完成重寫工作時蝌借,它給父進程發(fā)送一個信號,父進程在接收到信號之后骨望,將內(nèi)存緩存中的所有寫指令追加到新 AOF 文件的末尾擎鸠;
使用新AOF替換舊的AOF,這之后執(zhí)行的所有寫指令都將追加到新的AOF中劣光;
4. AOF的優(yōu)缺點
4.1 優(yōu)點
- 使用 AOF 持久化會讓 Redis 變得非常耐久绢涡,意思就是說,當發(fā)生異常導致需要重啟服務器時凿傅,只會丟失很少的一部分數(shù)據(jù)数苫,因為AOF持久化默認1s同步一次,也就是說箱残,Redis最多只會丟失1s中所做的修改
- Redis 可以在 AOF 文件體積變得過大時止吁,自動地在后臺對 AOF 進行重寫: 重寫后的新 AOF 文件包含了恢復當前數(shù)據(jù)集所需的最小命令集合
- AOF 文件有序地保存了對數(shù)據(jù)庫執(zhí)行的所有寫入操作, 這些寫入操作以 Redis 協(xié)議的格式保存盼理, 因此 AOF 文件的內(nèi)容非常容易被人讀懂俄删, 對文件進行分析(parse)也很輕松勾哩。
- AOF 文件是一個只進行追加操作的日志文件(append only log)思劳, 因此對 AOF 文件的寫入不需要進行 seek 妨猩, 即使日志因為某些原因而包含了未寫入完整的命令(比如寫入時磁盤已滿,寫入中途停機威兜,等等)庐椒, redis-check-aof 工具也可以輕易地修復這種問題。
4.2 缺點
- 對于相同的數(shù)據(jù)集來說笔宿,AOF 文件的體積通常要大于快照RDB文件的體積大棱诱,因為RDB只存儲數(shù)據(jù),而AOF中的寫指令炬灭,既包含指令靡菇,也包含數(shù)據(jù)厦凤;
- 如果AOF體積太大,那么恢復數(shù)據(jù)將要花費較長的時間泳唠,因為需要重做指令笨腥;
三勇垛、 RDB or AOF?
- 如果希望自己的數(shù)據(jù)庫有很高的安全性谆级,則應該兩者同時使用,AOF用作精確記錄脚仔,而快照用作數(shù)據(jù)備份舆绎,前面也說過,快照非常適合用來做數(shù)據(jù)備份猎醇,因為它只存儲數(shù)據(jù)庫中的數(shù)據(jù)努溃,并且經(jīng)過了壓縮梧税,而且它恢復Redis數(shù)據(jù)的速度一般要快于AOF;
- 如果可以容忍一段時間內(nèi)的數(shù)據(jù)丟失曹鸠,則可以考慮只使用RDB斥铺,減小服務器的開銷;