Redis 有兩種持久化的方式: 快照 (RDB文件) 和追加式文件 (AOF文件):redis
fork()
, 產生一個子進程.默認 Redis 會把快照文件存儲爲當前目錄下一個名爲 dump.rdb
的文件. 要修改文件的存儲路徑和名稱, 能夠經過修改配置文件 redis.conf
實現:安全
# RDB文件名,默認爲dump.rdb。 dbfilename dump.rdb # 文件存放的目錄,AOF文件一樣存放在此目錄下。默認爲當前工做目錄。 dir ./
你能夠配置保存點, 使 Redis 若是在每 N 秒後數據發生了 M 次改變就保存快照文件. 例以下面這個保存點配置表示每 60 秒, 若是數據發生了 1000 次以上的變更, Redis就會自動保存快照文件:服務器
save 60 1000
保存點能夠設置多個, Redis 的配置文件就默認設置了 3 個保存點:app
# 格式爲:save <seconds> <changes> # 能夠設置多個。 save 900 1 #900秒後至少1個key有變更 save 300 10 #300秒後至少10個key有變更 save 60 10000 #60秒後至少10000個key有變更
若是想禁用快照保存的功能, 能夠經過註釋掉全部 "save" 配置達到,或者在最後一條 "save" 配置後添加以下的配置:性能
save ""
默認狀況下, 若是 Redis 在後臺生成快照的時候失敗, 那麼就會中止接收數據, 目的是讓用戶能知道數據沒有持久化成功.spa
可是若是你有其餘的方式能夠監控到 Redis 及其持久化的狀態, 那麼能夠把這個功能禁止掉.3d
stop-writes-on-bgsave-error yes
默認 Redis 會採用 LZF
對數據進行壓縮.code
若是你想節省點 CPU 的性能, 你能夠把壓縮功能禁用掉, 可是數據集就會比沒壓縮的時候要大.blog
rdbcompression yes
從版本 5 的 RDB 的開始, 一個 CRC64 的校驗碼會放在文件的末尾. 這樣更能保證文件的完整性, 可是在保存或者加載文件時會損失必定的性能 (大概10%).生命週期
若是想追求更高的性能, 能夠把它禁用掉, 這樣文件在寫入校驗碼時會用 0 替代, 加載的時候看到 0 就會直接跳過校驗.
rdbchecksum yes
Redis 提供了兩個命令用於手動生成快照.
BGSAVE
命令使用後臺的方式保存 RDB 文件, 調用此命令後, 會馬上返回OK
.
Redis 會產生一個子進程進行快照寫入硬盤. 父進程繼續處理命令請求.
SAVE
命令會使用同步的方式生成 RDB 快照文件, 這意味着在這個過程當中會阻塞全部其餘客戶端的請求.
所以不建議在生產環境使用這個命令.
重點
save 60 1000
, 那麼從 Redis 最近一次建立快照以後開始算起. 當條件被知足時, 就會自動出發 BGSAVE
命令. 若是有多個 save
配置, 那麼當任意一個被知足時, 都會出發一次 BGSAVE
命令.SHUTDOWN
命令, 來關閉服務時, 或者接收到標準 TERM
信號時, 會執行一次 SAVE
命令, 阻塞全部客戶端, 而且執行完畢後會關閉 Redis 服務.
這裏注意的是 fork
操做會阻塞, 致使 Redis 讀寫性能降低. 咱們能夠控制單個 Redis 實例的最大內存, 來儘量下降 Redis 在 fork
時的事件消耗. 以及上面提到的自動觸發的頻率減小 fork
次數, 或者使用手動觸發, 根據本身的機制來完成持久化.
快照並非很可靠. 若是你的電腦忽然宕機了, 或者電源斷了, 又或者不當心殺掉了進程, 那麼最新的數據就會丟失.
而 AOF 文件則提供了一種更爲可靠的持久化方式. 每當 Redis 接受到會修改數據集的命令時, 就會把命令追加到 AOF 文件裏, 當你重啓 Redis 時, AOF 裏的命令會被從新執行一次, 重建數據.
把配置項 appendonly
設爲 yes
:
appendonly yes
# 文件存放目錄,與RDB共用。默認爲當前工做目錄。 dir ./ # 默認文件名爲appendonly.aof appendfilename "appendonly.aof"
你能夠配置 Redis 調用 fsync
的頻率, 有三個選項:
fsync
. 速度最慢, 最安全.fsync
一次. 速度快 (2.4版本跟快照方式速度差很少), 安全性不錯 (最多丟失 1 秒的數據).fsync
, 交由系統去處理. 這個方式速度最快, 可是安全性通常.推薦使用每秒 fsync 一次的方式 (默認的方式), 由於它速度快, 安全性也不錯. 相關配置以下:
# appendfsync always appendfsync everysec # appendfsync no
對於增量追加到文件這一步主要的流程是: 命令寫入=》追加到 aof_buf =》同步到aof磁盤. 那麼這裏爲何要先寫入 buf 在同步到磁盤呢? 若是實時寫入磁盤會帶來很是高的磁盤IO, 影響總體性能.
AOF 重寫是爲了減小 AOF 文件的大小, 隨着寫操做的不斷增長, AOF 文件會愈來愈大. 例如你遞增一個計數器 100 次, 那麼最終結果就是數據集裏的計數器的值爲最終的遞增結果, 可是 AOF 文件裏卻會把這 100 次操做完整的記錄下來.
而事實上要恢復這個記錄, 只須要 1 個命令就好了, 也就是說 AOF 文件裏那 100 條命令其實能夠精簡爲 1 條. 因此 Redis 支持這樣一個功能: 在不中斷服務的狀況下在後臺重建 AOF 文件.
對於上圖有四個關鍵點補充一下:
經過上面的分析, 咱們都知道 RDB 的快照、AOF的重寫都須要 fork
, 這是一個重量級操做, 會對 Redis 形成阻塞. 所以爲了避免影響 Redis 主進程響應, 咱們須要儘量下降阻塞.
fork
的頻率, 好比能夠手動來觸發 RDB 生成快照、與AOF重寫;fork
耗時過長;fork
失敗.在線上咱們到底該怎麼作? 我提供一些本身的實踐經驗.