Redis 是個基于內存的數據庫。那服務一旦宕機,內存中數據必將全部丟失。所以丟失數據的恢復對于 Redis 是十分重要的,我們首先想到是可以從數據庫中恢復,但是在由 Redis 宕機時(說明相關工作正在運行)且數據量很大情況下,從數據庫恢復的話,會為數據庫帶來巨大的壓力,進而導致程序相應緩慢。因此實現數據的持久化,避免從后端數據庫中恢復數據,對于Redis 是十分必要的。
~
本篇內容包括:Redis 持久化機制(即 RDB、AOF 和 二者的區別)、Redis 事務及相關命令。
文章目錄
- 一、Redis 持久化機制
- 1、Redis 持久化機制 RDB
- 2、Redis 持久化機制 AOF
- 3、Redis 持久化機制 RDB 與 AOF 的區別
- 二、Redis 事務
- 1、Redis 事務
- 2、Redis 事務相關命令
- 3、關于 Pipeline
一、Redis 持久化機制
Redis 是個基于內存的數據庫。那服務一旦宕機,內存中數據必將全部丟失。所以丟失數據的恢復對于 Redis 是十分重要的,我們首先想到是可以從數據庫中恢復,但是在由 Redis 宕機時(說明相關工作正在運行)且數據量很大情況下,從數據庫恢復的話,會為數據庫帶來巨大的壓力,進而導致程序相應緩慢。因此實現數據的持久化,避免從后端數據庫中恢復數據,對于Redis 是十分必要的。
此外,Redis 可以通過創建快照來獲得存儲在內存里面的數據。創建快照之后,可以對快照進行備份,可以將快照復制到其他服務器從而創建具有相同數據的服務器副本(Redis 主從結構,主要用來提高 Redis 性能),還可以將快照留在原地以便重啟服務器的時候使用,其中 Redis 最常用的快照持久化機制分為兩種,即 RDB 與 AOF。
1、Redis 持久化機制 RDB
RDB 持久化可以手動執行也可以根據配置定期執行,它的作用是將某個時間點上的數據庫狀態保存到 RDB 文件中,RDB 文件是一個壓縮的二進制文件,通過它可以還原某個時刻數據庫的狀態。由于RDB文件是保存在硬盤上的,所以即使 Redis 崩潰或者退出,只要 RDB 文件存在,就可以用它來恢復還原數據庫的狀態。
可以通過 SAVE 或者 BGSAVE 來生成 RDB 文件:
- SAVE 命令會阻塞 Redis 進程,直到 RDB 文件生成完畢,在進程阻塞期間,redis 不能處理任何命令請求,這顯然是不合適的。
- BGSAV E則是會 for k出一個子進程,然后由子進程去負責生成 RDB 文件,父進程還可以繼續處理命令請求,不會阻塞進程。
2、Redis 持久化機制 AOF
AOF 和 RDB 不同,AOF 是通過保存 redis服務器所執行的寫命令來記錄數據庫狀態的。

AOF 通過追加、寫入、同步三個步驟來實現持久化機制。
- 當 AOF 持久化處于激活狀態,服務器執行完寫命令之后,寫命令將會被追加 append 到 aof_buf 緩沖區的末尾
- 在服務器每結束一個事件循環之前,將會調用 flushAppendOnlyFile 函數決定是否要將 aof_buf 的內容保存到AOF文件中,可以通過配置 appendfsync 來決定。
- always:aof_buf 內容寫入并同步到 AOF 文件
- everysec:將 aof_buf 中內容寫入到 AOF 文件,如果上次同步 AOF 文件時間距離現在超過1秒,則再次對 AOF 文件進行同步
- no:將 aof_buf 內容寫入AOF文件,但是并不對 AOF 文件進行同步,同步時間由操作系統決定
- 如果不設置,默認選項將會是 everysec,因為 always 來說雖然最安全(只會丟失一次事件循環的寫命令),但是性能較差,而 everysec 模式只不過會可能丟失1秒鐘的數據,而 no 模式的效率和 everysec 相仿,但是會丟失上次同步 AOF 文件之后的所有寫命令數據。
3、Redis 持久化機制 RDB 與 AOF 的區別
- 實現方式:RDB 持久化是通過將某個時間點 Redis 服務器存儲的數據保存到 RDB 文件中來實現持久化的;AOF持久化是通過將 Redis 服務器執行的所有寫命令保存到 AOF 文件中來實現持久化的;
- 文件體積:由上述實現方式可知,RDB 持久化記錄的是結果,AOF 持久化記錄的是過程,所以 AOF 持久化生成的 AOF 文件會有體積越來越大的問題,Redis 提供了 AOF 重寫功能來減小 AOF 文件體積;
- 安全性:AOF 持久化的安全性要比 RDB 持久化的安全性高,即如果發生機器故障,AOF 持久化要比 RDB 持久化丟失的數據要少。因為 RDB 持久化會丟失上次 RDB 持久化后寫入的數據,而 AOF 持久化最多丟失1s之內寫入的數據(使用默認everysec 配置的話);
- 優先級:由于上述的安全性問題,如果 Redis 服務器開啟了 AOF 持久化功能,Redis 服務器在啟動時會使用 AOF 文件來還原數據,如果 Redis 服務器沒有開啟 AOF 持久化功能,Redis 服務器在啟動時會使用 RDB 文件來還原數據,所以 AOF 文件的優先級比 RDB 文件的優先級高。
- | RDB | AOF |
---|---|---|
啟動優先級 | 低 | 高 |
文件大小 | 小 | 大 |
恢復速度 | 快 | 慢 |
數據安全性 | 丟數據 | 根據策略決定 |
二、Redis 事務
1、Redis 事務
Redis 通過 MULTI、EXEC、WATCH 等命令來實現事務機制,事務執行過程將一系列多個命令按照順序一次性執行,并且在執行期間,事務不會被中斷,也不會去執行客戶端的其他請求,直到所有命令執行完畢。事務的執行過程如下:
- 服務端收到客戶端請求,事務以 MULTI 開始
- 如果客戶端正處于事務狀態,則會把事務放入隊列同時返回給客戶端 QUEUED,反之則直接執行這個命令
- 當收到客戶端 EXEC 命令時,WATCH 命令監視整個事務中的 key 是否有被修改,如果有則返回空回復到客戶端表示失敗,否則 Redis 會遍歷整個事務隊列,執行隊列中保存的所有命令,最后返回結果給客戶端
WATCH 的機制本身是一個 CAS 的機制,被監視的 key 會被保存到一個鏈表中,如果某個 key 被修改,那么 REDIS_DIRTY_CAS 標志將會被打開,這時服務器會拒絕執行事務。
2、Redis 事務相關命令
Redis 通過 MULTI、EXEC、DISCARD、WATCH 實現事務功能:
# MULTI 開始事務
> multi
OK
MULTI 命令將 Redis 中的 Redis_multi 選項打開,讓客戶端從非事務狀態變為事務狀態
# 命令入隊
> set bookName "LiZhengi"
QUEUED
> get bookName
QUEUED
> sadd tag "LiZhengi" "Old Book"
QUEUED
> smembers tag
QUEUED
在 Redsi 進入事務狀態后,Redis 命令并不是立即執行的,而是進入一個先進先出的事務隊列。其中返回 QUEUED 表示這個命令已經入了事務隊列。
# exec 提交事物
> exec
1) OK
2) "LiZhengi"
3) (integer) 2
4) 1) "LiZhengi"2) "Old Book"
可以看到:當執行 exec 命令時,Redis 根據客戶端所保存的事務隊列,事務隊列中的命令以先進先出的方式執行。當 exec 命令執行完畢時,Redis 會將結果保存到一個回復隊列,并將回復隊列返回給客戶端。客戶端從事務狀態退出,一個事務執行完畢。
# discard 取消事務
> multi
OK
> set bookName "LiZhengi"
QUEUED
> discard
OK
> get bookName
(nil)
discard 取消一個事務的命令,表示這個事務被取消。客戶端從事務狀態退出,回到非事務狀態,Redis_multi 選項關閉。
# watch 命令
watch 命令在事務開始之前監視任意數量的鍵:當調用 exce 命令執行事務時,如果任意一個被監視的鍵已經被其他客戶端修改了,那么整個事務不再執行,直接返回失敗。
3、關于 Pipeline
管道技術(Pipeline)是客戶端提供的一種批處理技術,用于一次處理多個 Redis 命令,從而提高整個交互的性能。
通常情況下 Redis 是單行執行的,客戶端先向服務器發送請求,服務端接收并處理請求后再把結果返回給客戶端,這種處理模式在非頻繁請求時不會有任何問題。
但如果出現集中大批量的請求時,因為每個請求都要經歷先請求再響應的過程,這就會造成網絡資源浪費,此時就需要管道技術來把所有的命令整合一次發給服務端,再一次響應給客戶端,這樣就能大大的提升了 Redis 的響應速度。
管道技術解決了多個命令集中請求時造成網絡資源浪費的問題,加快了 Redis 的響應速度,讓 Redis 擁有更高的運行速度。但要注意的一點是,管道技術本質上是客戶端提供的功能,而非 Redis 服務器端的功能。
Pipeline 與 事務相比:
- pipeline 是客戶端的行為,對于服務器來說是透明的,可以認為服務器無法區分客戶端發送來的查詢命令是以普通命令的形式還是以 pipeline 的形式發送到服務器的;
- 而事務則是實現在服務器端的行為,用戶執行 MULTI 命令時,服務器會將對應這個用戶的客戶端對象設置為一個特殊的狀態,在這個狀態下后續用戶執行的查詢命令不會被真的執行,而是被服務器緩存起來,直到用戶執行 EXEC 命令為止,服務器會將這個用戶對應的客戶端對象中緩存的命令按照提交的順序依次執行。