Redis爲持久化提供了兩種方式:redis
本文將經過下面內容的介紹,但願可以讓你們更全面、清晰的認識這兩種持久化方式,同時理解這種保存數據的思路,應用於本身的系統設計中。shell
爲了使用持久化的功能,咱們須要先知道該如何開啓持久化的功能。安全
# 時間策略 save 900 1 save 300 10 save 60 10000 # 文件名稱 dbfilename dump.rdb # 文件保存路徑 dir /home/work/app/redis/data/ # 若是持久化出錯,主進程是否中止寫入 stop-writes-on-bgsave-error yes # 是否壓縮 rdbcompression yes # 導入時是否檢查 rdbchecksum yes
配置其實很是簡單,這裏說一下持久化的時間策略具體是什麼意思。服務器
save 900 1
表示900s內若是有1條是寫入命令,就觸發產生一次快照,能夠理解爲就進行一次備份save 300 10
表示300s內有10條寫入,就產生快照下面的相似,那麼爲何須要配置這麼多條規則呢?由於Redis每一個時段的讀寫請求確定不是均衡的,爲了平衡性能與數據安全,咱們能夠自由定製什麼狀況下觸發備份。因此這裏就是根據自身Redis寫入狀況來進行合理配置。app
stop-writes-on-bgsave-error yes
這個配置也是很是重要的一項配置,這是當備份進程出錯時,主進程就中止接受新的寫入操做,是爲了保護持久化的數據一致性問題。若是本身的業務有完善的監控系統,能夠禁止此項配置, 不然請開啓。運維
關於壓縮的配置 rdbcompression yes
,建議沒有必要開啓,畢竟Redis自己就屬於CPU密集型服務器,再開啓壓縮會帶來更多的CPU消耗,相比硬盤成本,CPU更值錢。性能
固然若是你想要禁用RDB配置,也是很是容易的,只須要在save的最後一行寫上:save ""
spa
# 是否開啓aof appendonly yes # 文件名稱 appendfilename "appendonly.aof" # 同步方式 appendfsync everysec # aof重寫期間是否同步 no-appendfsync-on-rewrite no # 重寫觸發配置 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 加載aof時若是有錯如何處理 aof-load-truncated yes # 文件重寫策略 aof-rewrite-incremental-fsync yes
仍是重點解釋一些關鍵的配置:debug
appendfsync everysec
它其實有三種模式:設計
通常狀況下都採用 everysec 配置,這樣能夠兼顧速度與安全,最多損失1s的數據。
aof-load-truncated yes
若是該配置啓用,在加載時發現aof尾部不正確是,會向客戶端寫入一個log,可是會繼續執行,若是設置爲 no
,發現錯誤就會中止,必須修復後才能從新加載。
關於原理部分,咱們主要來看RDB與AOF是如何完成持久化的,他們的過程是如何。
在介紹原理以前先說下Redis內部的定時任務機制,定時任務執行的頻率能夠在配置文件中經過 hz 10
來設置(這個配置表示1s內執行10次,也就是每100ms觸發一次定時任務)。該值最大可以設置爲:500,可是不建議超過:100,由於值越大說明執行頻率越頻繁越高,這會帶來CPU的更多消耗,從而影響主進程讀寫性能。
定時任務使用的是Redis本身實現的 TimeEvent,它會定時去調用一些命令完成定時任務,這些任務可能會阻塞主進程致使Redis性能降低。所以咱們在配置Redis時,必定要總體考慮一些會觸發定時任務的配置,根據實際狀況進行調整。
在Redis中RDB持久化的觸發分爲兩種:本身手動觸發與Redis定時觸發。
針對RDB方式的持久化,手動觸發可使用:
而自動觸發的場景主要是有如下幾點:
save m n
配置規則自動觸發;bgsave
;debug reload
時;shutdown
時,若是沒有開啓aof,也會觸發。因爲 save
基本不會被使用到,咱們重點看看 bgsave
這個命令是如何完成RDB的持久化的。
這裏注意的是 fork
操做會阻塞,致使Redis讀寫性能降低。咱們能夠控制單個Redis實例的最大內存,來儘量下降Redis在fork時的事件消耗。以及上面提到的自動觸發的頻率減小fork次數,或者使用手動觸發,根據本身的機制來完成持久化。
AOF的整個流程大致來看能夠分爲兩步,一步是命令的實時寫入(若是是 appendfsync everysec
配置,會有1s損耗),第二步是對aof文件的重寫。
對於增量追加到文件這一步主要的流程是:命令寫入=》追加到aof_buf =》同步到aof磁盤。那麼這裏爲何要先寫入buf在同步到磁盤呢?若是實時寫入磁盤會帶來很是高的磁盤IO,影響總體性能。
aof重寫是爲了減小aof文件的大小,能夠手動或者自動觸發,關於自動觸發的規則請看上面配置部分。fork的操做也是發生在重寫這一步,也是這裏會對主進程產生阻塞。
手動觸發: bgrewriteaof
,自動觸發 就是根據配置規則來觸發,固然自動觸發的總體時間還跟Redis的定時任務頻率有關係。
下面來看看重寫的一個流程圖:
對於上圖有四個關鍵點補充一下:
不能是RDB仍是AOF都是先寫入一個臨時文件,而後經過
rename
完成文件的替換工做。
數據的備份、持久化作完了,咱們如何從這些持久化文件中恢復數據呢?若是一臺服務器上有既有RDB文件,又有AOF文件,該加載誰呢?
其實想要從這些文件中恢復數據,只須要從新啓動Redis便可。咱們仍是經過圖來了解這個流程:
啓動時會先檢查AOF文件是否存在,若是不存在就嘗試加載RDB。那麼爲何會優先加載AOF呢?由於AOF保存的數據更完整,經過上面的分析咱們知道AOF基本上最多損失1s的數據。
經過上面的分析,咱們都知道RDB的快照、AOF的重寫都須要fork,這是一個重量級操做,會對Redis形成阻塞。所以爲了避免影響Redis主進程響應,咱們須要儘量下降阻塞。
在線上咱們到底該怎麼作?我提供一些本身的實踐經驗。
本文的內容主要是運維上的一些注意點,但咱們開發者瞭解到這些知識,在某些時候有助於咱們發現詭異的bug。接下來會介紹Redis的主從複製與集羣的知識。