<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持久化錦囊在手,再也不會擔(dān)心數(shù)據(jù)丟失了

          共 4096字,需瀏覽 9分鐘

           ·

          2021-06-08 10:27

          大家好,我是小羽。

          Redis 的讀寫都是在內(nèi)存中進(jìn)行的,所以它的性能高。而當(dāng)我們的服務(wù)器斷開或者重啟的時候,數(shù)據(jù)就會消失,那么我們該怎么解決這個問題呢?

          其實(shí) Redis 已經(jīng)為我們提供了一種持久化的機(jī)制,分別是 RDBAOF 兩種方式,接下來跟著我一起看看這兩個錦囊都是怎么保證數(shù)據(jù)的持久化的。

          持久化

          由于 Redis 是基于內(nèi)存的數(shù)據(jù)庫,所以當(dāng)服務(wù)器出現(xiàn)故障的時候,我們的數(shù)據(jù)就得不到安全保障。

          這個時候就需要將內(nèi)存中的數(shù)據(jù)存儲到磁盤中,當(dāng)我們服務(wù)器重啟時,便可以通過磁盤來恢復(fù)數(shù)據(jù),這個過程就叫做 Redis 持久化。

          1ac6f9ebe07b27dd95760e557f82b4d5.webp

          Redis持久化

          RDB

          簡介

          RDB全稱Redis Database Backup file(Redis數(shù)據(jù)備份文件),也可以稱為Redis數(shù)據(jù)快照

          • RDB 文件是一個經(jīng)過壓縮的二進(jìn)制文件(默認(rèn):dump.rdb);

          • RDB 文件保存在硬盤里;

          • 通過保存數(shù)據(jù)庫中的鍵值對來記錄數(shù)據(jù)庫狀態(tài)。

          創(chuàng)建

          當(dāng) Redis 持久化時,程序會將當(dāng)前內(nèi)存中的數(shù)據(jù)庫狀態(tài)保存到磁盤中。

          b6a04cfe116e305f6e4d803e554922a1.webp

          創(chuàng)建

          創(chuàng)建 RDB 文件主要有兩個 Redis 命令:SAVEBGSAVE

          SAVE

          同步操作,執(zhí)行命令時,會阻塞 Redis 服務(wù)器進(jìn)程,拒絕客戶端發(fā)送的命令請求。

          代碼示例

          def?SAVE():
          ????#?創(chuàng)建?RDB?文件
          ????rdbSave()

          圖示

          d3d49edf4139d918483a51152ca15c11.webp

          Save命令
          BGSAVE

          異步操作,執(zhí)行命令時,子進(jìn)程執(zhí)行保存工作,服務(wù)器還可以繼續(xù)讓主線程處理客戶端發(fā)送的命令請求。

          代碼示例

          def?BGSAVE():
          ????#?創(chuàng)建子進(jìn)程
          ????pid?=?fork()

          ????if?pid?==?0:
          ????????#?子進(jìn)程負(fù)責(zé)創(chuàng)建?RDB?文件
          ????????rdbSave()
          ????????#?完成之后向父進(jìn)程發(fā)送信號
          ????????signal_parent()
          ????elif?pid?>?0:
          ????????#?父進(jìn)程繼續(xù)處理命令請求,并通過輪訓(xùn)等待子進(jìn)程的信號
          ????????handle_request_and_wait_signal()
          ????else:
          ????????handle_fork_error()

          圖示

          754d0c057d21fbdc9d92725619b2a9f2.webp

          bgSave命令

          載入

          載入工作在服務(wù)器啟動時自動執(zhí)行。

          58a4a97a3c6bde4ff5c6f2071ef78021.webp

          載入

          服務(wù)器在載入 RDB 文件期間,會一直處于阻塞狀態(tài),直到載入工作完成為止。

          主要設(shè)置

          Redis 允許用戶通過設(shè)置服務(wù)器配置的 save 選項(xiàng),讓服務(wù)器每隔一段時間自動執(zhí)行一次 BGSAVE 命令。

          設(shè)置保存條件

          提供配置如下:

          save?900?1
          save?300?10

          在這種情況下,只要滿足以下條件中的一個,BGSAVE 命令就會被執(zhí)行:

          • 服務(wù)器在 900 秒之內(nèi),對數(shù)據(jù)庫進(jìn)行了至少 1 次修改了;

          • 服務(wù)器在 300 秒之內(nèi),對數(shù)據(jù)庫進(jìn)行了至少 10 次修改。

          saveparams

          服務(wù)器程序會根據(jù) save 選項(xiàng)所設(shè)置的保存條件,設(shè)置服務(wù)器狀態(tài) redisServer 結(jié)構(gòu)的 saveparams 屬性。

          • saveparams 屬性是一個數(shù)組;

          • 數(shù)組中的每一個元素都是一個 saveparam 結(jié)構(gòu);

          • 每個 saveparam 結(jié)構(gòu)都保存了一個 save 選項(xiàng)設(shè)置的保存條件。

          struct?saveparam?{
          ????//?秒數(shù)
          ????time_t?seconds;
          ????//?修改數(shù)
          ????int?changes;
          }
          dirty

          dirty 計(jì)數(shù)器記錄距離上一次成功執(zhí)行 SAVE 命令或 BGSAVE 命令之后,服務(wù)器對數(shù)據(jù)庫狀態(tài)進(jìn)行了多少次修改(包括寫入、刪除、更新等操作)。

          lastsave

          是一個 UNINX 時間戳,記錄了服務(wù)器上一次成功執(zhí)行 SAVE 命令或者 BGSAVE 命令的時間。

          檢查保存條件是否滿足

          服務(wù)器周期性操作函數(shù) serverCron (該函數(shù)對正在運(yùn)行的服務(wù)器進(jìn)行維護(hù))默認(rèn)每隔 100 毫秒就會執(zhí)行一次,其中一項(xiàng)工作就是檢查 save 選項(xiàng)所設(shè)置的保存條件是否已經(jīng)滿足,滿足的話就執(zhí)行 BGSAVE 命令。

          代碼示例

          def?serverCron():
          ????#?....
          ????#?遍歷所有保存條件
          ????for?saveparam?in?server.saveparams:
          ????????#?計(jì)算距離上次執(zhí)行保存操作有多少秒
          ????????save_interval?=?unixtime_now()?-?server.lastsave

          ????????#?如果數(shù)據(jù)庫狀態(tài)的修改次數(shù)超過條件所設(shè)置的次數(shù)
          ????????#?如果距離上次保存的時間超過條件所設(shè)置的時間
          ????????if?server.dirty?>=?saveparam.changes?and?save_interval?>?saveparam.seconds:
          ????????????BGSAVE()

          默認(rèn)配置

          RDB 文件默認(rèn)的配置如下:

          ################################?SNAPSHOTTING??################################
          #
          #?Save?the?DB?on?disk:
          #在給定的秒數(shù)和給定的對數(shù)據(jù)庫的寫操作數(shù)下,自動持久化操作。
          #???save?<seconds>?<changes>
          #?
          save?900?1
          save?300?10
          save?60?10000

          #bgsave發(fā)生錯誤時是否停止寫入,一般為yes
          stop-writes-on-bgsave-error?yes

          #持久化時是否使用LZF壓縮字符串對象?
          rdbcompression?yes

          #是否對rdb文件進(jìn)行校驗(yàn)和檢驗(yàn),通常為yes
          rdbchecksum?yes

          #?RDB持久化文件名
          dbfilename?dump.rdb

          #持久化文件存儲目錄
          dir?./

          AOF

          簡介

          AOF全稱為 Append Only File(追加日志文件)。日志是寫后日志,Redis 是先執(zhí)行命令,把數(shù)據(jù)寫入內(nèi)存,然后才記錄日志。

          fcae22e3bdb4efd5737774081dc25f7a.webp

          寫后日志

          • 通過保存 Redis 服務(wù)器所執(zhí)行的寫命令來記錄數(shù)據(jù)庫狀態(tài);

          • 寫入 AOF 文件的所有命令都是以 Redis 的命令請求協(xié)議格式保存的。

          實(shí)現(xiàn)

          AOF 持久化流程實(shí)現(xiàn)主要是通過以下流程來實(shí)現(xiàn)的:

          80f1381c8922fc6ea9556433a955ca18.webp

          AOF流程

          命令追加

          若 AOF 持久化功能處于打開狀態(tài),服務(wù)器在執(zhí)行完一個命令后,會以協(xié)議格式將被執(zhí)行的寫命令追加到服務(wù)器狀態(tài)的 aof_buf 緩沖區(qū)的末尾。

          文件同步

          服務(wù)器每次結(jié)束一個事件循環(huán)之前,都會調(diào)用 flushAppendOnlyFile 函數(shù),這個函數(shù)會考慮是否需要將 aof_buf 緩沖區(qū)中的內(nèi)容寫入和保存到 AOF 文件里。

          flushAppendOnlyFile 函數(shù)執(zhí)行以下流程:

          • WRITE:根據(jù)條件,將 aof_buf 中的緩存寫入到 AOF 文件;

          • SAVE:根據(jù)條件,調(diào)用 fsync 或 fdatasync 函數(shù),將 AOF 文件保存到磁盤中。

          這個函數(shù)是由服務(wù)器配置的 appendfsync 的三個值:always、everysec、no 來影響的,也被稱為三種策略。

          Always

          每條命令都會 fsync 到硬盤中,這樣 redis 的寫入數(shù)據(jù)就不會丟失。

          c927bbeed86df58b66d43313627556d9.webp

          Always
          everysec

          每秒都會刷新緩沖區(qū)到硬盤中(默認(rèn)值)。

          9df2cc7bb3d73104c99e42dc932e7c17.webp

          everysec
          no

          根據(jù)當(dāng)前操作系統(tǒng)的規(guī)則決定什么時候刷新到硬盤中,不需要我們來考慮。

          c4acc9924cd759cf56b9a7c6c1db8ae6.webp

          no

          數(shù)據(jù)加載

          1. 創(chuàng)建一個不帶網(wǎng)絡(luò)連接的偽客戶端;

          2. 從 AOF 文件中分析并讀取出一條寫命令;

          3. 使用偽客戶端執(zhí)行被讀出的寫命令;

          4. 一直執(zhí)行步驟 2 和 3,直到 AOF 文件中的所有寫命令都被處理完畢為止。

          文件重寫

          為何需要文件重寫:

          • 為了解決 AOF 文件體積膨脹的問題;

          • 通過重寫創(chuàng)建一個新的 AOF 文件來替代現(xiàn)有的 AOF 文件,新的 AOF 文件不會包含任何浪費(fèi)空間的冗余命令。

          實(shí)現(xiàn)

          文件重寫的實(shí)現(xiàn)原理:

          • 不需要對現(xiàn)有的 AOF 文件進(jìn)行任何操作;

          • 從數(shù)據(jù)庫中直接讀取鍵現(xiàn)在的值;

          • 用一條命令記錄鍵值對,從而代替之前記錄這個鍵值對的多條命令。

          后臺重寫

          為不阻塞父進(jìn)程,Redis 將 AOF 重寫程序放到子進(jìn)程里執(zhí)行。

          在子進(jìn)程執(zhí)行 AOF 重寫期間,服務(wù)器進(jìn)程需要執(zhí)行三個流程:

          1. 執(zhí)行客戶端發(fā)來的命令;

          2. 將執(zhí)行后的寫命令追加到 AOF 緩沖區(qū);

          3. 將執(zhí)行后的寫命令追加到 AOF 重寫緩沖區(qū)。

          81a051c9494addaeefa9a312abc3c35a.webp

          服務(wù)器流程

          默認(rèn)配置

          AOF 文件默認(rèn)的配置如下:

          ##############################?APPEND?ONLY?MODE?###############################

          #開啟AOF持久化方式
          appendonly?no

          #AOF持久化文件名
          appendfilename?"appendonly.aof"
          #每秒把緩沖區(qū)的數(shù)據(jù)fsync到磁盤
          appendfsync?everysec
          #?appendfsync?no
          #是否在執(zhí)行重寫時不同步數(shù)據(jù)到AOF文件
          no-appendfsync-on-rewrite?no

          #?觸發(fā)AOF文件執(zhí)行重寫的增長率
          auto-aof-rewrite-percentage?100
          #觸發(fā)AOF文件執(zhí)行重寫的最小size
          auto-aof-rewrite-min-size?64mb

          #redis在恢復(fù)時,會忽略最后一條可能存在問題的指令
          aof-load-truncated?yes

          #是否打開混合開關(guān)
          aof-use-rdb-preamble?yes

          總結(jié)

          通過以上的簡介,想必大家都對 Redis 持久化有了大致的了解,那么這兩種方式,我們該如何選擇呢?

          • 對于大中型的應(yīng)用,我們既想保證數(shù)據(jù)完整性又想保證高效率,就應(yīng)該結(jié)合使用 RDB 和 AOF 兩種方式;

          • 如果只是需要保證數(shù)據(jù)的完整性,保護(hù)數(shù)據(jù)不會丟失,那么優(yōu)先使用 AOF 方式;

          • 如果是處理大規(guī)模的數(shù)據(jù)恢復(fù),追求更高更快的效率的話,優(yōu)先使用 RDB 方式。

          也可以參照下圖進(jìn)行選擇:

          030d67e2202865472ce9b789ec9b057f.webp


          主要對比


          瀏覽 58
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  久久久久久久久免费观看完整版 | 日本无码在线播放 | 精品一区二区视频在线观看 | 77777欧美 | 久久大鸡吧 |