【Redis】持久化機制:RDB / AOF 的應用與場景

文章目錄

  • Redis 持久化
  • 一、RDB
    • 1.1 說明
    • 1.2 觸發機制
      • 手動觸發
      • 自動觸發
    • 1.3 流程說明
    • 1.4 文件處理
    • 1.5 優缺點 & 適用場景
  • 二、AOF
    • 2.1 說明
    • 2.2 使用 AOF
    • 2.3 命令寫入
    • 2.4 文件同步
    • 2.5 重寫機制
    • 2.6 啟動時數據恢復
    • 2.7 優缺點 & 適用場景
  • 三、不使用 AOF / RDB 的情況
    • 3.1 場景
    • 3.2 實現方案

Redis 持久化

Redis 本身是作用與內存中的數據庫,所以必須考慮數據持久化問題(將內存中的數據存儲到硬盤中)。

Redis 支持 RDB 與 AOF 兩種持久化機制,持久化功能有效地避免因進程退出造成數據丟失問題,當下次重啟時利用之前持久化的文件可以實現數據恢復。

在這里插入圖片描述


一、RDB

1.1 說明

  1. RDB 持久化是 Redis 默認的持久化方式,通過 快照(snapshot)來持久化數據。
    • 即把當前進程數據生成快照保存到硬盤的過程、觸發RDB持久化過程分為手動觸發自動觸發
  2. Redis 會在指定的時間間隔內生成數據的快照并保存在磁盤中(RDB 文件),通常是 .rdb 文件。(自動觸發)、也可以手動執行命令進行手動觸發

1.2 觸發機制

手動觸發

手動觸發分別對應 savebgsave 命令:

  • SAVE:會阻塞 Redis 主進程,直到 RDB 持久化完成。這個命令會在當前進程中執行持久化操作,執行過程中 Redis 會暫停所有請求,直到數據保存完成。
    • 但是對于內存較大的實例會造成長時間阻塞,基本不采用。
  • BGSAVE :在后臺異步執行RDB持久化,Redis 會生成一個子進程來執行持久化操作,主進程可以繼續處理請求。執行 BGSAVE 時,Redis 會創建一個子進程來保存數據并生成 RDB 文件。
    • 阻塞只發生在 fork 階段,一般時間很短。

Redis 內部所有涉及 RDB 的操作都類似 bgsave 的方式。

自動觸發

Redis 運行自動觸發 RDB 持久化機制,該機制在實際環境中更實用。

Redis 默認的 RDB 持久化是基于時間和寫操作的觸發條件。可以通過 redis.conf 配置文件中的 save 參數設置自動觸發的條件。

  1. 使用 save 配置。如“save m n” 表示 m 秒內數據集發生了 n 次修改,自動 RDB 持久化。比如:

    save 900 1    # 900秒(15分鐘)內至少有1次寫操作時觸發RDB
    save 300 10   # 300秒(5分鐘)內至少有10次寫操作時觸發RDB
    save 60 10000 # 60秒內至少有10000次寫操作時觸發RDB
    
  2. 從節點進行全量復制操作時,主節點自動進行RDB持久化,隨后將RDB文件內容發送給從節點。

  3. 執行 shutdown 命令關閉 Redis 時,執行 RDB 持久化。

比如在redis.conf的這個位置(內存管理)進行save配置:
在這里插入圖片描述


1.3 流程說明

BGSAVE 是主流的 RDB 持久化方式,下圖演示了其運作流程:

在這里插入圖片描述

  1. 執行 bgsave 命令時,Redis 父進程首先會檢查是否已有其他子進程正在執行,如 RDB 或 AOF 子進程。如果存在其他子進程,bgsave 命令將直接返回,不會執行。

  2. 父進程執行 fork 創建子進程,在 fork 過程中,父進程會阻塞。可以通過執行 INFO stats 命令并查看 latest_fork_usec 選項,獲取最近一次 fork 操作的耗時,單位為微秒。

  3. fork 完成后,父進程不再阻塞,bgsave 命令返回 “Background saving started” 信息,表示子進程開始生成 RDB 文件,同時父進程可以繼續處理其他命令。

  4. 子進程生成 RDB 文件,它會根據父進程的內存內容生成一個臨時快照文件,并在完成后將原有文件替換為新生成的 RDB 文件。可以通過執行 lastsave 命令來獲取最后一次成功生成 RDB 文件的時間,信息也會在 INFO 統計的 rdb_last_save_time 選項中顯示。

  5. 子進程完成任務后,發送信號給父進程,通知父進程操作已完成。隨后,父進程會更新相關的統計信息。


1.4 文件處理

  1. 保存:RDB 文件會保存在通過 dir 配置指定的目錄中(默認目錄為 /var/lib/redis/),文件名通過 dbfilename 配置指定(默認文件名為 dump.rdb)。可以通過執行 config set dir {newDir}config set dbfilename {newFilename} 動態修改目錄和文件名設置。當 Redis 重啟時,RDB 文件會保存到新的目錄。

  2. 壓縮:Redis 默認使用 LZF 算法對生成的 RDB 文件進行壓縮處理,壓縮后的文件體積遠小于內存大小。默認情況下,壓縮是開啟的,可以通過 config set rdbcompression {yes|no} 動態修改壓縮設置。

提示:雖然開啟 RDB 壓縮會消耗一定的 CPU 資源,但可以顯著減小文件大小,方便將文件保存到硬盤或通過網絡發送到從節點,因此建議開啟壓縮功能。

  1. 校驗:如果 Redis 在啟動時加載到損壞的 RDB 文件,啟動會失敗。此時,可以使用 Redis 提供的 redis-check-dump 工具檢測 RDB 文件,并獲取相應的錯誤報告。

1.5 優缺點 & 適用場景

優點:

  1. RDB 是一個緊湊壓縮的二進制文件,代表 Redis 某個時間點上的數據快照,適用于備份、全量復制等場景。比如每6h執行 bgsave 備份,并把RDB文件復制到遠程及其或者文件系統中(如hdfs)。
  2. Redis 加載 RDB 數據遠快于 AOF。在重啟Redis時恢復速度較快。
  3. RDB 文件是壓縮格式,能夠節省存儲空間。

缺點:

  1. RDB 方式數據無法做到 實時持久化 / 秒級持久化。因為 bgsave 每次運行都會執行 fork 創建子進程,開銷較大,頻繁執行成本過高。
  2. RDB 文件使用特定二進制格式保存、Redis 版本演進過程中有多個 RDB 版本,兼容性可能存在風險。
  3. 數據丟失風險較大:RDB 是基于時間間隔的快照,如果在快照之間發生了 Redis 崩潰,則會丟失在最后一次快照之后的所有數據。

適用場景:

適合用于備份和災難恢復,尤其是對于不要求非常實時的數據恢復場景。


二、AOF

2.1 說明

AOF(Append Only File)持久化:

以獨立日志的方式記錄每次寫命令,重啟時再重新執行 AOF 文件中的命令,以達到恢復數據的目的。AOF 主要作用是解決了數據持久化的實時性。

AOF 文件中的內容是 Redis 執行的所有寫命令的日志,這些命令可以用來重建數據庫狀態,目前已經是Redis持久化的主流方式。

2.2 使用 AOF

開啟 AOF 功能需要設置配置:appendonly yes ,默認是不開啟的。

在這里插入圖片描述

AOF 文件名通過 appendfilename 配置指定,默認值為 appendonly.aof,其保存目錄與 RDB 持久化方式一致,可通過 dir 配置進行設置。

AOF 的工作流程包括:命令寫入(append)、文件同步(sync)、文件重寫(rewrite)、重啟加載(load)。

AOF 工作流程如下圖所示:
AOF 工作流程圖

對上圖工作流程的解釋:

  1. 所有寫入命令會被追加到 AOF 緩沖區(aof_buf)中。
  2. 根據配置的同步策略,AOF 緩沖區會定期將數據同步到硬盤。
  3. 隨著 AOF 文件增大,Redis 會定期進行文件重寫,以壓縮文件并減小磁盤占用。
  4. 當 Redis 重啟時,可以通過加載 AOF 文件來恢復數據。

2.3 命令寫入

AOF 命令寫入的內容是文本協議格式,如 set hello world,在AOF緩沖區中會追加的是:

*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n

此處遵守的是 Redis 格式協議,Redis 選擇的是文本協議,可能有以下原因:

  1. 實現簡單
    • 文本協議比二進制協議更加容易實現
  2. 簡單性和可讀性
    • 數據以純文本的形式傳輸,格式簡單且直觀,用戶可以很容易地查看和調試通信內容
  3. 兼容性
    • 文本協議的另一個優點是它具有較高的跨平臺兼容性。所有主流的操作系統和編程語言都可以輕松地處理文本數據

AOF 過程中為什么需要 aof_buf 緩沖區?

  • 我們知道,Redis使用單線程響應命令,如果每次寫 AOF 文件都直接同步硬盤,從內存的讀寫變為IO讀寫,性能必然下降。先寫入緩沖區可以有效減少 IO 次數,同時 Redis 還可以提供多種緩沖區策略,讓用戶根據自己的需求做出合理的平衡。

2.4 文件同步

Redis 提供了多種 AOF 緩沖區同步文件策略,使用參數 appendfsync 控制。不同配置值的含義如下表所示:

表 4-1 AOF 緩沖區同步文件策略

可配置值說明
always每次命令寫入 aof_buf 后都調用 fsync 同步,完成后返回。
everysec命令寫入 aof_buf 后執行 write 操作,不進行 fsync。每秒由同步線程執行 fsync
no命令寫入 aof_buf 后執行 write 操作,由操作系統控制 fsync 的頻率。

系統調用 writefsync 的說明

  • write 操作:觸發延遲寫(delayed write)機制。Linux 內核使用頁緩沖區提高硬盤 I/O 性能。write 操作將數據寫入系統緩沖區后立即返回,實際的硬盤同步依賴系統調度機制,例如緩沖區滿或達到時間周期。若系統發生故障或宕機,未同步的數據可能丟失。
  • fsync 操作:對單個文件進行強制硬盤同步,直到數據寫入硬盤前,fsync 會阻塞。

配置說明

  • always 配置:每次寫入時都會同步 AOF 文件,性能較差。在普通的 SATA 硬盤上,通常只能支持幾百 TPS 寫入。除非數據至關重要,否則不推薦使用此配置。
  • no 配置:由于操作系統同步策略不可控,性能較高,但數據丟失的風險大增。除非數據不重要,否則不推薦使用。
  • everysec 配置:為默認配置,也是推薦配置,兼顧了數據安全性與性能。理論上最多丟失 1 秒的數據,適用于大多數場景。

2.5 重寫機制

隨著 Redis 持續將命令寫入 AOF 文件,文件體積會不斷增大。為了優化存儲和性能,Redis 引入了 AOF 重寫機制,它會壓縮 AOF 文件的體積。

AOF 重寫的過程是將 Redis 進程內的數據轉換為寫命令,并同步到新的 AOF 文件中。

為什么重寫后的 AOF 文件會變小? 主要原因如下:

  • 剔除超時數據:進程內已經超時的數據不會寫入重寫后的文件。
  • 刪除無效命令:舊 AOF 文件中的無效命令(如 delhdelsrem 等)會在重寫時被刪除,僅保留數據的最終狀態。
  • 合并多個寫操作:多個連續的寫操作可以合并成一條命令。例如,lpush list alpush list blpush list c 可以合并為 lpush list a b c

重寫后的 AOF 文件較小,既降低了硬盤的空間占用,又能提高 Redis 啟動時的數據恢復速度。

AOF 重寫過程可以通過手動和自動兩種方式觸發:

  • 手動觸發:使用 bgrewriteaof 命令。
  • 自動觸發:根據 auto-aof-rewrite-min-sizeauto-aof-rewrite-percentage 參數自動觸發重寫。
    • auto-aof-rewrite-min-size:定義觸發重寫時 AOF 文件的最小大小,默認為 64MB。
    • auto-aof-rewrite-percentage:定義當前 AOF 文件大小相對于上次重寫時增加的比例。

在這里插入圖片描述

AOF 重寫的執行流程:

  1. 執行 AOF 重寫請求
    如果當前進程正在執行 AOF 重寫,新的請求會被延遲。如果當前正在執行 bgsave 操作,重寫命令會等到 bgsave 完成后再執行。

  2. 父進程執行 fork 創建子進程
    父進程會通過 fork 創建子進程進行重寫操作。

  3. 重寫過程

    • a. 父進程在 fork 后繼續響應其他命令,所有修改操作都會寫入 AOF 緩沖區,并根據 appendfsync 策略同步到硬盤,確保舊 AOF 文件的數據完整性。
    • b. 子進程只有在 fork 之前的內存數據,父進程中的修改操作會被寫入 AOF 重寫緩沖區。
  4. 子進程重寫 AOF 文件
    子進程根據內存快照,將命令合并并寫入新的 AOF 文件中。

  5. 完成重寫

    • a. 子進程寫入新文件后,發送信號給父進程。
    • b. 父進程將 AOF 重寫緩沖區內臨時保存的命令追加到新 AOF 文件中。
    • c. 父進程用新生成的 AOF 文件替換舊的 AOF 文件。

通過上述重寫機制,Redis 能有效優化 AOF 文件的體積,提升性能并減少存儲消耗。


2.6 啟動時數據恢復

當 Redis 啟動時,會根據 RDB 和 AOF 文件的內容,進行數據恢復。

在這里插入圖片描述


2.7 優缺點 & 適用場景

優點:

  1. AOF 可以實現更高的持久化安全性,相比于 RDB,它更能保證數據不丟失。
  2. 如果 Redis 崩潰,可以從 AOF 文件恢復到最后一個寫操作。
  3. 可設置不同的同步策略,以實現平衡的性能和持久化保障。

缺點:

  1. AOF 文件比 RDB 文件更大,因為它記錄的是每個寫操作的日志,可能會占用更多磁盤空間。
  2. 寫操作會稍微慢一些,因為每次寫入命令都要追加到 AOF 文件中,雖然可以通過異步寫入來緩解性能問題。
  3. AOF 恢復數據時的速度較慢,因為需要重放所有寫命令。

適用場景:

AOF 適合用于要求較高數據持久性的場景,例如需要盡量避免數據丟失的應用。


三、不使用 AOF / RDB 的情況

3.1 場景

在實際業務場景下,如果不使用 AOF 或 RDB,Redis 可以與 MySQL 等外部數據庫結合,來實現數據的持久化。這種方案通常適用于以下情況:

  1. 緩存加速 + 持久化分離

    • 特點
      • Redis 作為高性能緩存,MySQL 作為真實數據源。
      • 適合讀多寫少的業務(如商品詳情頁、用戶畫像)。
    • 同步策略
      • 讀:優先讀 Redis,未命中則查 MySQL 并回填。
      • 寫:直接寫 MySQL,并刪除/更新 Redis 緩存(Cache-Aside 模式)。
  2. 臨時數據 + 永久存儲分離

    • 特點
      • Redis 存儲短期高頻數據(如會話、排行榜),MySQL 存儲長期數據。
      • 適合時效性數據(如 30 天內的訂單狀態)。
    • 同步策略
      • 通過 TTL 自動清理 Redis 數據,關鍵數據異步歸檔到 MySQL。
  3. 高并發寫入緩沖

    • 特點
      • 用 Redis 緩沖突發寫入(如秒殺庫存),再平滑同步到 MySQL。
      • 適合寫密集型業務(如點擊計數、日志采集)。
    • 同步策略
      • Redis 累加計數,每小時同步一次聚合結果到 MySQL。

3.2 實現方案

  1. 雙寫模式(Write-Through)

    • 機制
      應用同時寫入 Redis 和 MySQL,保持雙數據源一致。
      def set_user(user_id, data):# 同步寫 MySQLmysql.execute("REPLACE INTO users VALUES (%s, %s)", (user_id, data))# 寫 Redisredis.set(f"user:{user_id}", data)
      
    • 優點:強一致性
    • 缺點:寫入性能下降,需處理事務回滾(如 MySQL 失敗需回滾 Redis)。
  2. 異步同步(Write-Behind)

    • 機制
      先寫 Redis,再通過消息隊列或定時任務異步同步到 MySQL。
      def set_user(user_id, data):redis.set(f"user:{user_id}", data)# 發送到消息隊列(如 Kafka/RabbitMQ)mq.publish("user_update", {"id": user_id, "data": data})# 消費者異步處理 MySQL 寫入
      
    • 優點:高性能,解耦
    • 缺點:存在短暫不一致窗口。
  3. 定時批量同步

    • 機制
      定期掃描 Redis 數據批量寫入 MySQL(適合冷數據)。
      -- MySQL 表設計示例
      CREATE TABLE redis_backup (`key` VARCHAR(255) PRIMARY KEY,`value` TEXT,`expire_time` DATETIME
      );
      

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/85341.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/85341.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/85341.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python 企業級開發與DevOps實踐

https://www.python.org/static/community_logos/python-logo-master-v3-TM.png 大型項目結構與設計模式 項目結構規范 text 復制 下載 enterprise_app/ ├── docs/ # 項目文檔 ├── tests/ # 測試代碼 │ ├── unit/ …

E結構體基礎.go

前言:結構體是一種用戶自定義的數據類型,它可以將多個不同類型的數據整合在一起,形成一個有機的整體。這就好比在現實生活中,我們有各種各樣的物品,它們各自有不同的屬性和用途,而結構體就像是一個收納箱&a…

Spring @Autowired 依賴注入全解析

Autowired 是 Spring 框架中實現依賴注入的核心注解,其自動裝配過程可分為以下步驟,結合了類型匹配、名稱解析和容器協作機制: 1. 組件掃描與 Bean 定義注冊 掃描階段:Spring 容器啟動時,通過 ComponentScan 或 XML 配…

將git的普通目錄用idea初始化為maven項目

在 IntelliJ IDEA 中將一個已存在的 Git 目錄初始化為 Maven 項目,可以通過以下步驟完成。這些步驟假設你已經有一個包含代碼的 Git 倉庫,并希望將其轉換為 Maven 項目結構,以便更好地管理依賴和構建。 步驟 1:打開或導入 Git 倉庫…

Vue 中 key 屬性的深入解析:改變 key 導致組件銷毀與重建

一、key 屬性的核心作用 在 Vue 中,key是一個特殊的屬性,主要用于協助 Vue 的虛擬 DOM(Virtual DOM)算法高效地更新實際 DOM。它的核心作用可以概括為: 唯一標識節點:為每個節點提供一個唯一的身份標識優化 Diff 算法:幫助 Vue 準確判斷兩個節點是否為同一節點(如for循…

【音視頻】PJSIP庫——示例簡介、C++類說明

1、簡介 pjsip庫的源碼中有很多示例,是入門pjsip的第一手資料,下面將各個示例所演示的功能列舉出來,以便下一步學習; 最后總結下C++接口主要類及成員函數說明。 2、示例介紹 2.1 音視頻處理 aectest 音頻回聲消除測試工具,用于演示音頻處理模塊中的回聲消除(AEC)功能…

網站用CDN可以防DDoS和CC攻擊嗎?

現在市面上常見有兩種CDN,加速CDN與高防CDN,這兩種的區別還是很大的。 加速CDN: 加速CDN基本上都是共享、無防節點,主要做的是加速,所以價格也會相對較低,大陸地區的CDN都需要備案域名接入使用。 高防CD…

【圖片識別改名】批量識別圖片中的文字對圖片進行改名,識別文字對圖片重新命名的操作步驟和注意事項

一、應用場景 快遞單號識別與管理:在快遞業務中,每天會產生大量的快遞面單圖片。通過咕嘎OCR批量識別面單上的快遞單號等關鍵信息,并以此對圖片進行重命名,方便工作人員快速查詢和管理快遞包裹的物流信息,提高快遞處理…

先理解軟件工程,再談AI輔助研發

摘要: 近期行業內對“AI賦能軟件工程”的討論,大多聚焦于代碼生成等局部提效,這是一種危險的短視。本文旨在糾正將“軟件開發”等同于“編碼”的普遍誤解,深入探討軟件工程的系統性本質。我們將論證,若缺乏堅實的工程體…

Android軟件適配遙控器需求-案例經驗分享

不分大屏產品需要有遙控器功能,這里分享部分實戰經驗 文章目錄 前言一、案例部分效果圖二、項目基礎架構三、焦點基礎知識適配遙控器基礎-焦點問題焦點管理明確焦點狀態布局實現硬編碼實現引入第三方自定義組件實現 焦點順序作用 初始焦點 requestFocus 按鍵處理獲取…

《HTTP權威指南》 第3章 HTTP報文

報文是如何流動的 HTTP報文是在HTTP程序之間發送的數據塊。數據塊以一些文本形式的元信息開頭。 報文方向有:流入、流出、上游、下游。 流入和流出描述事務處理的方向,流入和流出是基于服務器的描述。 流入:客戶端發往服務器的請求報文 流…

Kafka 集群架構與高可用方案設計(二)

Kafka 集群架構與高可用方案的優化策略 合理配置參數 在 Kafka 集群的配置中,參數的合理設置對于系統的高可用性和性能表現起著關鍵作用。例如,min.insync.replicas參數定義了 ISR(In-Sync Replicas,同步副本)集合中…

47-Oracle ASH報告解讀

上一期生成了ASH報告后,就需要解讀報告關鍵信息。ASH的使用可以快速定位瞬時性能問題。生產環境的場景時間緊、任務重,但是必須要結合具體業務分析,同時借助其他工具做報告做趨勢分析。 一、ASH 技術原理? ?1. 核心機制? ?采樣原理?&a…

“本地化思維+模塊化體驗”:一款輕量數據中心監控系統的真實測評

“本地化思維模塊化體驗”:一款輕量數據中心監控系統的真實測評 在數據中心運維逐步精細化的今天,一款真正貼合本地用戶習慣、設計有溫度的系統并不多見。近期體驗了一款功能全面、邏輯清晰的監控平臺,給人留下了深刻印象。并不是廣。今天就從…

詞編碼模型有哪些

詞編碼模型有哪些 詞編碼模型在高維向量空間的關系解析與實例說明 如Word2Vec、BERT、Qwen等 一、高維向量空間的基礎概念 詞編碼模型(如Word2Vec、BERT、Qwen等)的核心是將自然語言符號映射為稠密的高維向量,使語義相近的詞匯在向量空間中位置接近。以Qwen模型為例,其…

elementui el-select 獲取value和label 以及 對象的方法

獲取 el-select 的 value 和 label 值 在 Element UI 的 el-select 組件中,可以通過以下方法獲取選項的 value 和 label 值。 1、綁定 v-model 獲取 value el-select 通常通過 v-model 綁定 value 值,直接訪問綁定的變量即可獲取當前選中的 value。…

樹莓派與嵌入式系統實驗報告

一、Linux 系統編譯工具鏈實踐:mininim 源碼編譯 虛擬機 Ubuntu 編譯流程 環境配置問題 編譯時遇到虛擬機無法聯網的情況,通過連接個人熱點解決(校園網限制導致無法訪問外部資源)。 執行 ./bootstrap 時報錯 gnulib-tool: command…

IDEA部署redis測試

新建springboot,項目改為:testredis E:\ideaproject\testredis\src\main\java\org\example\testredis\TestredisApplication.java 代碼為: package org.example.testredis;import org.springframework.boot.SpringApplication; import org.…

旅游服務禮儀實訓室:從歷史演進到未來創新的實踐探索

一、旅游服務禮儀實訓室的歷史演進:從禮制規范到職業化培養 旅游服務禮儀實訓室的建設并非一蹴而就,其發展歷程與人類對禮儀認知的深化及職業教育體系的完善密切相關。 1. 古代禮儀教育的萌芽 禮儀作為社會行為規范,最早可追溯至中國夏商周…

Could not find a declaration file for module ‘..XX‘.

1. 添加 Vue 聲明文件 如果您還沒有為 .vue 文件創建類型聲明,可以通過創建一個新的類型聲明文件來解決該問題。 步驟: 在您的項目根目錄下創建一個名為 shims-vue.d.ts 的文件(您可以選擇其他名稱,但建議使用常見名稱以便于識…