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 屬性所配置的目錄中。比如在我的電腦上是
同時(shí),這個(gè)文件名也是可以修改的,在配置文件中的
有經(jīng)驗(yàn)的小伙伴一定發(fā)現(xiàn)了,這貨不就是 全量備份 嘛,或者換個(gè)更通俗點(diǎn)的名詞 快照(snapshotting) 。既然是這樣,那么全量備份的一些問題它也有。比如說:
幸好,AOF 就是來(lái)彌補(bǔ)它的這兩個(gè)問題的。下一小節(jié)我們?cè)僦v AOF ,先來(lái)看看默認(rèn)的 RDB 配置是怎樣的,我們可以如何修改。 RDB 配置在默認(rèn)的配置文件中,你可以找到下面這樣的配置信息。
這是啥意思,怎么有三條配置?這些數(shù)字又是啥意思?咱們一個(gè)一個(gè)來(lái)看。
看到這個(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 持久化操作。
好吧,來(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)該怎么配置呢?直接 AOFAppend-only file ,這是 AOF 的全稱,意思也很明顯,只追加操作到文件去。也就是說,它會(huì)將 SET 之類的命令追加到一個(gè)文件的末尾,然后重啟實(shí)例的時(shí)候,重放這個(gè)文件中的命令就可以了。 之前其實(shí)我們也已經(jīng)用過了,直接在配置文件中打開 appendonly 并設(shè)置為 yes 就啟用 AOF 功能了,不過默認(rèn)情況下,它是關(guān)閉的。我們也可以通過 開啟之后,我們可以直接打開這個(gè)文件看看,它的內(nèi)容是我們可以看懂的哦。
先執(zhí)行兩條命令,然后查看 appendonly.aof 文件。
上面亂碼的不用管,我們后面再說,先看下面的。我們可以看到 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 的值就好了。
現(xiàn)在使用 BGREWRITEAOF 命令,執(zhí)行 AOF 文件重寫,你就會(huì)發(fā)現(xiàn)上面的 INCR 命令合并成了一個(gè) SET 命令。
是不是好很多了?不夠不夠,要知道,AOF 一般是做增量備份的,數(shù)據(jù)增加是很快的,能不能再壓縮一些呢?這時(shí)你應(yīng)該想到 RDB 的壓縮格式了吧,去配置文件開啟 BGREWRITEAOF 對(duì)應(yīng)的自動(dòng)重寫配置也在配置文件中。
下面的 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)是這樣的。
很明顯,默認(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 可以:
當(dāng)然,它也會(huì)帶來(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)容。
把 set 命令給隨便加了些字符,這樣的話如果重啟服務(wù),直接就會(huì)報(bào)出錯(cuò)誤信息。
從提示中就可以看出,它讓我們嘗試用修復(fù)工具去修復(fù) AOF 文件。那么我們就來(lái)試試。
修復(fù)成功之后再看看,它會(huì)直接把我們剛剛亂改的命令給刪掉,也就是無(wú)效的內(nèi)容會(huì)被清理掉,保證其它數(shù)據(jù)的正常加載。(重啟之后的實(shí)例中 ddd 這條數(shù)據(jù)也就沒有了) 同樣的,對(duì)于 RDB 文件來(lái)說,也有一個(gè) Redis7 的變化在 Reids7 中,AOF 產(chǎn)生了比較多的變化,來(lái)自官方文檔,我這里沒有安裝 Redis7 所以沒有進(jìn)行詳細(xì)的測(cè)試,大家可以了解下。
總結(jié)這一把學(xué)完,相信你對(duì) Redis 的持久化策略應(yīng)該有了比較深入的印象了吧。還是那句話,大部分情況下,用默認(rèn)的配置就好了,有特殊需求的時(shí)候,至少你得知道這兩種策略可以應(yīng)用在什么場(chǎng)景下。另外就是應(yīng)付面試了,這些內(nèi)容也是非常容易出現(xiàn)在面試題中的。 參考文檔: https:///docs/manual/persistence/ |
|
來(lái)自: 硬核項(xiàng)目經(jīng)理 > 《待分類》