本篇重點
“對哪些數據做快照?”——關係到快照的執行效率問題
“做快照時,數據還能被增刪改嗎?”——關係到Redis主線程是否被阻塞,同時是否正常處理請求
前言
RDB: Redis DataBase,記錄Redis運行中某一時刻的內存數據
1. 對哪些數據做快照?——全量快照 vs 增量快照
- 全量快照——把內存中的所有數據都記錄到磁盤中
- 增量快照——只對一段時間內修改的數據記錄快照
2. 全量快照
- 生成RDB文件的方式
- save:主線程執行RDB,會導致主線程阻塞
- bgsave:默認配置,創建子進程專門寫RDB文件
- 全量快照在數據量較大時的表現
- 內存數據量\(\uparrow\),fork時間開銷\(\uparrow\),阻塞主線程風險\(\uparrow\)
- 頻繁寫全量,磁盤壓力\(\uparrow\),多個RDB競爭帶寬,容易導致“前一個RDB沒完,後一個RDB又開始的惡性循環”
使用增量快照代替頻繁的全量快照可以有效控制數據量較大時帶來的各種性能問題。
但增量快照本身有一個致命的空間消耗:需要 “記住”某一時間段內修改過的所有數據
3. 快照時數據能否修改?即寫操作是否可正常執行
- 可以,藉助OS的 “寫時複製”技術(Copy-On-Write,COW)
- 操作:
- bgsave子進程RDB時,主線程正常執行讀操作
- 對於寫操作,則bgsave依舊將原先數據寫盤,主線程生成該數據的副本,在副本上修改數據
- bgsave子進程RDB時,主線程正常執行讀操作
- 寫時複製保證快照期間數據可修改
4. 推薦持久化方案:AOF+RDB
RDB以一定的頻率執行全量快照,兩次RDB之間,使用AOF日誌記錄這段時間內的命令操作
- 既能有效防止兩次RDB之間,系統宕機導致的數據丟失
- 又能避免頻繁RDB導致的fork開銷增加阻塞主線程
- 同時,AOF日誌僅記錄兩次RDB間隔之間的操作,下次記錄時會清空本次原有AOF日誌,避免AOF重寫的額外開銷
5. 不同場景下AOF和RDB的選擇
- 數據不能丟失:RDB+AOF
- 允許min級別的數據丟失:RDB
- 若只用AOF,則優先使用Everysec寫盤策略
圖片來源於極客時間專欄《Redis核心技術與實戰》