1.持久化
1.1 持久化簡介
持久化(Persistence),持久化是將程式資料在持久狀態和瞬時狀態間轉換的機制,即把資料(如記憶體中的物件)保存到可永久保存的存盤設備中(如磁盤),
1.2 redis持久化
redis為記憶體資料庫,為了防止服務器宕機以及服務器行程退出后,服務器資料丟失,Redis提供了持久化功能,即將Redis中記憶體資料持久化到磁盤中,Redis 提供了不同級別的持久化方式:
- RDB持久化方式:可以在指定的時間間隔能對資料進行快照存盤.
- AOF持久化方式:記錄每次對服務器寫的操作,當服務器重啟的時候會重新執行這些命令來恢復原始的資料,AOF命令以redis協議追加保存每次寫的操作到檔案末尾.Redis還能對AOF檔案進行后臺重寫,使得AOF檔案的體積不至于過大.
如果服務器開啟了AOF持久化功能,服務器會優先使用AOF檔案還原資料,只有關閉了AOF持久化功能,服務器才會使用RDB檔案還原資料
2. RDB持久化
2.1 RDB檔案格式
RDB檔案是一個經過壓縮的二進制檔案(默認的檔案名:dump.rdb),由多個部分組成,RDB格式:
2.2 RDB檔案持久化創建與載入
在 Redis持久化時, RDB 程式將當前記憶體中的資料庫狀態保存到磁盤檔案中, 在 Redis 重啟動時, RDB 程式可以通過載入 RDB 檔案來還原資料庫的狀態,
2.3 作業方式
當 Redis 需要保存 dump.rdb 檔案時, 服務器執行以下操作:
- Redis 呼叫forks,同時擁有父行程和子行程,
- 子行程將資料集寫入到一個臨時 RDB 檔案中,
- 當子行程完成對新 RDB 檔案的寫入時,Redis 用新 RDB 檔案替換原來的 RDB 檔案,并洗掉舊的 RDB 檔案,
這種作業方式使得 Redis 可以從寫時復制(copy-on-write)機制中獲益,
2.4 創建方式
SAVE
同步操作,在執行該命令時,服務器會被阻塞,拒絕客戶端發送的命令請求
redis> save復制代碼
異步操作,在執行該命令時,子行程執行保存作業,服務器還可以繼續讓主執行緒處理客戶端發送的命令請求
redis>bgsave復制代碼
由于BGSAVE命令可不阻塞服務器行程下執行,可以讓用戶自定義save屬性,讓服務器每個一段時間自動執行一次BGSAVE命令(即通過組態檔對 Redis 進行設定, 讓它在“ N 秒內資料集至少有 M 個改動”這一條件被滿足時, 自動進行資料集保存操作),
比如:
/*
服服務器在900秒之內,對資料庫進行了至少1次修改
*/Save 900 1
/*服務器在300秒之內,對資料庫進行了至少10次修改
*/Save 300 10
/*服務器在60秒之內,對資料庫進行了至少10000次修改
*/Save 60 10000復制代碼
只要滿足其中一個條件就會執行BGSAVE命令
2.5 RDB 默認配置
################################ SNAPSHOTTING ################################
#
# Save the DB on disk:
#在給定的秒數和給定的對資料庫的寫運算元下,自動持久化操作,
# save <seconds> <changes>
#
save 900 1
save 300 10
save 60 10000
#bgsave發生錯誤時是否停止寫入,一般為yes
stop-writes-on-bgsave-error yes
#持久化時是否使用LZF壓縮字串物件?
rdbcompression yes
#是否對rdb檔案進行校驗和檢驗,通常為yes
rdbchecksum yes
# RDB持久化檔案名
dbfilename dump.rdb
#持久化檔案存盤目錄
dir ./
3. AOF持久化
3.1 AOF持久化簡介
AOF持久化是通過保存Redis服務器所執行的寫命令來記錄資料庫狀態
AOF持久化功能實作:
append命令追加:當AOF持久化功能處于打開狀態時,服務器執行完一個寫命令會協議格式被執行的命令追加服務器狀態的aof_buf緩沖區的末尾,
reids>SET KET VAULE //協議格式 \r\n$3\r\nSET\r\n$3\r\nKEY\r\n$5\r\nVAULE\r\n-
檔案寫入和同步sync:Redis的服務器行程是一個事件回圈,這個檔案事件負責接收客戶端的命令請求以及向客戶端發送命令回復,當執行了append命令追加后,服務器會呼叫flushAppendOnlyFile函式是否需要將AOF緩沖區的內容寫入和保存到AOF檔案
redis> SADD persistence "rdb" "aof"
redis> RPUSH size 128 256 512
3.2 AOF持久化策略
AOF持久化策略(即緩沖區內容寫入和同步sync到AOF中),可以通過配置appendfsync屬性來選擇AOF持久化策略:
- always:將aof_buf緩沖區中的所有內容寫入并同步到AOF檔案,每次有新命令追加到 AOF 檔案時就執行一次 fsync,
- everysec(默認):如果上次同步AOF的時間距離現在超過一秒,先將aof_buf緩沖區中的所有內容寫入到AOF檔案,再次對AOF檔案進行同步,且同步操作由一個專門執行緒負責執行,
- no:將aof_buf緩沖區中的所有內容寫入到AOF檔案,但并不對AOF檔案進行同步,何時同步由作業系統(OS)決定,
AOF持久化策略的效率與安全性:
- Always:效率最慢的,但安全性是最安全的,即使出現故障宕機,持久化也只會丟失一個事件 回圈的命令資料
- everysec:兼顧速度和安全性,出現宕機也只是丟失一秒鐘的命令資料
- No:寫入最快,但綜合起來單次同步是時間是最長的,且出現宕機時會丟失上傳同步AOF檔案之后的所有命令資料,
3.3 AOF重寫
由于AOF持久化會把執行的寫命令追加到AOF檔案中,所以隨著時間寫入命令會不斷增加, AOF檔案的體積也會變得越來越大,AOF檔案體積大對Reids服務器,甚至宿主服務器造成影響,
為了解決AOF檔案體積膨脹的問題,Redis提供了AOF檔案重寫(rewrite)功能:
- 生成一個不保存任何浪費空間的冗余命令新的AOF檔案,且新舊AOF檔案保存資料庫狀態一樣的
- 新的AOF檔案是通過讀取資料庫中的鍵值對來實作的,程式無須對現有的AOF檔案進行讀入,分析,或者寫入操作,
- 為防止緩沖區溢位,重寫處理list,hash,set以及Zset時,超過設定常量數量時會多條相同命令記錄一個集合,
- Redis 2.4 可以通過配置自動觸發 AOF 重寫,觸發引數
auto-aof-rewrite-percentage(觸發AOF檔案執行重寫的增長率) 以及auto-aof-rewrite-min-size(觸發AOF檔案執行重寫的最小尺寸)
AOF重寫的作用:
- 減少磁盤占用量
- 加速資料恢復
Redis服務器使用單個執行緒來處理命令請求,服務器大量呼叫aof_rewrite函式,在AOF重寫期間,則無法處理client發來的命令請求,所以AOF重寫程式放在子行程執行,好處:
- 子行程進行AOF重寫期間,服務器行程可以繼續處理命令請求
- 子行程帶有服務器行程的資料副本,保證了資料的安全性,
AOF重寫使用子行程會造成資料庫與重寫后的AOF保存的資料不一致,為了解決這種資料不一致,redis使用了AOF重寫緩沖區實作:
- 執行命令,同時將命令追加到AOF緩沖區和AOF重寫緩沖區
- 當AOF子行程重寫完成后,發送一個信號給父行程,父行程將執行AOF重寫緩沖區中的所有內容寫入到新AOF檔案中,新AOF檔案保存的資料庫狀態將和服務器當前的資料庫狀態一致,
- 對新的AOF檔案進行改名,原子性地覆寫現有AOF檔案,完成新舊兩個AOF檔案替換處理完成,
3.4 AOF持久化默認引數
############################## APPEND ONLY MODE ############################### #開啟AOF持久化方式 appendonly no #AOF持久化檔案名 appendfilename "appendonly.aof" #每秒把緩沖區的資料fsync到磁盤 appendfsync everysec # appendfsync no #是否在執行重寫時不同步資料到AOF檔案 no-appendfsync-on-rewrite no # 觸發AOF檔案執行重寫的增長率 auto-aof-rewrite-percentage 100 #觸發AOF檔案執行重寫的最小size auto-aof-rewrite-min-size 64mb #redis在恢復時,會忽略最后一條可能存在問題的指令 aof-load-truncated yes #是否打開混合開關 aof-use-rdb-preamble yes4 持久化方式總結與抉擇
4.1 RDB優缺點
RDB的優點
- RDB是一個非常緊湊的檔案,它保存了某個時間點得資料集,非常適用于資料集的備份,比如你可以在每個小時報保存一下過去24小時內的資料,同時每天保存過去30天的資料,這樣即使出了問題你也可以根據需求恢復到不同版本的資料集.
- 基于RDB檔案緊湊性,便于復制資料到一個遠端資料中心,非常適用于災難恢復.
- 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,但是你可以調節重寫日志檔案的頻率來提高資料集的耐久度.
4.2 AOF的優缺點
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 檔案的體積通常要大于 RDB 檔案的體積,
- 根據所使用的 fsync 策略,AOF 的速度可能會慢于 RDB , 在一般情況下, 每秒 fsync 的性能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負荷之下也是如此, 不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間(latency),
4.3 如何選擇使用哪種持久化方式?
一般來說, 如果想達到資料安全性, 你應該同時使用兩種持久化功能,
如果你非常關心你的資料, 但仍然可以承受數分鐘以內的資料丟失, 那么你可以只使用 RDB 持久化,
有很多用戶都只使用 AOF 持久化, 但并不推薦這種方式: 因為定時生成 RDB 快照(snapshot)非常便于進行資料庫備份, 并且 RDB 恢復資料集的速度也要比 AOF 恢復的速度要快, 除此之外, 使用 RDB 還可以避免之前提到的 AOF 程式的 bug ,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/107489.html
標籤:PHP
上一篇:PHP 核心特性 - 錯誤處理
