Redis 是完全開源免費的,是一個高性能的
key-value
內存數據庫。
Redis提供了持久化到磁盤的機制,分別是RDB(Redis DataBase)和AOF(Append Only File)慨仿。
持久化流程
- 客戶端向服務端發(fā)送寫操作(數據在客戶端的內存中);
- 數據庫服務端接收到寫請求的數據(數據在服務端的內存中)纳胧;
- 服務端調用write這個系統(tǒng)調用镰吆,將數據往磁盤上寫(數據在系統(tǒng)內存的緩沖區(qū)中);
- 操作系統(tǒng)將緩沖區(qū)中的數據轉移到磁盤控制器上(數據在磁盤緩存中)跑慕;
- 磁盤控制器將數據寫到磁盤的物理介質中(數據真正落到磁盤上)万皿。
存在兩種情況故障:
- Redis數據庫發(fā)生故障,只要在上面的第三步執(zhí)行完畢核行,那么就可以持久化保存牢硅,剩下的兩步由操作系統(tǒng)替我們完成;
- 操作系統(tǒng)發(fā)生故障芝雪,必須上面5步都完成才可以减余。
redis實現上面5個保存磁盤的步驟。提供了兩種策略機制惩系,RDB和AOF位岔。
RDB機制
RDB其實就是把數據以快照的形式保存在磁盤上如筛。RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤。也是默認的持久化方式抒抬,這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名為dump.rdb杨刨。
在我們安裝了redis之后,所有的配置都是在redis.conf文件中擦剑,里面保存了RDB和AOF兩種持久化機制的各種配置妖胀。
對于RDB來說,提供了三種機制實現生成一個快照的過程:save惠勒、bgsave赚抡、自動化。
save觸發(fā)方式
該命令會阻塞當前Redis服務器纠屋,執(zhí)行save命令期間怕品,Redis不能處理其他命令,直到RDB過程完成為止巾遭。執(zhí)行完成時候如果存在老的RDB文件肉康,就把新的替代掉舊的。我們的客戶端可能都是幾萬或者是幾十萬灼舍,這種方式顯然不可取吼和。
bgsave觸發(fā)方式
執(zhí)行該命令時,Redis會在后臺異步進行快照操作骑素,快照同時還可以響應客戶端請求炫乓。
具體操作是Redis進程執(zhí)行fork操作創(chuàng)建子進程,RDB持久化過程由子進程負責献丑,完成后自動結束末捣。阻塞只發(fā)生在fork階段,一般時間很短创橄。基本上 Redis 內部所有的RDB操作都是采用 bgsave 命令箩做。
自動觸發(fā)
自動觸發(fā)是由我們的配置文件來完成的。在redis.conf配置文件中妥畏,里面有如下配置邦邦,我們可以去設置:
- save:“save m n”。表示m秒內數據集存在n次修改時醉蚁,自動觸發(fā)bgsave燃辖;
- stop-writes-on-bgsave-error:默認值為yes。當啟用了RDB且最后一次后臺保存數據失敗网棍,Redis是否停止接收數據黔龟。如果Redis重啟了,那么又可以重新開始接收數據了;
- rdbcompression:默認值是yes氏身。對于存儲到磁盤中的快照巍棱,可以設置是否進行壓縮存儲;
- rdbchecksum:默認值是yes观谦。在存儲快照后,我們還可以讓redis使用CRC64算法來進行數據校驗桨菜,但是這樣做會增加大約10%的性能消耗豁状,如果希望獲取到最大的性能提升,可以關閉此功能倒得。
- dbfilename:設置快照的文件名泻红,默認是 dump.rdb;
- dir:設置快照文件的存放路徑霞掺,這個配置項一定是個目錄谊路,而不能是文件名。
命令 | save | bgsave |
---|---|---|
IO類型 | 同步 | 異步 |
是否阻塞 | 是 | 否(但fork子進程時會阻塞) |
復雜度 | O(n) | O(n) |
優(yōu)點 | 不消耗額外內存 | 不阻塞客戶端命令 |
缺點 | 阻塞客戶端命令 | 需要fork菩彬,消耗內存 |
優(yōu)點:
- RDB文件緊湊缠劝,全量備份,非常適合用于進行備份和災難恢復骗灶;
- 生成RDB文件的時候惨恭,redis主進程會fork()一個子進程來處理所有保存工作,主進程不需要進行任何磁盤IO操作耙旦;
- RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快脱羡。
缺點:
- RDB快照是一次全量備份,當進行快照持久化時免都,會開啟一個子進程專門負責快照持久化锉罐,子進程會擁有父進程的內存數據,父進程修改內存子進程不會反應出來绕娘,所以在快照持久化期間修改的數據不會被保存脓规,可能丟失數據。
AOF機制
全量備份總是耗時险领,有時候我們提供一種更加高效的方式AOF抖拦,工作機制很簡單,redis會將每一個收到的寫命令都通過write函數追加到文件中舷暮。就是日志記錄态罪。
持久化原理:每當有一個寫命令過來時,就直接保存在AOF文件中下面。
文件重寫原理:AOF的方式也同時帶來了另一個問題复颈。持久化文件會變的越來越大。為了壓縮aof的持久化文件。redis提供了bgrewriteaof命令耗啦。將內存中的數據以命令的方式保存到臨時文件中凿菩,同時會fork出一條新進程來將文件重寫。
重寫aof文件的操作帜讲,并沒有讀取舊的aof文件衅谷,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點類似似将。
三種觸發(fā)機制
- 每修改同步always:同步持久化获黔,每次發(fā)生數據變更會被立即記錄到磁盤 ,能較差但數據完整性比較好在验;
- 每秒同步everysec:異步操作玷氏,每秒記錄,如果一秒內宕機腋舌,有數據丟失盏触;
- 不同no:從不同步。
命令 | always | everysec | no |
---|---|---|---|
優(yōu)點 | 不丟失數據 | 每秒以此fsync | 不管用 |
缺點 | 磁盤IO開銷大 | 存在丟1秒數據的風險 | 不可控 |
優(yōu)點
- AOF可以更好的保護數據不丟失块饺,一般AOF會每隔1秒赞辩,通過一個后臺線程執(zhí)行一次fsync操作,最多丟失1秒鐘的數據授艰;
- AOF日志文件沒有任何磁盤尋址的開銷诗宣,寫入性能非常高,文件不容易破損想诅;
- AOF日志文件即使過大的時候召庞,出現后臺重寫操作,也不會影響客戶端的讀寫来破;
- AOF日志文件的命令通過非忱鹤疲可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復徘禁。比如某人不小心用flushall命令清空了所有數據诅诱,只要這個時候后臺rewrite還沒有發(fā)生,那么就可以立即拷貝AOF文件送朱,將最后一條flushall命令給刪了娘荡,然后再將該AOF文件放回去,就可以通過恢復機制驶沼,自動恢復所有數據炮沐。
缺點:
- 對于同一份數據來說,AOF日志文件通常比RDB數據快照文件更大回怜;
- AOF開啟后大年,支持的寫QPS會比RDB支持的寫QPS低,因為AOF一般會配置成每秒fsync一次日志文件,當然翔试,每秒一次fsync轻要,性能也還是很高的;
RDB和AOF對比
要根據自己的需求自行配置垦缅;
命令 | RDB | AOF |
---|---|---|
啟動優(yōu)先級 | 低 | 高 |
體積 | 小 | 大 |
恢復速度 | 快 | 慢 |
數據安全性 | 丟數據 | 根據策略而定 |
輕重 | 重 | 輕 |