<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Redis持久化神器!

          共 4263字,需瀏覽 9分鐘

           ·

          2020-08-26 13:51


          天天用Redis,持久化方案有哪些你知道嗎?

          前言?

          • Redis目前已經(jīng)成為主流的內(nèi)存數(shù)據(jù)庫了,但是大部分人僅僅是停留在會用的階段,你真的了解Redis內(nèi)部的工作原理嗎?

          • 今天這篇文章將為大家介紹Redis持久化的兩種方案,文章將會從以下五個方面介紹:

            1. 什么是RDB,RDB如何實現(xiàn)持久化?

            2. 什么是AOF,AOF如何實現(xiàn)持久化?

            3. AOF和RDB的區(qū)別。

            4. 如何重啟恢復(fù)數(shù)據(jù)?

            5. 持久化性能問題和解決方案

          RDB

          • RDB持久化是把當(dāng)前進程數(shù)據(jù)生成快照保存到硬盤的過程, 觸發(fā)RDB持久化過程分為手動觸發(fā)和自動觸發(fā)。

          • RDB完成后會自動生成一個文件,保存在dir配置的指定目錄下,文件名是dbfileName指定。

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

          手動觸發(fā)

          • 手動觸發(fā)的命令有savebgsave

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

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

          自動觸發(fā)

          • 除了手動觸發(fā)RDB,Redis服務(wù)器內(nèi)部還有如下幾個場景能夠自動觸發(fā)RDB:

            1. 根據(jù)我們的?save m n?配置規(guī)則自動觸發(fā)。

            2. 如果從節(jié)點執(zhí)行全量復(fù)制操作, 主節(jié)點自動執(zhí)行bgsave生成RDB文件并發(fā)送給從節(jié)點。

            3. 執(zhí)行debug reload命令重新加載Redis時, 也會自動觸發(fā)save操作。

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

          RDB執(zhí)行流程

          • RDB的主流方式就是bgsave,通過下圖我們來看看RDB的執(zhí)行流程:


          • 通過上圖可以很清楚RDB的執(zhí)行流程,如下:

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

            2. 父進程fork操作創(chuàng)建一個子進程,fork操作中父進程會被阻塞。

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

            4. 子進程完成后發(fā)送信號給父進程,父進程更新統(tǒng)計信息。

          RDB的優(yōu)點

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

          • Redis加載RDB恢復(fù)數(shù)據(jù)遠遠快于AOF的方式。

          RDB的缺點

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

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

          AOF

          • AOF(append only file) 持久化:以獨立日志的方式記錄每次寫命令,重啟時再重新執(zhí)行AOF文件中的命令達到恢復(fù)數(shù)據(jù)的目的。AOF的主要作用是解決了數(shù)據(jù)持久化的實時性, 目前已經(jīng)是Redis持久化的主流方式

          如何開啟AOF

          • 開啟AOF功能需要設(shè)置配置:appendonly yes, 默認不開啟。AOF文件名通過appendfilename配置設(shè)置, 默認文件名是appendonly.aof。保存路徑同RDB持久化方式一致,通過dir配置指定。

          AOF整體的執(zhí)行流程

          • AOF執(zhí)行的流程大致分為命令寫入文件同步文件重寫重啟加載四個步驟,如下圖:

          • 從上圖大致了解了AOF的執(zhí)行流程,下面一一分析上述的四個步驟。

          命令寫入

          • AOF命令寫入的內(nèi)容直接是文本協(xié)議格式。例如set hello world這條命 令, 在AOF緩沖區(qū)會追加如下文本:

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

          • 命令寫入是直接寫入到AOF的緩沖區(qū)中,至于為什么?原因很簡單,Redis使用單線程響應(yīng)命令,如果每次寫AOF文件命令都直接追加到硬盤, 那么性能完全取決于當(dāng)前硬盤負載。先寫入緩沖區(qū)aof_buf中, 還有另一個好處, Redis可以提供多種緩沖區(qū) 同步硬盤的策略,在性能和安全性方面做出平衡。

          文件同步

          • Redis提供了多種AOF緩沖區(qū)同步文件策略, 由參數(shù)appendfsync控制,如下:

            • 配置為always時, 每次寫入都要同步AOF文件, 在一般的SATA硬盤上,Redis只能支持大約幾百TPS寫入, 顯然跟Redis高性能特性背道而馳,不建議配置。

            • 配置為no,由于操作系統(tǒng)每次同步AOF文件的周期不可控,而且會加大每次同步硬盤的數(shù)據(jù)量,雖然提升了性能,但數(shù)據(jù)安全性無法保證。

            • 配置為everysec(默認的配置),是建議的同步策略, 也是默認配置,做到兼顧性能和數(shù)據(jù)安全性。理論上只有在系統(tǒng)突然宕機的情況下丟失1秒的數(shù)據(jù)(當(dāng)然,這是不太準確的)。

          文件重寫機制

          • 隨著命令不斷寫入AOF, 文件會越來越大, 為了解決這個問題, Redis引入AOF重寫機制壓縮文件體積。AOF文件重寫是把Redis進程內(nèi)的數(shù)據(jù)轉(zhuǎn)化為寫命令同步到新AOF文件的過程。

          • 為什么要文件重寫呢??因為文件重寫能夠使得AOF文件的體積變得更小,從而使得可以更快的被Redis加載。

          • 重寫過程分為手動觸發(fā)和自動觸發(fā)。

            • 手動觸發(fā)直接使用bgrewriteaof命令。

            • 根據(jù)auto-aof-rewrite-min-sizeauto-aof-rewrite-percentage參數(shù)確定自動觸發(fā)時機。

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

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

          • 自動觸發(fā)時機相當(dāng)于aof_current_size>auto-aof-rewrite-minsize&&(aof_current_size-aof_base_size) /aof_base_size>=auto-aof-rewritepercentage。其中aof_current_sizeaof_base_size可以在info Persistence統(tǒng)計信息中查看。

          • 那么文件重寫后的AOF文件為什么會變小呢??有如下幾個原因:

            1. 進程內(nèi)已經(jīng)超時的數(shù)據(jù)將不會再次寫入AOF文件中。

            2. 舊的AOF文件含有無效命令,如del key1、?hdel key2等。重寫使用進程內(nèi)數(shù)據(jù)直接生成,這樣新的AOF文件只保留最終數(shù)據(jù)的寫入命令。

            3. 多條寫命令可以合并為一個, 如:lpush list a、?lpush list blpush listc可以轉(zhuǎn)化為:lpush list a b c。為了防止單條命令過大造成客戶端緩沖區(qū)溢出,對于list、?set、?hash、?zset等類型操作,以64個元素為界拆分為多條。

          • 介紹了文件重寫的系列知識,下面來看看Redis內(nèi)部是如何進行文件重寫的,如下圖:

          • 看完上圖,大致了解了文件重寫的流程,對于重寫的流程,補充如下:

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

            2. 為了把重寫期間響應(yīng)的寫入信息也寫入到新的文件中,因此也會為子進程保留一個緩沖區(qū),防止新寫的文件丟失數(shù)據(jù)。

            3. 重寫是直接把當(dāng)前內(nèi)存的數(shù)據(jù)生成對應(yīng)命令,并不需要讀取老的AOF文件進行分析、命令合并。

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

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

          AOF的優(yōu)點

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

          AOF的缺點

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

          • 數(shù)據(jù)恢復(fù)速度相對于RDB比較慢。

          AOF和RDB的區(qū)別

          • RDB持久化是指在指定的時間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫入磁盤,實際操作過程是fork一個子進程,先將數(shù)據(jù)集寫入臨時文件,寫入成功后,再替換之前的文件,用二進制壓縮存儲。

          • AOF持久化以日志的形式記錄服務(wù)器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文本的方式記錄,可以打開文件看到詳細的操作記錄。

          重啟加載

          • 無論是RDB還是AOF都可用于服務(wù)器重啟時的數(shù)據(jù)恢復(fù),執(zhí)行流程如下圖:


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

          性能問題與解決方案

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

          • 那么如何減少fork操作的阻塞呢?

            1. 優(yōu)先使用物理機或者高效支持fork操作的虛擬化技術(shù)。

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

            3. 合理配置Linux內(nèi)存分配策略,避免物理內(nèi)存不足導(dǎo)致fork失敗。

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



          瀏覽 38
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月天黄色小说 | 免费一级片电影网站 | 日本AAA视频 | 青青操在线观看视频 | 91AV影院|