Rdb存儲的弊端
- 存儲數據量較大,效率較低(基於快照思想,每次讀寫都是全部數據,當數據量巨大,效率非常低)
- 大數據量下的IO性能較低
- 基於fork創建子進程,內存產生額外消耗
- 宕機帶來的數據丟失風險
解決思路
- 不寫全數據,僅記錄部分數據
- 改記錄數據未記錄操作過程
- 對所有操作均進行記錄,排除丟失數據的風險
AOF概念
- AOF(append only file)持久化:以獨立日誌的方式記錄每次寫命令,重啓時再重新執行AOF文件中命令達到恢復數據的目的,與rdb相比可以簡單描述爲記錄數據爲記錄數據產生的過程
- AOF的主要作用是解決了數據持久化的實時性,目前已經是redis持久化的主流方式
AOF寫數據過程
從aof寫命令刷新緩存區多久同步到aof,每次同步多少條
以下有三種策略
aof寫數據三種策略(appendfsync)
- Always(每次)
每次寫入操作均同步到aof文件中,數據零誤差,性能較低,不建議使用
- Everysec(每秒)
每秒將緩衝區中的指令同步到aof文件中,數據準確性較高,性能較高,建議使用,也是默認配製在系統突然宕機的情況下丟失1秒內的數據
在系統突然宕機的情況下丟失1秒內的數據
- No(系統控制)
由操作系統控制每次同步到aof文件的週期,整體過程不可控
AOF功能開啓
配置
appendonly yes|no
作用
是否開啓aof持久化功能,默認爲不開啓狀態
配置
appendfsync always|everysec|no
作用
aof寫數據策略
如下爲配置文件示例:
AOF相關配置
配置
appendfilename filename
作用
aof持久化文件名,默認文件名未appendonly.aof,建議配置爲appendonly-端口號.aof
配置
dir
作用
aof持久化文件保存路徑,與rdb持久化文件保存一致即可
Aof寫數據遇到的問題
如果連續執行如下指令
我們會看到有很多重複且沒必要保存的指令,name最後爲ww,num最後爲3,有很多冗餘數據,那麼有沒有一種方案優化呢?
Aof重寫
隨着命令不斷寫入AOF,文件會越來越大,爲了解決這個問題,redis引入了aof重寫機制壓縮文件體積,aof文件重寫是將redis進程內的數據轉化爲寫命令同步到新aof文件的過程。簡單說就是將對同一個數據的若干條命令執行結果轉化成最終結果數據對應的指令進行記錄。
AOF重寫作用
降低磁盤佔用量,提高磁盤利用率
提高持久化效率,降低持久化寫時間,提高IO性能
降低數據恢復用時,提高數據恢復效率
AOF重寫規則
- 進程內已超時的數據不再寫入文件
- 忽略無效指令,重寫時使用進程內數據直接生成,這樣新的aof文件只保留最終數據的寫入命令,如del key1,hdel key2,srem key3,set key4 111,set key5 222等
- 對同一數據的多條寫命令合併爲一條命令
如lpush list1 a,lpush list1 b,lpush list1 c可以轉化爲:lpush list1 a b c。
爲防止數據量多大造成客戶端緩衝區溢出,對list、set、hash、zset等類型,每條指令最多寫入64個元素。
AOF重寫方式
- 手動重寫
bgrewriteaof
自動重寫
auto-aof-rewrite-min-size size
auto-aof-rewrite-percentage percentage
AOF手動重寫--bgrewriteaof指令工作原理
AOF自動重寫方式
- 自動重寫觸發條件設置
auto-aof-rewrite-min-size size
auto-aof-rewrite-percentage percentage
自動重寫觸發比對參數(運行指令info persistence獲取具體信息)
aof_current_size
aof_base_size
自動重寫觸發條件
aof_current_size>auto-aof-rewrite-min-size
aof_current_size-aof_base_size/aof_base_size>=auto-aof-rewrite-percentage
Aof工作流程
將上圖進一步深入,內部都幹了啥,如下圖: