2 RDB(Redis database)- 全量寫入
Redis Server在有多db 中存儲的K.V可了解為Redis的一個狀态。當發生寫操作時,Redis就會從一個狀态切換到另外一個狀态。
基于全量的持久化就是在某個時刻,将Redis的所有資料持久化到硬碟中,形成一個快照。快照,顧名思義可以了解為拍照一樣,把整個記憶體資料映射到硬碟中,儲存一份到硬碟,是以恢複資料起來比較快,把資料映射回去即可,不像 AOF,一條條的執行操作指令。
當Redis 重新開機時,通過加載最近一個快照資料,可以将 Redis 恢複至最近一次持久化狀态上。
快照是預設的持久化方式。這種方式是就是将記憶體中資料以快照的方式寫入到二進制檔案中,預設的檔案名為 dump.rdb。
2.1 觸發方式
save
- 用戶端顯示觸發
- 或用戶端發送 shutdown 指令,系統會先執行 save 指令阻塞用戶端,然後關閉伺服器
save本身是
單線程串行
方式執行,是以當資料量大時,可能會發生Redis Server的長時間卡頓。
其備份期間其他指令全部阻塞,無法執行,是以備份時期
資料的狀态始終一緻
。
若存在老的RDB檔案,則新的會替換老的,時間複雜度O(N)。
設定 redis.conf
再使用腳本初始化 500w 資料,等待後發現已經落盤:
bgsave
bgsave 可由
- 用戶端顯式觸發
- 配置定時任務觸發
- 當有主從架構時,從伺服器向主伺服器發送 sync 指令來執行複制操作時,主伺服器會執行 bgsave
bgsave指令在執行時,會fork一個子程序。子程序送出完成後,會立即給用戶端傳回響應,備份操作在背景異步執行,期間不會影響Redis的正常響應。
對于bgsave來說,當父程序Fork完子程序之後,異步任務會将目前的記憶體狀态作為一個版本進行複制。在複制過程中産生的變更,不會反映在這次備份當中。
不用指令,而使用配置
在Redis的預設配置中,當滿足下面任一條件,會自動觸發 bgsave 的執行:
bgsave相對于save的優勢是
異步執行
,不影響後續指令執行。但Fork子程序,涉及父程序的記憶體複制,會增加伺服器記憶體開銷。
當記憶體開銷高到使用虛拟記憶體時,bgsave的Fork子程序會阻塞運作
,可能會造成秒級不可用。是以使用bgsave需要保證伺服器空閑記憶體足夠。
2.2 RDB執行流程
rdb.c檔案執行流程:
2.3 RDB 最佳配置
關閉自動RDB:
dbfilename dump-${port}.rdb
dir /redisDataPath
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
需要注意的觸發時機
- 主從複制時機的全量複制,master節點會執行bgsave
- debug reload
- shutdown
- flushDB 、 flushAll
2.4 RDB性質
- RDB是Redis記憶體到硬碟的快照,用于持久化
- save通常會阻塞Redis
- bgsave不會阻塞Redis,但會fork新程序
- save自動配置滿足任一就會被執行
2.5 RDB 優點
-
緊湊壓縮的二進制檔案
RDB會生成多個資料檔案,每個檔案都代表了某時刻Redis中的所有資料,這種方式非常适合做冷備。可将這種完整資料檔案發送到雲伺服器存儲,比如ODPS分布式存儲,以預定好的備份政策來定期備份Redis中的資料
-
fork子程序性能最大化
RDB對Redis對外提供的讀寫服務,影響非常小,可讓Redis保持高性能,因為Redis主程序隻要fork一個子程序,讓子程序執行RDB
-
啟動效率高
相對于AOF,直接基于RDB檔案重新開機和恢複Redis程序,更加快速
2.6 RDB缺點
耗時
O(n)
寫時複制(copy-on-write)
耗記憶體,copy-on-write政策。RDB每次在fork子程序來執行RDB快照資料檔案生成的時候,如果資料檔案特别大,可能會導緻對用戶端提供的服務暫停數毫秒,或者甚至數秒。
執行 fork 時,os會使用寫時複制,即 fork 函數發生的一刻父子程序共享同一記憶體資料。當父程序要更改其中某片資料時(如執行一個寫指令),os會将該片資料複制一份以保證子程序資料不受影響,是以新的 RDB 檔案存儲的是執行 fork 一刻的記憶體資料。
不可控
容易丢失資料。一般RDB每隔5分鐘,或者更長時間生成一次,若過程中Redis當機,就會丢失最近未持久化的資料
2.7 恢複流程
當Redis重新啟動時,會從本地磁盤加載之前持久化的檔案。當恢複完成之後,再受理後續的請求操作。
4 選型及最佳實踐
混合持久化
Redis 4.0 開始支援 RDB 和 AOF 的混合持久化(預設關閉,通過配置項
aof-use-rdb-preamble
開啟)。
如果把混合持久化打開,AOF 重寫時就直接把 RDB 内容寫到 AOF 檔案開頭:
- 好在可以結合 RDB 和 AOF 的優點, 快速加載同時避免丢失過多資料
- 但是,AOF 裡的 RDB 部分就是壓縮格式不再是 AOF 格式,可讀性較差
RDB最佳政策
- 關閉
- 集中手動管理RDB操作
- 在從節點打開自動執行配置,但是不宜頻繁執行RDB
AOF最佳政策
- 建議打開,但是如果隻是純作為緩存使用可不開
- AOF重寫集中管理
- everysec
抉擇RDB & AOF
不要僅使用RDB,因為那樣會導緻丢失很多資料
也不要僅使用AOF,因為那樣有兩個問題
你通過AOF做冷備,沒有RDB做冷備,來的恢複速度更快
RDB每次簡單粗暴生成資料快照,更加健壯,可以避免AOF這種複雜的備份和恢複機制的bug
綜合使用AOF和RDB
用AOF保證資料不丢失,作為資料恢複的第一選擇
用RDB做不同程度的冷備,在AOF檔案都丢失或損壞不可用時,還可使用RDB快速實作資料恢複
一些最佳實踐
-
小分片
例如設定maxmemory參數設定每個redis隻存儲4個G的空間,這樣各種操作都不會太慢
- 監控(硬碟、記憶體、負載、網絡)
- 足夠的記憶體
參考
- https://redis.io/topics/persistence
- 《Redis設計與實作》