持久化簡介
持久化一般有兩種思路:
- 將當前數據狀態進行保存,快照形式,存儲數據結果,存儲格式簡單,關注點在數據。
- 將數據的操作過程進行保存,日誌形式,存儲操作過程,存儲格式複雜,關注點在數據的操作過程。
以上兩種思路在redis中分別對應RDB和AOF。
RDB
在redis命令行輸入SAVE
命令就能手動執行一次RDB持久化。但這種前臺啓動的方式會阻塞當前Redis服務器,直到當前RDB過程完成爲止,線上環境不建議使用。實際上redis內部涉及到RDB的操作都是採用bgsave
的方式。
bgsave
既然SAVE
單線程執行方式效率過低,自然想到bgsave
後臺異步執行,該指令執行後redis會調用fork函數生成子進程去創建rdb文件。
但我們每次手動執行bgsave
纔會持久化就很蠢,肯定可以自動化的,需要在配置文件中配置:
save second changes
# 滿足限定時間範圍內key的變化數量達到指定數量即進行持久化
second:監控時間範圍
changes:監控key的變化量
如:
save 900 1
save 300 10
save 60 10000
只要有一個條件滿足,就會執行rdb的文件保存。
# 關閉rdb如下
save ""
RDB相關配置
配置字段 | 說明 |
---|---|
dbfilename dump.rdb | 設置本地數據庫文件名,默認值爲 dump.rdb ,通常設置爲dump-端口號.rdb |
dir | 設置存儲rdb文件的路徑 ,目錄名稱data |
rdbcompression yes | 設置存儲至本地數據庫時是否壓縮數據,默認爲 yes,採用 LZF 壓縮 ,通常默認爲開啓狀態,如果設置爲no,可以節省 CPU 運行時間,但會使存儲的文件變大(巨大) |
rdbchecksum yes | 設置是否進行RDB文件格式校驗,該校驗過程在寫文件和讀文件過程均進行 ,通常默認爲開啓狀態,如果設置爲no,可以節約讀寫性過程約10%時間消耗,但是存儲一定的數據損壞風險 |
stop-writes-on-bgsave-error yes | 後臺存儲過程中如果出現錯誤現象,是否停止保存操作,默認開啓 |
RDB特殊啓動形式
- 全量複製:出現在主從複製中。
- 服務器運行過程中重啓:
debug reload
- 關閉服務器時指定保存數據:
shutdown save
默認情況下執行shutdown命令時,自動執行bgsave(如果沒有開啓AOF持久化功能)。
RDB優點
- RDB是一個緊湊壓縮的二進制文件,存儲效率較高
- RDB內部存儲的是redis在某個時間點的數據快照,非常適合用於數據備份,全量複製等場景
- RDB恢復數據的速度要比AOF快很多
- 應用:服務器中每X小時執行bgsave備份,並將RDB文件拷貝到遠程機器中,用於災難恢復。
RDB缺點
- RDB方式無論是執行指令還是利用配置,無法做到實時持久化,具有較大的可能性丟失數據
- bgsave指令每次運行要執行fork操作創建子進程,內存產生額外消耗
- Redis的衆多版本中未進行RDB文件格式的版本統一,有可能出現各版本服務之間數據格式無法兼容現象
- 基於快照思想,每次讀寫都是全部數據,當數據量巨大時,IO效率非常低
AOF
AOF(append only file)持久化:以獨立日誌的方式記錄每次寫命令,重啓時再重新執行AOF文件中命令達到恢復數據的目的。與RDB相比可以簡單描述爲改記錄數據爲記錄數據產生的過程。AOF的主要作用是解決了數據持久化的實時性,目前已經是Redis持久化的主流方式。
AOF寫數據三種策略
和 RDB 類似,AOF 會後臺 fork 一個子進程,主進程仍進行服務,子進程執行AOF持久化,數據被dump到磁盤上。但與 RDB 不同的是,後臺子進程持久化過程中,主進程會記錄期間的所有數據變更,可以理解爲命令會先進入緩存隊列(緩衝區),然後等到後臺子進程結束後,Redis 更新緩存追加到 AOF 文件中。這期間有三種策略:
- always(每次)
每次寫入操作均同步到AOF文件中,數據零誤差,性能較低,不建議使用。 - everysec(每秒)
每秒將緩衝區中的指令同步到AOF文件中,數據準確性較高,性能較高,建議使用,也是默認配置 ,在系統突然宕機的情況下丟失1秒內的數據。 - no(系統控制)
由操作系統控制每次同步到AOF文件的週期,整體過程不可控。
AOF相關配置
配置字段 | 說明 |
---|---|
appendonly yes|no | 是否開啓AOF持久化功能,默認爲不開啓狀態 |
appendfilename filename | AOF持久化文件名,默認文件名未appendonly.aof,建議配置爲appendonly-端口號.aof |
dir | AOF持久化文件保存路徑,與RDB持久化文件保持一致,目錄名稱data |
appendfsync always|everysec|no | AOF寫數據策略 |
AOF重寫
隨着命令不斷寫入AOF,文件會越來越大,爲了解決這個問題,Redis引入了AOF重寫機制壓縮文件體積。AOF文件重寫是將Redis進程內的數據轉化爲寫命令同步到新AOF文件的過程。簡單說就是將對同一個數據的若干個條命令執行結果轉化成最終結果數據對應的指令進行記錄。
比如多次set同一個key,只記錄最後一次即可。
AOF重寫規則
- 進程內已超時的數據不再寫入文件。
- 忽略無效指令,重寫時使用進程內數據直接生成,這樣新的AOF文件只保留最終數據的寫入命令。
- 對同一數據的多條寫命令合併爲一條命令。爲防止數據量過大造成客戶端緩衝區溢出,對list、set、hash、zset等類型,每條指令最多寫入64個元素。
AOF重寫方式
- 手動重寫:
bgrewriteaof
- 自動重寫:配置如下
auto-aof-rewrite-min-size size # size默認大小爲64mb auto-aof-rewrite-percentage percentage # 默認100,即當前AOF文件大小是上次日誌重寫得到AOF文件大小的二倍時
RDB與AOF對比
持久化方式 | RDB | AOF |
---|---|---|
佔用存儲空間 | 小(數據級:壓縮) | 大(指令級:重寫) |
存儲速度 | 慢 | 快 |
恢復速度 | 快 | 慢 |
數據安全性 | 會丟失數據 | 依據策略決定 |
資源消耗 | 高/重量級 | 低/輕量級 |
啓動優先級 | 低 | 高 |
如不能承受數分鐘以內的數據丟失,對業務數據非常敏感,選用AOF。AOF文件存儲體積較大,且恢復速度較慢。
如能承受數分鐘以內的數據丟失,且追求大數據集的恢復速度,選用RDB。實現比較緊湊的數據持久化會使Redis性能降的很低。
資料來源:https://www.bilibili.com/video/BV1CJ411m7Gc