Redis是一個鍵值對資料庫,伺服器中通常包含着任意個非空資料庫,而每個非空資料庫中又可以包含任意個鍵值對,我們将是伺服器中的非空資料庫以及它們的鍵值對統稱為資料庫狀态。
Redis是記憶體資料庫,它将資料存儲在記憶體中,如果不能将記憶體中的資料持久化到磁盤中,Redis突然當機,會導緻資料丢失。
為了解決這個問題,Redis提供了RDB持久化功能,
一、RDB持久化
RDB,英文全稱Redis DataBase,在指定的時間間隔,将記憶體中的資料寫入磁盤,待恢複時再将磁盤中的資料寫入記憶體。
1、自動觸發
redis.conf配置檔案中,save <seconds> <changes>,比如 save 60 20,在60秒内修改20次就自動觸發RDB備份。
2、手動觸發
通過save和bgsave手動觸發RDB備份。
(1)save,在主程式中執行會阻塞目前Redis伺服器,直到RDB持久化完成,也就是說save持久化期間,Redis就不能用了,禁止使用。
(2)bgsave,不阻塞目前Redis伺服器,Redis會fork一個子程序,異步進行快照操作。
禁用快照:redis-cli config set save ""。
3、設定儲存條件
伺服器程式會根據save選項所設定的儲存條件,設定伺服器狀态redisServer結構的saveparams屬性。
dirty計數器記錄距離上次成功執行save指令後,伺服器對資料狀态進行了多少次修改。
lastsave屬性是一個UNIX時間戳,記錄了伺服器上一次成功執行save指令的時間。
屬性是一個數組,數組中的每個元素都是一個saveparam結構,每個saveparam結構都儲存了一個save選項設定的儲存條件。
以上就是Redis伺服器根據save選項所設定的儲存條件,自動執行bgsave指令,進行間隔性資料儲存的實作原理。
4、加解密
RDB持久化功能所生成的RDB檔案是一個經過壓縮的二進制檔案,通過該檔案可以還原生成RDB檔案時的資料庫狀态。
5、RDB持久化優缺點
(1)優點
- 适合大規模的資料備份、恢複;
- 可以定時備份;
- 對資料一緻性、完整性要求不高的場景可以使用;
- RDB檔案在記憶體中的加載速度要比AOF塊;
(2)缺點
- 因為是定時備份,如果Redis當機的話,會丢失一部分資料;
- 因為是資料的全量同步,如果資料量過大,會産生大量IO,嚴重影響伺服器性能;
- RDB持久化時,會fork一個子程序,如果資料過大, 可能會導緻伺服器的瞬間延遲;fork的時候記憶體中的資料會被克隆一份,是否會造成記憶體溢出,值得考慮;
6、哪些情況會觸發RDB持久化?
(1)redis.conf中的定時配置;
(2)手動執行save、bgsave指令;
(3)執行flushall、flushdb指令,産生的.rdb檔案是空的;
(4)執行shutdown指令,且沒有設定AOF持久化;
(5)主動複制時,主節點自動觸發;
注意:save和bgsave不能同時執行,如果bgsave指令正在執行,那麼用戶端發送的save指令會被拒絕執行,伺服器禁止save和bgsave同時執行是為了避免父程序和子程序同時執行兩個rdbSave調用,防止産生競争條件。
建立RDB檔案的實際工作是由rdb.c/rdbSave函數完成,save和bgsave會以不同的方式調用這個函數。
二、AOF持久化
AOF,Append Only File,,Redis啟動時會讀取該檔案,重新執行一遍之前的寫操作指令,達到恢複資料的效果。
預設不開啟,需要更改為appendonly yes,開啟AOF快照功能。
1、AOF持久化過程
(1)在執行Redis指令時,Redis會将這些指令放入AOF緩存中,AOF緩存是位于記憶體中的一個區域,AOF緩存中的指令達到一定數量後,批量寫入磁盤,避免頻繁的磁盤IO操作;
(2)根據AOF緩沖區同步檔案的三種寫回政策,将指令寫到磁盤的AOF檔案中;
(3)随着寫入AOF内容的增加,會根據規則進行指令的合并,起到壓縮AOF檔案的效果;
(4)當Redis重新開機時,會根據AOF檔案,依此執行指令,恢複記憶體資料;
很多人會問,如果加入到AOF緩存的資料還沒寫入磁盤,此時伺服器當機了,資料不會産生丢失嗎?
系統提供了fsync和fdatasync兩個同步函數,他們可以強制作業系統立即将緩存區中的資料寫入到磁盤裡,確定寫入資料的完整性。
2、appendfsync的選項值
(1)Always,同步寫回,每個寫指令執行完立刻同步到磁盤;最多隻會丢失一個指令的資料,最安全,但是效率最低;
(2)everysec,每秒寫回;它最多丢失1秒的資料;
(3)no,作業系統控制的寫回,每個指令執行完,存到AOF緩存中,由作業系統決定,啥時候将指令寫入到磁盤AOF檔案中;
3、AOF持久化優缺點
(1)優點
更好的保護資料不丢失,性能高,可做緊恢複。
(2)缺點
- 等量級的指令,AOF持久化檔案要大于RDB持久化檔案;
- 恢複速度慢于RDB;
4、資料恢複順序和加載流程
當同時開啟AOF和RDB的時候,會優先加載AOF檔案來恢複資料,因為通常情況下AOF檔案比RDB檔案備份的資料要完整。
三、Redis事務
1、Redis事務是什麼?
可以一次性順序執行多個指令,不可被其它指令插隊,但是,Redis的事務不能復原。
2、Redis事務常用指令
(1)discard,取消事務,放棄執行事務内的所有指令;
(2)exec,執行所有指令;
(3)multi,标記一個事務塊的開始;
(4)unwatch,取消watch指令對所有key的監視;
(5)watch key,監視某個key,如果這個key在事務執行之前被其它指令改動,那麼事務将被打斷;
3、事務指令執行順序
4、事務的ACID特性
在Redis中,事務總是具有原子性(Atomicity)、一緻性(Consistency)、隔離性(Isolation),并且Redis運作在某些特殊模式下,也具有持久性(Durability)。
(1)原子性
事務具有原子性,指的是事務中的多個操作當做一個整體來執行,伺服器要麼就執行事務中的全部操作,要麼就一個操作也不執行。
(2)一緻性
如果資料庫在執行事務之前是一緻的,那麼在事務執行之後,無論事務執行是否成功,資料庫也應該是一緻的。
(3)隔離性
隔離性指即使資料庫中有多個事務并發地執行,各個事務之間也不會互相影響,并且在并發狀态下執行的事務和串行執行的事務産生的結果完全相同。
(4)持久性
當一個事務執行完畢時,執行這個事務所得的結果已經被儲存到硬碟裡,即使伺服器此時當機,執行事務所得的結果也不會丢失。
四、Redis管道
1、Redis管道釋義
Redis是一種基于用戶端-服務端模型以及請求響應協定的TCP服務,每個請求會遵循如下操作:
(1)用戶端向服務端發送指令,
(2)式等待服務端響應;
服務端處理指令,并将結果傳回給用戶端;
上面兩步走,稱為RTT,資料往返于兩端的時間,Round Trip Time。
如果需要執行大量指令,那麼新的指令要等待上一個指令執行完畢才能執行,會頻繁的調用系統IO,頻繁發送網絡請求,同時需要Redis調用多次read()和write()系統方法,系統方法會将資料從使用者态轉移到核心态,性能不佳。
2、注意事項
(1)pipeline緩存的指令隻會依此執行,不保證原子性,如果執行中發生異常,也會繼續執行後面的指令;
(2)使用pipeline組裝的指令個數不能太多,不然可能會造成阻塞時間過長的現象,同時服務端也會被迫回複一個隊列答複,占用過多記憶體;
3、代碼實戰
編寫一個指令腳本,添加幾個不同類型的資料。
通過 cat run.txt | redis-cli -a 111111 --pipe 指令,體驗Redis管道效果。