Redis持久化方案

      網友投稿 882 2022-05-28

      目錄

      文章目錄

      目錄

      RDB

      觸發 RDB 持久化

      RDB 執行流程

      RDB 常用配置

      AOF

      AOF 執行流程

      命令寫入

      文件同步

      文件重寫

      重啟加載

      AOF 常用配置

      性能問題與解決方案

      Redis M/S 是否開啟持久化?

      RDB

      RDB 持久化是把當前進程數據生成快照保存到硬盤的過程。 觸發 RDB 持久化過程分為手動觸發和自動觸發。RDB 完成后會自動生成一個文件,保存在 dir 配置的指定目錄下,文件名是 dbfileName 指定。

      RDB 文件是經過壓縮的二進制文件,存儲路徑既可以在啟動前配置,也可以通過命令動態設定。動態設定存儲路徑在磁盤損害或空間不足時非常有用,命令為:config set dir {newdir} 和 config set dbfilename {newFileName}。

      Redis 默認會采用 LZF 算法對生成的 RDB 文件做壓縮處理,壓縮后的文件遠遠小于內存大小,默認開啟。

      RDB 文件在 Redis 啟動時自動載入,沒有專門的命令。但是由于 AOF 的優先級更高,因此當 AOF 開啟時,Redis 會優先載入 AOF 文件來恢復數據。只有當 AOF 關閉時,才會檢測 RDB 文件,并自動載入。服務器載入 RDB 文件期間處于阻塞狀態,直到載入完成為止。同時,在載入 RDB 文件的過程中會對 RDB 文件進行校驗,如果文件損壞,則日志中會打印錯誤,Redis 啟動失敗。

      RDB 的優點:

      RDB 是一個緊湊壓縮的二進制文件,代表 Redis 在某個時間點上的數據快照。非常適用于備份,全量復制等場景。比如每 6 小時執行 bgsave 備份,并把 RDB 文件拷貝到遠程機器或者文件系統中,用于災難恢復。

      Redis 加載 RDB 恢復數據遠遠快于 AOF 的方式。

      RDB 的缺點:

      RDB 方式數據沒辦法做到實時持久化/秒級持久化。因為 bgsave 每次運行都要執行 fork 操作創建子進程,屬于重量級操作,頻繁執行成本過高。

      RDB 文件使用特定二進制格式保存, Redis 版本演進過程中有多個格式的 RDB 版本, 存在老版本 Redis 服務無法兼容新版 RDB 格式的問題。

      觸發 RDB 持久化

      手動觸發:命令有 save 和 bgsave

      save:該命令會阻塞 Redis 服務器,直到 RDB 的過程完成,已經被廢棄,因此線上不建議使用。

      bgsave:每次進行 RDB 進程都會 fork 一個子進程,由子進程完成 RDB 的操作,因此阻塞只會發生在 fork 階段,一般時間很短。

      NOTE:因為 save 命令的整個過程都會阻塞服務器,因此已經被廢棄,線上環境要杜絕 save 命令的使用。

      自動觸發的場景:

      根據配置項 save m n 自動觸發,指定當 m 秒內發生 n 次變化時,會觸發 bgsave。

      在主從復制場景下,如果 SLAVE 執行全量復制操作,則 MASTER 會執行 bgsave 命令,并將 RDB 文件發送給 SLAVE。

      執行 debug reload 命令重新加載 Redis 時, 也會自動觸發 bgsave 操作。

      默認情況下執行 shutdown 命令時, 如果沒有開啟 AOF 持久化功能則自動執行 bgsave。

      RDB 執行流程

      執行 bgsave 命令后,會先判斷是否存在 AOF 或者 RDB 的子進程,如果存在,直接返回。

      父進程 fork 操作創建一個子進程,fork 操作中父進程會被阻塞。

      fork 完成后,子進程開始根據父進程的內存生成臨時快照文件,完成后對原有的 RDB 文件進行替換。執行 lastsave 命令可以查看最近一次的 RDB 時間。

      子進程創建RDB文件,根據父進程內存快照生成臨時快照文件,完成后對原有文件進行原子替換。

      子進程完成后發送信號給父進程,父進程更新統計信息。

      RDB 常用配置

      save m n:bgsave 自動觸發的條件。如果沒有 save m n 配置,相當于自動的 RDB 持久化關閉,不過此時仍可以通過其他方式觸發。

      stop-writes-on-bgsave-error yes:當 bgsave 出現錯誤時,Redis 是否停止執行寫命令;

      設置為 yes,則當硬盤出現問題時,可以及時發現,避免數據的大量丟失;

      設置為 no,則 Redis 無視 bgsave 的錯誤繼續執行寫命令,當對 Redis 服務器的操作系統(尤其是硬盤)使用了監控時,該選項考慮設置為 no。

      rdbcompression yes:是否開啟 RDB 文件壓縮。

      rdbchecksum yes:是否開啟 RDB 文件的校驗,在寫入文件和讀取文件時都起作用。關閉 checksum 在寫入文件和啟動文件時大約能帶來 10% 的性能提升,但是數據損壞時無法發現。

      dbfilename dump.rdb:RDB 文件名。

      dir ./:RDB 文件和 AOF 文件所在目錄。

      AOF

      AOF(Append Only File)持久化,以獨立日志的方式記錄每次寫命令,即:每次寫命令都會被記錄到單獨的日志文件中,重啟時再重新執行 AOF 文件中的命令達到恢復數據的目的。AOF 的主要作用是解決了數據持久化的實時性, 目前已經是 Redis 持久化的主流方式。

      Redis 服務器默認開啟 RDB,關閉 AOF。要開啟 AOF,需要在配置文件中配置:appendonly yes。AOF 文件名通過 appendfilename 配置設置, 默認文件名是 appendonly.aof。保存路徑同 RDB 持久化方式一致,通過 dir 配置指定。

      AOF 執行流程

      由于 AOF 會記錄 Redis 的每條寫命令,因此 AOF 不需要設置觸發條件。

      與載入 RDB 文件類似,Redis 啟動時載入 AOF 文件,也會進行校驗,如果文件損壞,則日志中會打印錯誤,Redis 啟動失敗。但如果是 AOF 文件結尾不完整,例如:機器突然宕機等容易導致文件尾部不完整,且 aof-load-truncated(默認是開啟的)參數開啟,則日志中會輸出警告,Redis 忽略掉 AOF 文件的尾部,啟動成功。

      注意:因為 Redis 的命令只能在客戶端上下文中執行,而載入 AO F文件時命令是直接從文件中讀取的,并不是由客戶端發送。因此 Redis 服務器在載入 AOF 文件之前,會先創建一個沒有網絡連接的客戶端(偽客戶端),之后用它來執行 AOF 文件中的命令,命令執行的效果與帶網絡連接的客戶端完全一樣。

      AOF 整體的執行流程分為 4 個步驟:

      命令寫入(追加,Append):將 Redis 的寫命令追加到緩沖區 aof_buf。

      文件同步(Sync):根據不同的同步策略將 aof_buf 中的內容同步到硬盤;

      文件重寫(Rewrite):定期重寫 AOF 文件,達到壓縮的目的。

      重啟加載

      命令寫入

      AOF 命令寫入,又稱命令追加,內容直接是文本協議格式。例如 set hello world 這條命令, 在 AOF 緩沖區會追加如下文本:

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

      1

      需要注意的是,Redis 先將寫命令追加到緩沖區,而不是直接寫入文件系統,主要是為了避免每次有寫命令都直接寫入硬盤,導致硬盤 IO 成為 Redis 負載的瓶頸。這是大多數高性能數據庫的常規設計。

      Redis 使用單線程響應命令,如果每次寫 AOF 文件命令都直接追加到硬盤, 那么性能完全取決于當前硬盤負載。先寫入緩沖區 aof_buf 中, 還有另一個好處, Redis 可以提供多種緩沖區同步硬盤的策略,在性能和安全性方面做出平衡。

      文件同步

      Redis 提供了多種 AOF 緩存區的文件同步策略,策略涉及到操作系統的 write 函數和 fsync 函數:為了提高文件寫入效率,在現代操作系統中,當用戶調用 write 函數將數據寫入文件時,操作系統通常會將數據暫存到一個內存緩沖區里,當緩沖區被填滿或超過了指定時限后,才真正將緩沖區的數據寫入到硬盤里。這樣的操作雖然提高了效率,但也帶來了安全問題,例如:如果計算機停機,內存緩沖區中的數據會丟失。因此系統同時提供了 fsync、fdatasync 等同步函數,可以強制操作系統立刻將緩沖區中的數據寫入到硬盤里,從而確保數據的安全性。

      Redis 的持久化方案

      AOF 緩存區的同步文件策略由配置項 appendfsync 控制,具有以下參數類型:

      always:每次寫入都要同步 AOF 文件,即:命令寫入 aof_buf 后立即調用系統 fsync 函數操作同步到 AOF 文件,fsync 完成后線程返回。這種情況下,每次有寫命令都要同步到 AOF 文件,硬盤 IO 成為了性能瓶頸。在一般的 SATA 硬盤上,Redis 只能支持大約幾百 TPS 寫入,即便是 SSD 固態硬盤,每秒大約也只能處理幾萬個命令,而且會大大降低 SSD 的壽命。 顯然跟 Redis 高性能特性背道而馳,不建議配置。

      no:命令寫入 aof_buf 后調用系統 write 函數操作,因為不對 AOF 文件做 fsync 同步,而是由操作系統負責,同步周期通常為 30 秒,但這種同步的時間是不可控的,且緩沖區中堆積的數據會很多,數據安全性無法保證。雖然提升了性能,但數據安全性無法保證。

      everysec(默認),建議使用。命令寫入 aof_buf 后調用系統 write 操作,write 完成后線程返回。fsync 同步文件操作由專門的線程每秒調用一次。是前述兩種策略的折中,是性能和數據安全性的平衡。

      做到兼顧性能和數據安全性。理論上只有在系統突然宕機的情況下丟失 1 秒的數據。

      文件重寫

      為什么要文件重寫呢? 因為過大的 AOF 文件不僅會影響服務器的正常運行,也會導致數據恢復需要的時間過長。文件重寫能夠使得 AOF 文件的體積變得更小,從而使得可以更快的被 Redis 加載。

      文件重寫是指定期重寫 AOF 文件,減小 AOF 文件的體積。需要注意的是,AOF 重寫是把 Redis 進程內的數據轉化為寫命令,同步到新的 AOF 文件,不會對舊的 AOF 文件進行任何讀取、寫入操作。

      值得注意的是,文件重寫雖然是強烈推薦的,但并不是必須的。即使沒有文件重寫,數據也可以被持久化并在 Redis 啟動的時候導入。因此在一些場景中,會關閉自動的文件重寫,然后通過定時任務在每天的某一時刻定時執行。

      文件重寫之所以能夠壓縮 AOF 文件,是基于 3 個現實前提:

      過期的數據不再寫入文件。

      無效的命令不再寫入文件。

      多條命令可以合并為一個。

      重寫過程分為手動觸發和自動觸發:

      手動觸發:直接使用 bgrewriteaof 命令,fork 子進程進行具體的工作,父進程僅在 fork 時被阻塞。

      自動觸發:根據 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 參數確定自動觸發時機。

      auto-aof-rewrite-min-size:表示運行 AOF 重寫時文件最小體積, 默認為 64MB。

      auto-aof-rewrite-percentage:代表當前 AOF 文件空間(aof_current_size) 和上一次重寫后 AOF 文件空間(aof_base_size) 的比值。

      自動觸發時機相當于:

      aof_current_size > auto-aof-rewrite-minsize && (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewritepercentage

      1

      其中,aof_current_size 和 aof_base_size 可以在 info Persistence 統計信息中查看到。

      注意,只有當 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 兩個參數同時滿足時,才會自動觸發 AOF 重寫,即 bgrewriteaof 命令操作。

      Redis 內部進行文件重寫的流程:

      重寫期間,主線程并沒有阻塞,而是在執行其他的操作命令,依然會向舊的 AOF 文件寫入數據,這樣能夠保證備份的最終完整性,如果數據重寫失敗,也能保證數據不會丟失。

      為了把重寫期間響應的寫入信息也寫入到新的文件中,因此也會為子進程保留一個緩沖區,防止新寫的文件丟失數據。

      重寫是直接把當前內存的數據生成對應命令,并不需要讀取老的 AOF 文件進行分析、命令合并。

      AOF 文件直接采用的文本協議,主要是兼容性好、追加方便、可讀性高可認為修改修復。

      無論是 RDB 還是 AOF 都是先寫入一個臨時文件,然后通過重命名完成文件的替換。

      AOF 的優點:使用 AOF 持久化會讓 Redis 變得非常耐久:你可以設置不同的 fsync 策略,比如無 fsync ,每秒鐘一次 fsync ,或者每次執行寫入命令時 fsync 。AOF 的默認策略為每秒鐘 fsync 一次,在這種配置下,Redis 仍然可以保持良好的性能,并且就算發生故障停機,也最多只會丟失一秒鐘的數據(fsync 會在后臺線程執行,所以主線程可以繼續努力地處理命令請求)。

      AOF 的缺點:

      對于相同的數據集來說,AOF 文件的體積通常要大于 RDB 文件的體積。根據所使用的 fsync 策略,AOF 的速度可能會慢于 RDB。在一般情況下, 每秒 fsync 的性能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負荷之下也是如此。不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間。

      數據恢復速度相對于 RDB 比較慢。

      重啟加載

      無論是 RDB 還是 AOF 都可用于服務器重啟時的數據恢復,執行流程如下圖:

      上圖很清晰的分析了 Redis 啟動恢復數據的流程,先檢查 AOF 文件是否開啟,文件是否存在,再檢查 RDB 是否開啟,文件是否存在。

      AOF 常用配置

      appendonly no:是否開啟 AOF。

      appendfilename:AOF 文件名。

      dir ./:RDB 文件和 AOF 文件所在目錄。

      appendfsync everysec:fsync 持久化策略。

      no-appendfsync-on-rewrite no:AOF 重寫期間是否禁止 fsync。如果開啟該選項,可以減輕文件重寫時 CPU 和硬盤的負載(尤其是硬盤),但是可能會丟失 AOF 重寫期間的數據;需要在負載和安全性之間進行平衡。

      auto-aof-rewrite-percentage 100:文件重寫觸發條件之一。

      auto-aof-rewrite-min-size 64mb:文件重寫觸發提交之一。

      aof-load-truncated yes:如果 AOF 文件結尾損壞,Redis 啟動時是否仍載入 AOF 文件。

      性能問題與解決方案

      通過上面的分析,我們都知道 RDB 的快照、AOF 的重寫都需要 fork,這是一個重量級操作,會對 Redis 造成阻塞。因此為了不影響 Redis 主進程響應,我們需要盡可能降低阻塞。

      優先使用物理機或者高效支持 fork 操作的虛擬化技術。

      控制 Redis 實例最大可用內存,fork 耗時跟內存量成正比,線上建議每個 Redis 實例內存控制在 10GB 以內。

      合理配置 Linux 內存分配策略,避免物理內存不足導致 fork 失敗。

      降低 fork 操作的頻率,如適度放寬 AOF 自動觸發時機,避免不必要的全量復制等。

      Redis M/S 是否開啟持久化?

      極端情況下可以容忍全量數據丟失,那么建議 Master 關閉持久化,Slave 關閉持久化;

      極端情況下不能容忍全量數據丟失,但可以容忍部分數據丟失,如果內存數據集較小且不會增長建議 Master 開啟 RDB,Slave 開啟 RDB;如果數據集很大,或不確定數據集增長趨勢,建議 Master 關閉持久化,Slave 開啟 RDB。開啟 RDB 需要 CPU 和磁盤性能保障。如果 Master 關閉持久化,Slave 開啟 RDB 需要保證 Slave 的 RDB 不會被 Master 誤重啟所覆蓋,這里提供幾種方案:

      重啟腳本包一層命令先網絡請求加載備機備份目錄下的 RDB 文件后再執行 Start,可以防止誤重啟,但備機調整部署可能需要調整腳本,主機打開持久化也需要調整腳本。

      定時將 RDB 文件通過網絡 I/O 傳給 Master 節點(文件大比較耗時,文件增長需要考慮定時腳本執行間隔,否則會造成持續的網絡 I/O),而且也會有一定數據損失。

      定時備份 Slave 的 RDB 到備份目錄,不做任何其他操作,誤重啟時人工拷貝 RDB 到 Master 節點(會有一定數據損失)。

      最大限度需要數據無損,建議 Master 開啟 AOF,Slave 開啟 AOF。開啟 AOF 需要 CPU 和磁盤性能保障。開啟 AOF 建議 fsync 同步刷盤使用 everysec,自定義腳本在應用空閑時定時做 bgrewrite,bgrewrite 期間增量數據做緩沖。

      Redis 任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:ECCV 2020 實例分割+全景分割論文大盤點
      下一篇:cmd應對文件夾變成了exe
      相關文章
      国产精品亚洲lv粉色| 久久久久亚洲Av片无码v| 国产成人久久精品亚洲小说| 亚洲精品中文字幕无码AV| 亚洲中文字幕在线第六区| 亚洲人成网站色在线入口| 国产成人亚洲综合a∨| 色偷偷亚洲男人天堂| 亚洲aⅴ天堂av天堂无码麻豆| 亚洲AV综合永久无码精品天堂| 亚洲精品宾馆在线精品酒店| 亚洲欧美第一成人网站7777| 亚洲中文字幕无码mv| 亚洲欧好州第一的日产suv| 亚洲kkk4444在线观看| 亚洲一区二区三区在线| 亚洲午夜在线一区| 亚洲激情校园春色| 亚洲AV色吊丝无码| 亚洲最大在线观看| 亚洲中文字幕久久精品无码2021| 亚洲天堂在线播放| 亚洲天堂在线播放| 亚洲男女一区二区三区| 亚洲国产精品综合福利专区| 亚洲视频一区二区三区| 亚洲国产成人精品电影| 亚洲精品综合在线影院| 亚洲欧美日韩一区二区三区在线| 亚洲爆乳无码专区www| 四虎精品亚洲一区二区三区| 亚洲精品国自产拍在线观看| 久久久久无码专区亚洲av| 亚洲男同帅GAY片在线观看| 亚洲成熟xxxxx电影| 亚洲黄色网址大全| 亚洲国产片在线观看| 亚洲人成色777777精品| 亚洲国产精品成人AV无码久久综合影院| 亚洲人成无码www久久久| 亚洲高清专区日韩精品|