【redis】-- redis的持久化(作為資料庫)
目錄
- 1.RDB
- rdb持久化的方式
- rdb方式的優點:
- aof的優點
- 3.持久化的其他特性
- 日誌重寫
- 工作原理
- rdb和aof混合使用
redis是一個基於記憶體的資料庫,故在redis正在執行的資料都在記憶體中,而記憶體掉電,記憶體上所以資料都會消失。故把redis當成資料庫使用時就需要對redis進行持久化。
在說redis持久化的時候,我們先來聊聊其他的知識。linux的父子程序。在Linux中使用fork()函式會給當前正在執行的程序建立一個子程序。那麼現在問題就來了,fork時父子程序中的資料有什麼關係呢?一般說到程序我們都會知道程序間彼此是資料隔離的。然而實際上,子程序在剛建立時,可以看到子程序中的資料。而在修改該資料時,卻不會對父程序造成影響。同樣子程序也不會受到父程序修改資料的影響。而造成這種現象的,正是因為linux的copy on write機制。
copy on write:是一種核心機制,通俗來講就是寫時複製。及建立子程序並不發生複製,建立子程序後父子程序共用資料。只有在修改資料是才會建立新的空間。
這樣做的好處是建立程序變快了。而且根據開發經驗,我們建立子程序後不可能父子程序把所有資料都改一遍。而這套機制就是指標支撐的。玩的是指標
redis中有兩種資料到儲存方式,rdb和aof。下面我們來著重講一下這兩種持久化方式:
1.RDB
rdb持久化的方式
RDB持久化方式能夠在指定的時間間隔能對你的資料進行快照儲存.
redis的rdb持久化方式有儲存的是時點資料即某一個時間點的資料。因為如果儲存實時更新的資料的話,如果一直有資料寫入會導致,持久化過程一直進行,降低了redis的快捷的特性。因此redis有兩種持久化資料的方式
- save:前臺更新資料,如果使用這種方法持久化,那麼只能在伺服器停機維護時,發生因為它會阻塞redis程序造成redis的服務不可用。
- bgsave:後臺執行,該命令的原理是,建立一個子程序來進行redis的持久化,而redis依然提供服務。此時就用到了剛才講到的copy on write機制,父子程序共用了一套資料。
以上兩個命令直接可以在redis的客戶端執行。
注意如果使用配置檔案的方式配置資料持久化,配置檔案中給出bgsave的規則: save這個標識。配置的規則:(要修改的檔案是dbfilename dump.rdb,檔案一般儲存在var/lib/redis/6379)
save 900 1 save 300 10 save 60 10000
該規則意味著,在每60秒檢測一次redis的資料量,如果達到10000就進行持久化,否則不持久化。在每300秒檢測一次redis的資料量,如果達到10就進行持久化,否則不持久化。在每900秒檢測一次redis的資料量,如果達到1就進行持久化,否則不持久化。
rdb方式的優點:
- RDB是一個非常緊湊的檔案,它儲存了某個時間點得資料集,非常適用於資料集的備份,比如你可以在每個小時報儲存一下過去24小時內的資料,同時每天儲存過去30天的資料,這樣即使出了問題你也可以根據需求恢復到不同版本的資料集.
- RDB是一個緊湊的單一檔案,很方便傳送到另一個遠端資料中心或者亞馬遜的S3(可能加密),非常適用於災難恢復.
- RDB在儲存RDB檔案時父程序唯一需要做的就是fork出一個子程序,接下來的工作全部由子程序來做,父程序不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的效能.
與AOF相比,在恢復大的資料集的時候,RDB方式會更快一些.
rdb的缺點
- 如果你希望在redis意外停止工作(例如電源中斷)的情況下丟失的資料最少的話,那麼RDB不適合你.雖然你可以配置不同的save時間點(例如每隔5分鐘並且對資料集有100個寫的操作),是Redis要完整的儲存整個資料集是一個比較繁重的工作,你通常會每隔5分鐘或者更久做一次完整的儲存,萬一在Redis意外宕機,你可能會丟失幾分鐘的資料.
- RDB 需要經常fork子程序來儲存資料集到硬碟上,當資料集比較大的時候,fork的過程是非常耗時的,可能會導致Redis在一些毫秒級內不能響應客戶端的請求.如果資料集巨大並且CPU效能不是很好的情況下,這種情況會持續1秒,AOF也需要fork,但是你可以調節重寫日誌檔案的頻率來提高資料集的耐久度.
- 不支援拉鍊化,只有一個rdb檔案
丟失資料相對多一些時點與時點之間視窗資料容易丟失。8點得到一個rdb,9點剛要寫一個rdb,掛機了。那麼8~9之間的資料就會丟失。
2.AOF
AOF實際是把對redis操作的操作記錄,通過日誌的方式記錄下來,這樣想要恢復資料庫檔案,只需要把所以指令執行一遍就行。
需要開啟aof只需要把dump修改appendonly該為yes即可。
appendonly yes
aof的優點
- 使用AOF 會讓你的Redis更加耐久: 你可以使用不同的fsync策略:無fsync,每秒fsync,每次寫的時候fsync.使用預設的每秒fsync策略,Redis的效能依然很好(fsync是由後臺執行緒進行處理的,主執行緒會盡力處理客戶端請求),一旦出現故障,你最多丟失1秒的資料.
- AOF檔案是一個只進行追加的日誌檔案,所以不需要寫入seek,即使由於某些原因(磁碟空間已滿,寫的過程中宕機等等)未執行完整的寫入命令,你也也可使用redis-check-aof工具修復這些問題.
- Redis 可以在 AOF 檔案體積變得過大時,自動地在後臺對 AOF 進行重寫: 重寫後的新 AOF 檔案包含了恢復當前資料集所需的最小命令集合。 整個重寫操作是絕對安全的,因為 Redis 在建立新 AOF 檔案的過程中,會繼續將命令追加到現有的 AOF 檔案裡面,即使重寫過程中發生停機,現有的 AOF 檔案也不會丟失。 而一旦新 AOF 檔案建立完畢,Redis 就會從舊 AOF 檔案切換到新 AOF 檔案,並開始對新 AOF 檔案進行追加操作。
AOF 檔案有序地儲存了對資料庫執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式儲存, 因此 AOF 檔案的內容非常容易被人讀懂, 對檔案進行分析(parse)也很輕鬆。 匯出(export) AOF 檔案也非常簡單: 舉個例子, 如果你不小心執行了 FLUSHALL 命令, 但只要 AOF 檔案未被重寫, 那麼只要停止伺服器, 移除 AOF 檔案末尾的 FLUSHALL 命令, 並重啟 Redis , 就可以將資料集恢復到 FLUSHALL 執行之前的狀態
aof的缺點
弊端,體量無線變大, 恢復慢
為解決aof的弊端日誌,優點如果能保住,還是可以用的。就有一個方案:設計一個方案讓日誌,AOF足夠小
就是hdfs,fsimage+edits.log 。讓日誌只記錄增量,合併操作的中間過程。
而4.0版本也是這項技術的分界點
- 4.0以前進行重寫時,刪除抵消的命令合併重複的命令。這樣最終也是一個純指令的日誌檔案
- 4.0以後將老的資料RDB到aof檔案中,將增量的以指令的方式Append到AOFAOF是一個混合體。其利用了RDB的快,利用了日誌的全量
從這點可以看出,aof和rdb是可以共存的。
3.持久化的其他特性
日誌重寫
Redis 支援一種有趣的特性: 可以在不打斷服務客戶端的情況下, 對 AOF 檔案進行重建(rebuild)。執行 BGREWRITEAOF 命令, Redis 將生成一個新的 AOF 檔案, 這個檔案包含重建當前資料集所需的最少命令。Redis 2.2 需要自己手動執行 BGREWRITEAOF 命令; Redis 2.4 則可以自動觸發 AOF 重寫, 具體資訊請檢視 2.4 的示例配置檔案。
工作原理
AOF 重寫和 RDB 建立快照一樣,都巧妙地利用了寫時複製機制:
- Redis 執行 fork() ,現在同時擁有父程序和子程序。子程序開始將新 AOF 檔案的內容寫入到臨時檔案。
- 對於所有新執行的寫入命令,父程序一邊將它們累積到一個記憶體快取中,一邊將這些改動追加到現有 AOF 檔案的末尾,這樣樣即使在重寫的中途發生停機,現有的 AOF 檔案也還是安全的。
- 當子程序完成重寫工作時,它給父程序傳送一個訊號,父程序在接收到訊號之後,將記憶體快取中的所有資料追加到新 AOF 檔案的末尾。
搞定!現在 Redis 原子地用新檔案替換舊檔案,之後所有命令都會直接追加到新 AOF 檔案的末尾。
redis的持久化想要開啟其實挺簡單的只需要,修改conf配置檔案的幾個配置項即可。
rdb和aof混合使用
當二者混合使用時,如果redis伺服器停止後重新執行,那麼redis恢復資料只會從aof中同步,而不會去向rdb同步。而且在主從複製時,rdb會記錄上一次連線的埠,而aof不會。所以主從複製時,如果沒有開啟aof,那麼從伺服器在斷開主伺服器後重新連線主伺服器,只會同步從伺服器斷開時的增量資料,而開啟aof後從伺服器需要同步主伺服器中的所有內