1、Redis的持久化方式
1.1、redis為了防止數(shù)據(jù)丟失以及服務(wù)重啟時能夠恢復(fù)數(shù)據(jù),Redis支持?jǐn)?shù)據(jù)的持久化,主要分為兩種方式,分別是RDB和AOF。
1.2、Redis 支持的持久化機(jī)制 有三種:
1、RDB(Redis DataBase)持久化
2、AOF(Append Only File)持久化
3、RDB-AOF 混合持久化
1.3、Redis 默認(rèn)有 16 個數(shù)據(jù)庫,分別是 DB0 ~ DB15。
2、RDB
RDB持久化是把當(dāng)前進(jìn)程數(shù)據(jù)生成快照保存到磁盤上的過程,由于是某一時刻的快照,那么快照中的值要早于或者等于內(nèi)存中的值。
生成的rdb文件的名稱以及存儲位置由redis.conf中的dbfilename和dir兩個參數(shù)控制,默認(rèn)生成的rdb文件是dump.rdb。
2.1、觸發(fā)方式
觸發(fā)rdb持久化的方式有2種,分別是手動觸發(fā)和自動觸發(fā)。
手動觸發(fā)
redis客戶端執(zhí)行save命令和bgsave命令都可以觸發(fā)rdb持久化,但是兩者還是有區(qū)別的。
1.使用save命令時是使用redis的主進(jìn)程進(jìn)行持久化,此時會阻塞redis服務(wù),造成服務(wù)不可用直到持久化完成,線上環(huán)境不建議使用;
2.bgsave命令是fork一個子進(jìn)程,使用子進(jìn)程去進(jìn)行持久化,主進(jìn)程只有在fork子進(jìn)程時會短暫阻塞,fork操作完成后就不再阻塞,主進(jìn)程可以正常進(jìn)行其他操作。
3.bgsave是針對save阻塞主進(jìn)程所做的優(yōu)化,后續(xù)所有的自動觸發(fā)都是使用bgsave進(jìn)行操作。
自動觸發(fā)
在以下4種情況時會自動觸發(fā)
1、redis.conf中配置save m n,即在m秒內(nèi)有n次修改時,自動觸發(fā)bgsave生成rdb文件;
2、主從復(fù)制時,從節(jié)點要從主節(jié)點進(jìn)行全量復(fù)制時也會觸發(fā)bgsave操作,生成當(dāng)時的快照發(fā)送到從節(jié)點;
3、執(zhí)行debug reload命令重新加載redis時也會觸發(fā)bgsave操作;
4、默認(rèn)情況下執(zhí)行shutdown命令時,如果沒有開啟aof持久化,那么也會觸發(fā)bgsave操作;
配置示例:
save 900 1
save 300 10
save 60 10000
配置分別表示:
900秒(15分鐘)內(nèi)有1個更改
300秒(5分鐘)內(nèi)有10個更改
60秒內(nèi)有10000個更改
2.2、bgsave 命令的執(zhí)行流程:
1、若父進(jìn)程存在正在執(zhí)行的子進(jìn)程,直接返回
2、fork 操作(創(chuàng)建子進(jìn)程) 執(zhí)行過程中,父進(jìn)程進(jìn)入阻塞狀態(tài)
3、fork 操作 完成后,父進(jìn)程繼續(xù)響應(yīng)其他命令
4、創(chuàng)建 “.rdb” 文件,并存儲 父進(jìn)程內(nèi)存中的數(shù)據(jù)
5、父進(jìn)程 得到通知,以新的 “.rdb” 文件 替換舊的 “.rdb” 文件

2.3、bgsave 命令的原理:COW(Copy On Write)
在 Linux 操作系統(tǒng)中,可以通過 glibc庫 中的 fork 函數(shù) 創(chuàng)建一個子進(jìn)程,該進(jìn)程與父進(jìn)程完全相同,并且共享 父進(jìn)程 的內(nèi)存空間
當(dāng) 父進(jìn)程 或 子進(jìn)程 需要修改內(nèi)存中的數(shù)據(jù)時,會將對應(yīng)的 page 進(jìn)行復(fù)制,然后對副本進(jìn)行修改

2.4、RDB 的優(yōu)缺點:
優(yōu)點
RDB文件是某個時間節(jié)點的快照,默認(rèn)使用LZF算法進(jìn)行壓縮,壓縮后的文件體積遠(yuǎn)遠(yuǎn)小于內(nèi)存大小,適用于備份、全量復(fù)制等場景;
Redis加載RDB文件恢復(fù)數(shù)據(jù)要遠(yuǎn)遠(yuǎn)快于AOF方式;
缺點
RDB方式實時性不夠,無法做到秒級的持久化;
每次調(diào)用bgsave都需要fork子進(jìn)程,fork子進(jìn)程屬于重量級操作,頻繁執(zhí)行成本較高;
RDB文件是二進(jìn)制的,沒有可讀性,AOF文件在了解其結(jié)構(gòu)的情況下可以手動修改或者補(bǔ)全;
版本兼容RDB文件問題;
3、AOF
3.1、AOF介紹
aof方式持久化是使用文本協(xié)議將每次的寫命令記錄到aof文件中,經(jīng)過文件重寫后記錄最終的數(shù)據(jù)生成命令,在redis啟動時,通過執(zhí)行aof文件中的命令恢復(fù)數(shù)據(jù)。
aof方式主要解決了數(shù)據(jù)實時性持久化的問題,aof方式對于兼顧數(shù)據(jù)安全性和性能非常有幫助。
說明:
目前 Redis 持久化 的主流方式(解決了數(shù)據(jù)持久化的實時性)?
以 獨立日志 的方式,記錄了每次寫入的命令
生成一個 文本協(xié)議格式 的 文本文件(文件后綴為 “.aof”)
3.2AOD的啟用
AOF 默認(rèn)不開啟,需要修改配置項來啟動它:
appendonly yes # 啟動?
aofappendfilename "appendonly.aof" # 設(shè)置文件名
注:AOF 保存的默認(rèn)文件是 appendonly.aof
3.3、AOF可以配置三種刷盤策略:
appendfsync always:每次執(zhí)行寫命令都會刷盤,非常慢,也非常安全。
appendfsync everysec:每秒刷盤一次,兼顧性能和安全。
appendfsync no:將刷盤操作交給系統(tǒng),很快,不安全。
推薦使用everysec,該策略下,最多會丟1秒的數(shù)據(jù)。
3.4、配置示例
打開配置文件,追加配置如下即可AOF配置。
vim /data/db/redis/6379/redis.conf
appendonly yes
appendfsync everysec
示例:
root@db01:/data/db/redis/6379# cat /data/db/redis/6379/redis.confdaemonize yes? ?
port 6379
bind 172.21.209.40? 127.0.0.1? ?
logfile /data/db/redis/6379/redis.log
dir /data/db/redis/6379/
dbfilename dump.rdb
requirepass 123456?
##RDB的配置
save 900 1
save 300 10
save 60 10000
##AOF的配置
appendonly yes
appendfsync everysec
4、兩種方式對比

5、Redis混合持久化
重啟 Redis 時,我們很少使用 RDB來恢復(fù)內(nèi)存狀態(tài),因為會丟失大量數(shù)據(jù)。我們通常使用 AOF 日志重
放,但是重放 AOF 日志性能相對 RDB來說要慢很多,這樣在 Redis 實例很大的情況下,啟動需要花費(fèi)很
長的時間。 Redis 4.0 為了解決這個問題,帶來了一個新的持久化選項——混合持久化。
通過如下配置可以開啟混合持久化(必須先開啟aof):
# aof‐use‐rdb‐preamble yes
如果開啟了混合持久化,AOF在重寫時,不再是單純將內(nèi)存數(shù)據(jù)轉(zhuǎn)換為RESP命令寫入AOF文件,而是將重寫這一刻之前的內(nèi)存做RDB快照處理,并且將RDB快照內(nèi)容和增量的AOF修改內(nèi)存數(shù)據(jù)的命令存在一起,都寫入新的AOF文件,新的文件一開始不叫appendonly.aof,等到重寫完新的AOF文件才會進(jìn)行改名,覆蓋原有的AOF文件,完成新舊兩個AOF文件的替換。
于是在 Redis 重啟的時候,可以先加載 RDB 的內(nèi)容,然后再重放增量 AOF 日志就可以完全替代之前的AOF 全量文件重放,因此重啟效率大幅得到提升。
5.1、混合持久化AOF文件結(jié)構(gòu)如下:

6、Redis數(shù)據(jù)備份策略
1、寫crontab定時調(diào)度腳本,每小時都copy一份rdb或aof的備份到一個目錄中去,僅僅保留最近48
小時的備份。
2、每天都保留一份當(dāng)日的數(shù)據(jù)備份到一個目錄中去,可以保留最近1個月的備份。
3、每次copy備份的時候,都把太舊的備份給刪了。
4、每天晚上將當(dāng)前機(jī)器上的備份復(fù)制一份到其他機(jī)器上,以防機(jī)器損壞。