四、redis持久化

Redis 支持RDB和AOF兩種持久化機制,之所以存在兩種,是因為它們各自適用于不同的場景、不同的階段。我接下來對其進行介紹,并分析我們在實際場景中如何使用配置。

RDB

有兩個重要命令,save和bgsave,一個是同步,一個是異步,完成后會在指定的目錄生成一份壓縮文件(默認是dump.rdb,使用LZF算法,可以通過dbfilename配置,dir配置文件夾)。

  • save: 阻塞當前Redis服務器、直到RDB過程完成,因為會阻塞線程,所以基本被廢棄了。
  • bgsave: Redis主線程會進行fork操作,創(chuàng)建子進程,RDB持久化過程由子進程負責,雖然也會有阻塞,但只阻塞fork階段,這個命令是對save的一個改進
  • 自動保存,在程序中以下情景會自動觸發(fā)bgsave
    1. 使用save相關配置,如"save m n",表示m秒內數據存在n次修改時自動觸發(fā),可以配置多個規(guī)則
    2. 如果從節(jié)點執(zhí)行全量復制,那么master節(jié)點會自動執(zhí)行bgsave,然后將RDB文件發(fā)給從節(jié)點
    3. 執(zhí)行debug reload 命令重新加載Redis時,也會觸發(fā)
    4. 在shutdown命令執(zhí)行后,如果沒有開啟AOF持久化功能,會觸發(fā)bgsave

優(yōu)勢:

  • 是一個壓縮后的二進制文件,代表某個時間點的快照,特別適合發(fā)送到其他節(jié)點。
  • Redis加載RDB的速度遠遠快于AOF

缺陷

  • 沒辦法實時的持久化,bgsave是一個重量級的操作,不可能頻繁執(zhí)行
  • RDB文件使用特定格式保存

AOF

為了應對RDB的缺點,AOF方式產生。以獨立日志的方式記錄每次命令,重啟的時候再重新執(zhí)行AOF文件中的命令達到恢復數據的目的。

  • 開啟
    默認是不開啟的,需要配置 appendonly yes,默認文件名是appendonly.aof,路徑與RDB一致。

  • 工作流程

    1. 將寫入命令追加到aof_buf緩沖區(qū)中
    2. AOF緩沖區(qū)根據對應的策略向硬盤做同步工作fsync
    3. 隨著AOF文件越來越大,需要定期重寫,達到壓縮的目的
    4. 當redis重啟時,可以加載AOF文件進行數據恢復
  • 文件格式
    為文本協(xié)議格式,也就是之前講過的通信協(xié)議的格式,如:·*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n
    之所以采用文本協(xié)議,是因為其兼容性好,而且可讀性比較強,可以直接修改

  • 文件同步: appendfsync配置

    1. always 寫入aof_buf后立即同步到文件,fsync完成后線程返回
    2. everysec 建議的配置,命令寫入aof_buf后調用系統(tǒng)write操作,完成后線程返回。fsync同步文件操作,由另一個線程每秒調用一次。
    3. no 寫入aof_buf后調用系統(tǒng)write操作,不對AOF文件做fsync同步,同步的步驟由系統(tǒng)來做,最長30s
    • write:利用頁緩沖區(qū)來提高硬盤IO性能,會有短暫的延遲,如果真正同步之前發(fā)生宕機,則會丟失數據。因此系統(tǒng)同時提供了fsync、fdatasync等同步函數,可以強制操作系統(tǒng)立刻將緩沖區(qū)中的數據寫入到硬盤里,從而確保數據的安全性
    • fsync:針對單個文件操作(比如AOF文件),做強制硬盤同步,fsync將阻塞直到寫入硬盤后返回。
  • 重寫機制,重寫采用了以下方法實現了壓縮

    1. 進程內超時的數據不再寫入
    2. 無效命令不再寫入(也就是中間過程)
    3. 合并多條命令,比如lpush list a,lpush list b -> lpush list a b c.
    • 手動觸發(fā): bgrewriteaof
    • 自動觸發(fā): auto-aof-rewrite-min-size和auto-aof-rewrite-percentage
    • 重寫過程: 主進程fork一個新進程,并使用AOF重寫緩沖區(qū)保存重寫期間的數據。重寫完成后,父進程吧重寫緩沖區(qū)的數據刷新到新的文件。

重啟加載

記住,優(yōu)先加載AOF

重啟加載

運維優(yōu)化

  1. fork操作
    fork操作是一個重量級操作,子進程會復制父進程的空間內存頁表,在搞ops情況下有可能阻塞大量的命令。

    • 優(yōu)先使用物理機,或者高效的虛擬化技術
    • 控制Redis實例最大可用內存,耗時時間跟內存(內存頁)成正比
    • 合理配置Linux內存分配
    • 降低fork的頻率,也就是放款AOF自動觸發(fā)的機制
  2. 子進程

    • cpu 在子進程將進程中的文件分批寫入的時候消耗比較大
    • Redis是密集型服務,所以不要做單核綁定(子進程會搶占),可以使用多實例部署的方式
    • 內存,子進程共享父進程的內存快照,在新命令時,父進程會創(chuàng)建內存頁副本,這一部分是增加的內存(AOF還有重寫緩沖區(qū))。
    • 因此對于內存,盡量保證只有一個子進程,另外不要再大量寫入時觸發(fā)重寫操作。
  3. AOF阻塞
    在子線程同步磁盤時,主線程會不斷對比上次AOF同步時間,如果超過2S(everysec方式),則會阻塞等待。如果發(fā)生阻塞,很可能是磁盤IO存在高負荷,導致同步變慢。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 本文是《Redis開發(fā)與運維》的學習筆記。內容大部分摘自此書。 眾所周知,redis是內存數據庫,它把數據存儲在內...
    大數據Zone閱讀 619評論 0 3
  • 前言 在上一篇文章中,介紹了Redis內存模型,從這篇文章開始,將依次介紹Redis高可用相關的知識——持久化、復...
    Java架構閱讀 2,500評論 3 21
  • Redis支持RDB和AOF兩種持久化機制,持久化功能有效地避免因進程退出造成的數據丟失問題,當下次重啟時利用之前...
    xuxw閱讀 2,197評論 0 0
  • 一、Redis高可用概述 在介紹Redis高可用之前,先說明一下在Redis的語境中高可用的含義。 我們知道,在w...
    空語閱讀 1,672評論 0 2
  • 一、Redis高可用概述 在介紹Redis高可用之前,先說明一下在Redis的語境中高可用的含義。 我們知道,在w...
    java架構源閱讀 215評論 0 0

友情鏈接更多精彩內容