乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      【Redis19】Redis進(jìn)階:持久化策略

       硬核項(xiàng)目經(jīng)理 2023-05-08 發(fā)布于湖南

      Redis進(jìn)階:持久化策略

      從最早接觸 Redis 開始,我們就知道它是一個(gè)內(nèi)存數(shù)據(jù)庫(kù),這是它的優(yōu)勢(shì),也是它的劣勢(shì)。為啥這么說呢??jī)?nèi)存速度快,但是斷電或者重啟即丟。然而,要做為一個(gè)生產(chǎn)環(huán)境所能使用的數(shù)據(jù)庫(kù)系統(tǒng),將數(shù)據(jù)持久化就成為了一個(gè)必要的能力。畢竟我們可不想重啟 Redis 之后,每個(gè)生產(chǎn)緩存都要從頭重建一遍,最好是重啟的時(shí)候直接就幫我們將之前已經(jīng)保存的數(shù)據(jù)重新加載進(jìn)來(lái)。這就是 Redis 持久化要干的事。

      在 Redis 中,提供了兩種持久化方案,一個(gè)叫 RDB ,一個(gè)叫 AOF 。

      RDB

      其實(shí)之前在基礎(chǔ)相關(guān)的命令學(xué)習(xí)中,我們就已經(jīng)接觸過一點(diǎn)相關(guān)的知識(shí)了,比如說 SAVE 這個(gè)命令。當(dāng)時(shí)我們測(cè)試的時(shí)候,在客戶端執(zhí)行 SAVE 馬上就會(huì)把當(dāng)前系統(tǒng)中的數(shù)據(jù)保存到一個(gè) dump.rdb 的文件中。這個(gè)文件會(huì)保存在配置文件 dir 屬性所配置的目錄中。比如在我的電腦上是 dir "/usr/local/var/db/redis"這個(gè)目錄。

      ?  redis ll /usr/local/var/db/redis/dump.rdb
      -rw-r--r--  1 zhangyue  admin   103B  6 13 12:52 /usr/local/var/db/redis/dump.rdb

      同時(shí),這個(gè)文件名也是可以修改的,在配置文件中的 dbfilename "dump.rdb" 就是用于修改 RDB 持久化的文件名。這個(gè)文件如果你直接打開,會(huì)是亂碼的,也就是說,Redis 在對(duì) RDB 進(jìn)行持久化的時(shí)候進(jìn)行了壓縮編碼(LZF壓縮 rdbcompression 配置可以設(shè)置成不壓縮)。這兩個(gè)配置是可以通過 CONFIG SET 動(dòng)態(tài)修改的,比如說磁盤滿了或者有問題了,可以馬上加一塊新硬盤,然后動(dòng)態(tài)修改,下次持久化時(shí)就會(huì)將數(shù)據(jù)保存到新修改的路徑或文件名上了。RDB 的特點(diǎn)主要是:

      • RDB 的持久化是保存整個(gè)實(shí)例中所有的數(shù)據(jù),如果我們的程序運(yùn)行時(shí)間比較長(zhǎng),承擔(dān)的業(yè)務(wù)也比較重的話,原樣保存出來(lái)的文件就會(huì)非常大。因此,RDB 在保存的時(shí)候會(huì)進(jìn)行壓縮編碼。
      • RDB 文件是一個(gè)單一的并且非常緊湊的文件,因此,它很好備份,拷貝走就好啦!同樣的,相比于 AOF 來(lái)說,RDB 的恢復(fù)速度也更快一些。
      • RDB 在保存文件時(shí)會(huì)通過 Redis 實(shí)例 fork 出一個(gè)子進(jìn)程來(lái)進(jìn)行,是異步的,對(duì)應(yīng)的是我們之前學(xué)習(xí)過的 BGSAVE 這個(gè)命令。如果我們?cè)诿钚惺褂?SAVE 命令,那么會(huì)產(chǎn)生阻塞,因此,最好不要直接使用 SAVE 命令,使用 BGSAVE 命令或者通過配置文件讓應(yīng)用實(shí)例自動(dòng)備份就好了。
      • 在主從架構(gòu)中,RDB 可以支持重新啟動(dòng)和故障切換后的部分重新同步。

      有經(jīng)驗(yàn)的小伙伴一定發(fā)現(xiàn)了,這貨不就是 全量備份 嘛,或者換個(gè)更通俗點(diǎn)的名詞 快照(snapshotting) 。既然是這樣,那么全量備份的一些問題它也有。比如說:

      • 頻繁的 fork 子進(jìn)程,特別是數(shù)據(jù)量比較大的時(shí)候,fork 過程也是非常耗時(shí)的。雖說是一個(gè)子進(jìn)程,但不可避免的也會(huì)對(duì)主進(jìn)程產(chǎn)生影響,畢竟會(huì)搶占 CPU 時(shí)間。
      • 由上,包括 MySQL 也是類似的,我們不會(huì)一直總是做全量備份,往往是在一定的時(shí)間間隔內(nèi)進(jìn)行全量備份。而在時(shí)間間隔的中間如果發(fā)生了意外情況導(dǎo)致服務(wù)宕機(jī)的話,這中間的數(shù)據(jù)是會(huì)丟失的。

      幸好,AOF 就是來(lái)彌補(bǔ)它的這兩個(gè)問題的。下一小節(jié)我們?cè)僦v AOF ,先來(lái)看看默認(rèn)的 RDB 配置是怎樣的,我們可以如何修改。

      RDB 配置

      在默認(rèn)的配置文件中,你可以找到下面這樣的配置信息。

      save 3600 1
      save 300 100
      save 60 10000

      這是啥意思,怎么有三條配置?這些數(shù)字又是啥意思?咱們一個(gè)一個(gè)來(lái)看。

      save 時(shí)間 改動(dòng)型命令執(zhí)行次數(shù)

      看到這個(gè)注釋就好理解了吧,在多長(zhǎng)時(shí)間內(nèi),執(zhí)行了多少命令,就執(zhí)行一次 BGSAVE 保存 RDB 文件。注意,這個(gè)執(zhí)行的命令一定是改動(dòng)了數(shù)據(jù)的命令,比如 SET ,而 GET 這類的命令是不算在內(nèi)的。為啥呢?查詢類的命令沒啥可保存的必要呀,我們要保存的是存在的數(shù)據(jù)以及被改動(dòng)的數(shù)據(jù)。

      然后,上面寫了三條,就是這三條規(guī)則有一條觸發(fā)了就會(huì)進(jìn)行 RDB 持久化操作。

      • save 3600 1:表示1小時(shí)內(nèi)有1條改動(dòng)命令
      • save 300 100:表示300秒內(nèi)有100條改動(dòng)命令
      • save 60 10000:表示60秒內(nèi)有10000條改動(dòng)命令

      好吧,來(lái)試試。現(xiàn)在新加一條規(guī)則,60秒內(nèi)有1條命令就保存,然后重啟 Redis 實(shí)例。現(xiàn)在去 SET 一條測(cè)試數(shù)據(jù),看看 dump.rdb 文件有沒有變化。

      注意,CONFIG SET 是不能動(dòng)態(tài)修改 save 配置的。要關(guān)閉 RDB 機(jī)制應(yīng)該怎么配置呢?直接 save "" 就可以啦。

      AOF

      Append-only file ,這是 AOF 的全稱,意思也很明顯,只追加操作到文件去。也就是說,它會(huì)將 SET 之類的命令追加到一個(gè)文件的末尾,然后重啟實(shí)例的時(shí)候,重放這個(gè)文件中的命令就可以了。

      之前其實(shí)我們也已經(jīng)用過了,直接在配置文件中打開 appendonly 并設(shè)置為 yes 就啟用 AOF 功能了,不過默認(rèn)情況下,它是關(guān)閉的。我們也可以通過 appendfilename "appendonly.aof" 來(lái)設(shè)置文件的名稱,使用的路徑也是 dir 的路徑,所以一般情況下,這個(gè)文件會(huì)和 dump.rdb 文件放在一起。

      開啟之后,我們可以直接打開這個(gè)文件看看,它的內(nèi)容是我們可以看懂的哦。

      ?  redis redis-cli
      127.0.0.1:6379> set bb 123123
      OK
      127.0.0.1:6379> lpush list 1 2 3 4 5
      (integer) 5

      先執(zhí)行兩條命令,然后查看 appendonly.aof 文件。

      ?  redis vim /usr/local/etc/redis.conf
      REDIS0009ú      redis-ver^E6.2.6ú
      redis-bitsà@ú^Ectime?ìú§bú^Hused-mem?°8^Q^@ú^Laof-preambleà^At^@?^C^@^Nà^A^A^Q^Q^@^@^@^N^@^@^@^C^@^@?^B?^Bó?^@^Baa?óà^A^@^@^AbáT^@?d′^\??^?X*2^M
      $6^M
      SELECT^M
      $1^M
      0^M
      *3^M
      $3^M
      set^M
      $2^M
      bb^M
      $6^M
      123123^M
      *7^M
      $5^M
      lpush^M
      $4^M
      list^M
      $1^M
      1^M
      $1^M
      2^M
      $1^M

      上面亂碼的不用管,我們后面再說,先看下面的。我們可以看到 set 、lpush 之類的內(nèi)容,上面的數(shù)字表示執(zhí)行的命令的字符長(zhǎng)度。接著就是命令的參數(shù),同樣也是一個(gè)字符長(zhǎng)度加上一個(gè)實(shí)際的值。這個(gè)就是 AOF 生成的持久化文件的內(nèi)容。

      上面的一堆亂碼是啥呢?咱們先來(lái)說說這個(gè)。

      AOF 重寫

      從上面的例子中可以看出,AOF 是原樣保存數(shù)據(jù)的,這樣會(huì)有一個(gè)問題那就是無(wú)用命令的增多。比如說多次執(zhí)行 INCR ,但最后我們需要的其實(shí)是最后那次 INCR 的數(shù)據(jù),在回放數(shù)據(jù)的時(shí)候其實(shí)只要 SET 到最后一次 INCR 的值就好了。

      ?  redis redis-cli
      127.0.0.1:6379> INCR cc
      (integer) 1
      127.0.0.1:6379> INCR cc
      (integer) 2
      127.0.0.1:6379> INCR cc
      (integer) 3
      127.0.0.1:6379> INCR cc
      (integer) 4
      127.0.0.1:6379>

      // appendonly.aof
      $4^M
      INCR^M
      $2^M
      cc^M
      *2^M
      $4^M
      INCR^M
      $2^M
      cc^M
      *2^M
      $4^M
      INCR^M
      $2^M
      cc^M
      *2^M
      $4^M
      INCR^M
      $2^M
      cc^M

      現(xiàn)在使用 BGREWRITEAOF 命令,執(zhí)行 AOF 文件重寫,你就會(huì)發(fā)現(xiàn)上面的 INCR 命令合并成了一個(gè) SET 命令。

      // appendonly.aof
      SET
      $2
      cc
      $1
      4

      是不是好很多了?不夠不夠,要知道,AOF 一般是做增量備份的,數(shù)據(jù)增加是很快的,能不能再壓縮一些呢?這時(shí)你應(yīng)該想到 RDB 的壓縮格式了吧,去配置文件開啟 aof-use-rdb-preamble yes ,啟用 RDB+AOF 的混合模式,這時(shí)再執(zhí)行 BGREWRITEAOF ,你就會(huì)發(fā)現(xiàn)數(shù)據(jù)被壓縮成了和 RDB 一樣的格式,體積再進(jìn)一步縮小,恢復(fù)時(shí)的執(zhí)行速度也更快了。

      BGREWRITEAOF 對(duì)應(yīng)的自動(dòng)重寫配置也在配置文件中。

      auto-aof-rewrite-percentage 100
      auto-aof-rewrite-min-size 64mb

      下面的 64mb 表示第一次 aof 文件重寫的基準(zhǔn)大小,上面的 100 表示的是當(dāng)前日志文件與 64mb 這個(gè)基準(zhǔn)進(jìn)行比較的百分比。當(dāng)文件達(dá)到了這個(gè)百分比后,自動(dòng)進(jìn)行重寫,也就是文件到達(dá) 128mb 的時(shí)候進(jìn)行重寫。之后的重寫就不會(huì)依賴于 64mb 這個(gè)數(shù)值了,而是變成一個(gè)動(dòng)態(tài)值將當(dāng)前壓縮后的大小保存到實(shí)例中,下次只要超過這個(gè)值的 1 倍,就會(huì)再次進(jìn)行重寫。如果把百分比設(shè)置為 0 ,則相當(dāng)于關(guān)閉了重寫的機(jī)制。

      AOF 寫入時(shí)機(jī)

      上面 RDB 的寫入時(shí)機(jī)是多選的,默認(rèn)三種情況下有一個(gè)觸發(fā)就會(huì)寫入。而 AOF 則只能配置一種,它的配置項(xiàng)是這樣的。

      # appendfsync always
      appendfsync everysec
      # appendfsync no

      很明顯,默認(rèn)情況下是每秒寫入,always 是一直寫入,也就是只要有一個(gè)修改類的命令出現(xiàn),馬上就進(jìn)行寫入,一直有磁盤操作,大家就能想到,它多少會(huì)拖慢速度,但很安全,因?yàn)閿?shù)據(jù)基本不會(huì)丟。最后一個(gè)是不直接寫入,先把日志寫到內(nèi)存緩沖區(qū),然后由操作系統(tǒng)決定何時(shí)將緩沖區(qū)內(nèi)容寫回磁盤。

      不用多說了吧,always 會(huì)很耗性能,no 的主動(dòng)權(quán)不在 Redis 手中但性能最好。所以,一般情況下走默認(rèn)的就好了,但是,注意,這1秒內(nèi)如果執(zhí)行了命令,但 AOF 還沒有自動(dòng)寫入就出問題崩潰了,這時(shí)的數(shù)據(jù)也會(huì)丟失的。

      AOF 重寫工作原理

      和 RDB 一樣,好像上面 RDB 的寫入過程也沒細(xì)說,那就一起說吧。它們倆都是使用的寫時(shí)復(fù)制這種技術(shù)。都是 fork 子進(jìn)程,將新的 AOF 內(nèi)容寫入臨時(shí)文件。在寫入時(shí),父進(jìn)程對(duì)新來(lái)的命令寫入到緩存。當(dāng)重寫工作完成后,臨時(shí)文件替換成正式文件,子進(jìn)程向父進(jìn)程發(fā)送信號(hào),然后父進(jìn)程將緩存中的數(shù)據(jù)寫入到新的 AOF 文件。

      AOF 的優(yōu)劣

      對(duì)于 AOF 的優(yōu)劣來(lái)說,很明顯就是和 RDB 的對(duì)比,相對(duì)于 RDB 來(lái)說,AOF 可以:

      • 更加安全,可以使用不同的策略,默認(rèn)就是按秒的,要丟也是丟一秒內(nèi)的數(shù)據(jù)
      • 只追加文件,沒有別的操作,速度比較快
      • 自動(dòng)重寫 AOF 文件,優(yōu)化文件體積
      • 保證有序?qū)懭?,未重寫前的?shù)據(jù)是人類可讀的

      當(dāng)然,它也會(huì)帶來(lái)一些問題。

      • 一般來(lái)說,AOF 的文件大小會(huì)大于 RDB
      • 雖然寫入文件的速度很快,但是,在巨量寫入的情況下,肯定還是不如 RDB ,特別是設(shè)置 always 之后
      • 如果在重寫過程中有新的寫入,AOF 可能會(huì)使用大量?jī)?nèi)存,并且這些新的寫入命令會(huì)被寫入磁盤兩次
      • awlays 會(huì)阻塞主進(jìn)程不是異步的,而每秒 fsync 雖說是異步線程,但如果數(shù)據(jù)量非常大,會(huì)阻塞 fsync 子線程進(jìn)而影響主線程,因此,AOF 總體來(lái)說是有阻塞問題的

      用哪個(gè)?

      這個(gè)嘛,要看具體的業(yè)務(wù)情況咯。如果說你想要可以媲美關(guān)系型數(shù)據(jù)庫(kù)的存儲(chǔ)安全性,那就把 AOF 和 RDB 都打開。不過官方更推薦的是,如果你只是將 Redis 當(dāng)做緩存工具的話,那就都不要開。

      當(dāng)然,這是兩種極端情況,大部業(yè)務(wù)場(chǎng)景下,其實(shí)我們保持默認(rèn),也就是 RDB 的默認(rèn)持久化規(guī)則就好了。

      另外,在服務(wù)實(shí)例啟動(dòng)的時(shí)候,如果開啟了 AOF ,則優(yōu)先根據(jù) AOF 來(lái)進(jìn)行數(shù)據(jù)還原。AOF 的優(yōu)先級(jí)是要高于 RDB 的,畢竟它更安全,記錄的數(shù)據(jù)更全面一些。

      備份策略

      對(duì)于 Redis 的這兩個(gè)文件來(lái)說,備份相當(dāng)?shù)暮?jiǎn)單。為啥這么說呢?因?yàn)檫@兩個(gè)文件即使在服務(wù)運(yùn)行期間也是可以直接復(fù)制剪切走的。換句話說,你拿寶塔做個(gè)定時(shí)任務(wù)去備份這倆文件,然后再發(fā)送走就好了,本地硬盤存儲(chǔ)也行,郵件也行,網(wǎng)盤也行,其它服務(wù)器直接 scp 也行,總之非常簡(jiǎn)單。

      要還原的話,直接拷貝回配置文件中 dir 指定的目錄位置就好了。

      RDB 和 AOF 修復(fù)工具

      根據(jù)上面的內(nèi)容,我們知道 AOF 和 RDB 文件都是可以直接拷貝、刪除、修改的,那么這兩個(gè)文件就很容易就會(huì)不小心被修改或者篡改。于是,Redis 順道便提供了兩個(gè)修復(fù)工具。我們先拿 AOF 文件試試,直接亂寫一些內(nèi)容。

      $3^M
      setdfdfsdf^M
      $3^M
      ddd^M
      $3^M
      123^M

      把 set 命令給隨便加了些字符,這樣的話如果重啟服務(wù),直接就會(huì)報(bào)出錯(cuò)誤信息。

      39166:M 15 Jun 2022 09:53:51.755 * Reading the remaining AOF tail...
      39166:M 15 Jun 2022 09:53:51.755 # Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>

      從提示中就可以看出,它讓我們嘗試用修復(fù)工具去修復(fù) AOF 文件。那么我們就來(lái)試試。

      ?  redis redis-check-aof --fix appendonly.aof
      The AOF appears to start with an RDB preamble.
      Checking the RDB preamble to start:
      [offset 0] Checking RDB file --fix
      [offset 26] AUX FIELD redis-ver = '6.2.6'
      [offset 40] AUX FIELD redis-bits = '64'
      [offset 52] AUX FIELD ctime = '1655177336'
      [offset 67] AUX FIELD used-mem = '1128240'
      [offset 83] AUX FIELD aof-preamble = '1'
      [offset 85] Selecting DB ID 0
      [offset 103] Checksum OK
      [offset 103] \o/ RDB looks OK! \o/
      [info] 1 keys read
      [info] 0 expires
      [info] 0 already expired
      RDB preamble is OK, proceeding with AOF tail...
      0x              86: Expected \r\n, got: 6466
      AOF analyzed: size=164, ok_up_to=126, ok_up_to_line=8, diff=38
      This will shrink the AOF from 164 bytes, with 38 bytes, to 126 bytes
      Continue? [y/N]: y
      Successfully truncated AOF

      修復(fù)成功之后再看看,它會(huì)直接把我們剛剛亂改的命令給刪掉,也就是無(wú)效的內(nèi)容會(huì)被清理掉,保證其它數(shù)據(jù)的正常加載。(重啟之后的實(shí)例中 ddd 這條數(shù)據(jù)也就沒有了)

      同樣的,對(duì)于 RDB 文件來(lái)說,也有一個(gè) redis-check-rdb 命令用于修復(fù) RDB 文件,這個(gè)命令不需要使用參數(shù),直接就可以對(duì)指定的文件進(jìn)行修復(fù)。

      Redis7 的變化

      在 Reids7 中,AOF 產(chǎn)生了比較多的變化,來(lái)自官方文檔,我這里沒有安裝 Redis7 所以沒有進(jìn)行詳細(xì)的測(cè)試,大家可以了解下。

      • 采用多部分 AOF 機(jī)制,原始的單個(gè) AOF 被分為一個(gè)基本文件和可能有多個(gè)的增量文件
      • 基本文件是重寫 AOF 時(shí)存在的初始數(shù)據(jù),也就是 RDB 那種格式的,增量文件包含上次創(chuàng)建基本文件以來(lái)的增量數(shù)據(jù),它們會(huì)放在一個(gè)目錄中并由另外一個(gè)清單文件來(lái)進(jìn)行跟蹤
      • 通過臨時(shí)清單文件跟蹤基本文件和增量文件,當(dāng)它們就緒時(shí),執(zhí)行原子替換操作
      • 加入重寫限制機(jī)制,確保重試失敗的重寫會(huì)產(chǎn)生過多的增量文件的問題

      總結(jié)

      這一把學(xué)完,相信你對(duì) Redis 的持久化策略應(yīng)該有了比較深入的印象了吧。還是那句話,大部分情況下,用默認(rèn)的配置就好了,有特殊需求的時(shí)候,至少你得知道這兩種策略可以應(yīng)用在什么場(chǎng)景下。另外就是應(yīng)付面試了,這些內(nèi)容也是非常容易出現(xiàn)在面試題中的。

      參考文檔:

      https:///docs/manual/persistence/

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多