事件背景
Redis主從開啟AOF,錯誤操作導致數據被清空。
Redis主要作用:緩存、隊列。
事故過程
Redis搭建了主從,持久化方式為RDB,RDB沒有定時備份,且AOF都沒有開啟。
考慮到開啟AOF會使Redis安全性更高,所以嘗試先在從機做測試,沒問題后再上主機。
Redis開啟AOF的方式非常簡單,打開Redis的conf文件,找到【appendonly】配置項,將【no】改為【yes】重啟服務即可。
Redis從機重啟后,成功在數據目錄生成了百M以上的【appendonly.aof】文件,以該aof文件單獨啟動Redis實例,生成的數據和單獨以RDB文件啟動生成的數據一樣,因此判斷從機AOF配置成功。
接着直接上了主機,Redis主機以同樣的方式配置AOF后,結果實例重啟的瞬間,Redis主從數據被清空,主從AOF及RDB文件大小接近0M。
問題分析
1、為什么在已經開啟RDB持久化的情況下,還打算開啟AOF?
解答:同時開啟兩種持久化,Redis擁有足以媲美PostgreSQL的數據安全性。
RDB 持久化可以在指定的時間間隔內生成數據集的時間點快照,常用做備份。
AOF 持久化記錄服務器執行的所有寫操作命令,並在服務器啟動時,通過重新執行這些命令來還原數據集。
RDB默認的快照保存配置:
save 900 1 #900秒內如果超過1個key被修改,則發起快照保存
save 300 10 #300秒內容如超過10個key被修改,則發起快照保存
save 60 10000 #60秒內容如超過10000個key被修改,則發起快照保存
而AOF默認策略則為每秒鍾一次fsync
當然你也可以設置不同的fsync策略,比如無fsync
或者每秒鍾一次fsync,或者每次執行寫入命令時fsync
AOF文件有序地保存了對數據庫執行的所有寫入操作,
這些寫入操作以Redis協議的格式保存。
因此AOF文件的內容非常容易被人讀懂,對文件進行分析也很輕松。
導出AOF文件也非常簡單:舉個例子,如果你不小心執行了 FLUSHALL 命令,
但只要AOF文件未被重寫,那么只要停止服務器,
移除AOF文件末尾的FLUSHALL命令,並重啟Redis,
就可以將數據集恢復到FLUSHALL執行之前的狀態。
有效地利用以上的RDB和AOF特性,能使Redis擁有足以媲美PostgreSQL的數據安全性。
2、為什么在從機AOF配置成功的情況下,主機開啟AOF,主從數據瞬間被清空?
解答:首先得明白Redis有這么一個特性,即兩種持久化同時開啟的情況下,Redis啟動默認加載AOF文件恢復數據。
Redis從機由於事先沒有開啟AOF,配置重啟后,從機會生成一個空的AOF文件並默認加載,這時從機數據是空的,但由於配置了主從,從機會同步主機數據,所以你會發現新生成的AOF文件大小在迅速增長。因此Redis從機開啟AOF后,數據最終是沒有問題的。
這時候Redis主機也配置AOF並重啟,主機生成AOF並默認加載,數據瞬間被清空,同時主機RDB發現60秒內有超過10000個key被修改,發起了快照保存,RDB數據也被清空。由於都是內存操作,所以非常快。最后再主從同步,所有數據被刪。
3、兩種持久化同時開啟的情況下,Redis啟動為什么默認選擇加載AOF而不是RDB文件來恢復數據?
解答:AOF默認策略為每秒鍾一次fsync,所以通常情況下,AOF文件所保存的數據相對RDB更完整。
4、AOF 持久化會記錄服務器執行的所有寫操作命令,那么數據被清空后,為什么不能通過AOF文件的日志記錄恢復數據?
解答:Redis會自動地在后台對AOF進行重寫,重寫后的新AOF文件包含了恢復當前數據集所需的最小命令集合
為什么會重寫?
因為AOF記錄了服務器執行的所有寫操作命令,而RDB本身又是一個非常緊湊的文件
所以對於相同的數據集來說,AOF文件的體積通常要大於RDB文件的體積
而體積大了終究不好,比如Redis重啟默認加載AOF文件就要更多的時間
5、面試官如果問你,如何在不用【config set】命令的情況下,將Redis持久化由RDB切換到AOF,你怎么回答?
解答:呵呵,利用主從。。。從機配置AOF重啟后,將生成的AOF文件復制至主機Redis數據目錄,主機配置AOF后再重啟。
注:在 Redis 2.2 或以上版本,通過【config set】可以在不重啟的情況下,從 RDB 切換到 AOF。
1)為最新的 dump.rdb 文件創建一個備份。
2)將備份放到一個安全的地方。
3)執行以下兩條命令:
redis-cli> CONFIG SET appendonly yes
redis-cli> CONFIG SET save ""
4)確保命令執行之后,數據庫的鍵的數量沒有改變。
5)確保寫命令會被正確地追加到 AOF 文件的末尾。
步驟 3 執行的第一條命令開啟了AOF功能:<font style="color:red">Redis會阻塞直到初始AOF文件創建完成為止</font>,之后Redis會繼續處理命令請求, 並開始將寫入命令追加到 AOF 文件末尾。
步驟 3 執行的第二條命令用於關閉RDB功能。這一步是可選的,如果你願意的話,也可以同時使用RDB和AOF這兩種持久化功能。
不過別忘了在redis.conf中打開AOF功能!否則的話,服務器重啟之后,之前通過【CONFIG SET】設置的配置就會被遺忘,程序會按原來的配置來啟動服務器。