接下來兩篇將記錄Redis持久化儲存兩大技術:AOF日誌、RDB快照
本篇重點
“AOF日誌實現”
“AOF日誌三種寫回策略”
“AOF重寫——避免日誌過大的解決方案”
前言
Redis持久化儲存兩大技術:AOF日誌、RDB快照
AOF: Append Only File
RDB: Redis DB
背景
Redis執行中,若突然宕機,儲存在記憶體中的資料都會丟失。此時如果從後端資料庫恢復資料,雖然可行,但也會導致效率問題:
- 頻繁訪問資料庫增加資料庫壓力
- 慢速資料庫讀取導致Redis效能下降
因此,Redis實現資料持久化的方式,要避免從後端資料庫中恢復資料,採用的方式就是AOF日誌和RDB快照,本篇文章主要討論AOF日誌。
1. AOF日誌實現
- 寫後日志:先執行命令,資料寫入記憶體;再記錄日誌
- 日誌記錄內容:Redis收到的每一條命令,記錄格式如下:
"*+number"——當前命令有number個欄位,後面內容是對應欄位描述
"$+number"——表示當前欄位佔用的位元組數,後面跟具體欄位名稱
例子:命令:
set testkey testvalue
,寫入AOF日誌後的格式是*3 // 當前命令3個欄位(分別是set testkey testvalue)
$3 // 第一個欄位佔3B
set // 第一個欄位名:set
$7
testkey
$9
testvalue
- “寫後日志”的原因
- Redis記錄AOF日誌時不會對命令進行語法檢查(節省檢查開銷)
- 基於第一點,採用“寫後日志”防止記錄錯誤命令
- AOF日誌在主執行緒中執行
- AOF不會阻塞當前寫操作(先執行命令,後記錄日誌)
- AOF潛在風險:
- AOF存在阻塞下一個操作的風險(下個操作執行之前主執行緒寫上一個操作的日誌)
- 若Redis直接用作資料庫,命令執行後系統宕機——AOF日誌沒記錄導致資料丟失
以上的AOF潛在風險都與AOF日誌寫盤時間相關,解決方案——AOF三種寫回策略
2. AOF日誌三種寫回策略——appendfsync引數的三個可選項
Always——同步寫回:每個寫命令執行後,同步寫磁碟
Everysec——每秒寫回:日誌暫時寫到AOF日誌cache,每隔1s寫盤
No——作業系統控制的寫回:日誌暫時寫到AOF日誌cache,由OS決定何時寫盤
配置項 | 寫回時機 | 優點 | 缺點 | 適用場景 |
---|---|---|---|---|
Always | 同步寫回 | 可靠性高 資料基本不丟失 |
每個寫操作都伴隨寫盤,效能影響較大 | 高可靠性 |
Everysec | 每秒寫回 | 效能適中 | 宕機時丟失1s內資料 | 允許少量資料丟失,同時效能影響較小 |
No | OS控制寫回 | 效能好 | 宕機時丟失資料較多 | 高效能 |
QA
Q: AOF檔案過大帶來的一系列效能問題?如何控制AOF檔案過大?
A: 效能問題
- 檔案系統本身檔案大小的限制
- 檔案太大時,追加命令記錄效率變低
- 宕機後,AOF檔案中的命令挨個重新執行的導致的故障恢復過程緩慢
解決方案:AOF重寫機制
3. AOF重寫——避免AOF日誌過大
- AOF重寫:Redis根據資料庫現狀,建立一個新的AOF檔案
- 原理:“多變一”——某個KV被多條命令反覆修改
- AOF重寫是否會阻塞主執行緒?AOF重寫機制。
- AOF日誌由主執行緒寫盤
- AOF重寫日誌由後臺子程序bgrewriteaof執行
- 重寫過程——“一個拷貝,兩處日誌”
- “一個拷貝”:主執行緒fork bgrewriteaof子程序,通過拷貝頁表(OS的“寫時複製”原則)訪問主執行緒的記憶體資料
- “兩處日誌”:寫操作發生時,AOF日誌與AOF重寫均先將操作記錄到各自日誌cache中,隨後fork bgrewriteaof子程序程序重寫日誌操作
- AOF非阻塞的重寫過程
結尾
AOF故障恢復需要執行所有操作記錄,即“重放”過程很慢,既能避免資料丟失,又能更快恢復資料的方法——“RDB快照”
圖片來源於極客時間專欄《Redis核心技術與實戰》