持久化簡介
利用永久性存儲介質將數據進行保存,在特定的事件將保存的數據進行恢復的工作機制稱爲持久化
也就是說,把內存中的數據寫到磁盤中去,防止服務宕機,內存數據丟失。
爲什麼要持久化
防止數據的意外丟失,確保數據安全性
持久化的過程保存什麼
- 將當前數據狀態進行保存,快照形式,存儲數據結果,存儲而是簡單,關注點在數據 -----》 RDB
- 將數據的操作過程進行保存,日誌形式,存儲操作過程,存儲格式複雜,關注點在數據的操作過程 ------》AOF
RDB(Redis DataBase)
誰,什麼事件,幹什麼事情?
- 誰:redis操作者(用戶)
- 什麼時間:即時(隨時進行)
- 幹什麼事情:保存數據
RDB的啓動方式——save指令
- 命令
save
- 作用
手動執行一次保存操作
RDB啓動方式——save指令相關配置
- dbfilename dump.rdb
說明:設置本地數據庫文件名,默認值爲dump.rdb
經驗:通常設置魏dump-端口號.rdb - dir
說明:設置存儲.rdb文件的路徑
經驗:通常設置成存儲空間較大的目錄中,目錄名稱data - rdbcompression yes
說明:設置存儲至本地數據庫時是否壓縮數據,默認爲yes,採用LZF壓縮
經驗:通常默認爲開啓狀態,如果設置成no,可以節省CPU運行時間,但會使存儲的文件變大(巨大) - rdbchecksumy yes
說明:設置是否進行RDB文件格式的校驗,該校驗過程在寫文件和讀文件過程均進行
經驗:通常默認爲開啓狀態,如果設置爲no,可以節約讀寫性過程約10%時間消耗,但是存儲一定的數據損壞風險
注意:Redis是單線程的,所有命令都會在類似隊列中排好隊,不建議使用save指令,因爲save指令的執行會阻塞當前Redis服務器,直到當前RDB過程完成位置,有可能會造成長時間阻塞,線上環境不建議使用
數據量過大,單線程執行方式造成效率過低如何處理?
後臺執行
- 誰:redis操作者(用戶)發起指令;redis服務器控制指令執行
- 什麼時間:即時(發起);合理時間(執行)
- 幹什麼事情:保存數據
RDB啓動方式——bgsave指令
- 命令
bgsave
- 作用
手動啓動後臺保存操作,但不是立即執行
RDB啓動方式——bgsave指令工作原理
注意:bgsave命令是針對save阻塞問題做的優化。Redis內部所有涉及到RDB操作都採用bgsave的方式,save命令可以放棄使用
RDB啓動方式——bgsave指令相關配置
以下跟save配置相同
新增
- stop-writes-on-bgsave-error yes
說明:後臺存儲過程中如果出現錯誤線程,是否停止保存操作
經驗:通常默認爲開啓狀態
到目前位置,save和bgsave都是手動的保存指令,那麼會引入以下問題
反覆執行保存命令,忘記了怎麼辦?不知道數據產生了多少變化,何時保存?
自動執行
- 誰:redis服務器發起指令(基於條件)
- 什麼時間:滿足條件
- 幹什麼事情:保存數據
RDB啓動方式——save配置
- 配置
save second changes
- 作用
滿足限定時間範圍內ke的變化數量達到指定數量即進行持久化(但是要注意,除了查詢指令外,增刪改達到次數會自動進行持久化) - 參數
second:監控時間範圍
changes:監控key的變化量 - 位置
在conf文件中進行配置 - 範例
RDB啓動方式——save配置原理
注意:
save配置要根據實際業務情況進行設置,頻度過高或過低都會出現性能問題,結果可能是災難性的
save配置中對second與changes設置通常具有互補對應關係,儘量不要設置成包含性關係
save配置啓動後執行的是bgsave操作
RDB三種啓動方式對比
rdb特殊啓動形式
- 全量複製
在主從複製中會提到 - 服務器運行過程中重啓
debug reload - 關閉服務器時指定保存數據
shutdown save
RDB 優缺點
- RDB是一個緊湊壓縮的二進制文件,存儲效率較高
- RDB內部存儲的是redis在某個時間點的數據快照,非常適合用於數據備份,全量複製等場景
- RDB恢復數據的速度要比AOF快很多
- 應用:服務器中每X小時執行bgsave備份,並將RDB文件拷貝到遠程己氣中,用於災難恢復
RDB缺點
- RDB方式無論是執行指令還是利用配置,無法做到實時持久化,具體較大的可能性丟失數據
- bgsave指令每次運行要執行fork操作創建子進程,要犧牲掉一些性能
- Redis的衆多版本中未進行RDB文件格式的版本統一,有可能出現個版本服務之間數據格式無法兼容現象
RDB存儲的弊端
- 存儲數據量較大,效率較低——基於快照思想,每次讀寫都是全部數據,當數據量巨大時,效率非常低
- 大數據量下的IO性能較低
- 基於fork創建子進程,內存產生額外消耗
- 宕機帶來的數據丟失風險
解決思路
- 不寫全數據,僅記錄部分數據
- 改記錄數據爲記錄操作過程
- 對所有操作均進行記錄,排除丟失數據的風險
- 這也就是AOF的引入
AOF
概念
- AOF持久化:以獨立日誌的方式記錄每次寫命令,重啓時再重新執行AOF文件中命令達到恢復數據的目的。與RDB相比可以簡單描述爲改記錄數據產生的過程
- AOF的主要作用是解決了數據持久化的實時性,目前已經是Redis持久化的主流方式
AOF寫數據過程
AOF寫數據三種策略
- always(每次)
每次寫入操作均同步到AOF文件中,數據零誤差,性能較低 - everysec(每秒)
每秒將緩衝區中的指令同步到AOF文件中,數據準確性高,性能較高
再系統突然當即的情況下丟失1秒內的數據 - no(系統控制)
由操作系統每次同步到AOF文件的週期,整體過程不可控
- 配置
appendonly yes|no
- 作用
是否開啓APF持久化功能,默認爲不開啓 - 配置
appendfsync always|everysec|no
- 作用
AOF寫數據策略
AOF相關配置
- 配置
appendfilename filename
- 作用
AOF持久化文件名,默認文件名爲appendonly.aof,建議配置爲appendonly-端口號.aof - 配置
dir
- 作用
AOF持久化文件保存路徑,與RDB持久化文件保持一致即可
AOF寫數據遇到的問題
如果連續執行如下指令該如何處理
AOF重寫
隨着命令的不斷寫入AOF,文件會越來越大(AOF引發的問題),爲了解決這個問題,Redis引入AOF重寫機制壓縮文件體積,AOF文件重寫是將Redis進程內的數據轉換爲寫命令同步到新AOF文件的過程,簡單說就是將同樣一個數據的若干個命令執行結果轉換爲最終結果數據對應的指令進行記錄。
AOF重寫作用
- 降低磁盤佔用量,提高磁盤利用路
- 提高持久化效率,降低持久化寫時間,提高IO性能
- 降低數據恢復用時,提高數據恢復效率
AOF重寫規則
- 進程內已超時的數據不再寫入文件
- 忽略無效指令,重寫時使用進程內數據直接生成,這樣新的AOF文件只保留最終數據的寫入命令
如del key1,hdel key2,srem key3,set key 222等 - 對統一數據的多條命令合併爲一條命令
如 lpush list1 a ,lpush list1 b,lpush list1 c可以轉化爲lpush list1 a b c
爲防止數據量過大造成客戶端緩衝區溢出,對list,set,hash,set等類型,每條指令最多寫入64個元素
AOF重寫方式
- 手動重寫(操作完之後直接命令行輸入)
bgrewriteaof
- 自動重寫
auto-aof-rewrite-min-size size
auto-aof-rewrite-percentage percentage // (aof_current_size - aof_base_size) / aof_base_size >= percentage時觸發重寫,在Redis命令行中輸入info可以查看當前的aof_current_size和aof_base_size
AOF自動重寫方式
- 自動重寫觸發條件設置
auto-aof-rewrite-min-size
auto-aof-rewrite-percentage percent
- 自動重寫觸發對比參數(運行指令info Persistence獲取具體信息)
aof_current_size
aof_base_size
- 自動重寫觸發條件
AOF和RDB的區別
RDB和AOF的選擇之感
- 對數據非常敏感,建議使用默認的AOF持久化方案
AOF持久化策略使用erverysecond,每秒鐘fsync一次。該策略redis任然可以保持很好的處理性能,當出現問題時,最多丟失0-1秒中的數據。
注意:由於AOF文件存儲體積較大,且恢復數據較慢 - 數據呈現階段有效性,建議使用RDB持久化方案
數據可以良好的做到階段內無丟失(該階段是開發者或運維人工手工維護的),且恢復速度較快,階段點數據恢復通常採用RDB方案
注意:利用RDB實現緊湊的數據持久化會使Redis降得很低 - 綜合對比
- RDB與AOF得選擇實際上是在做一種權衡,每種都有利弊
- 如不能承受數分鐘以內得數據丟失,對業務數據非常敏感,選用AOF
- 如能承受數分鐘以內數據丟失,且追求大數據集得恢復速度,選用RDB
災難恢復選用RDB - 雙保險策略,同時開啓RDB和AOF,重啓後,Redis優先使用AOF來恢復數據,降低丟失數據的量
持久化應用場景