做爲一款內存數據庫,爲何斷電後Redis數據不會丟失

前言

Redis 做爲一款內存數據庫,被普遍使用於緩存,分佈式鎖等場景,那麼假如斷電或者因其餘因素致使 Reids 服務宕機,在重啓以後數據會丟失嗎?java

Redis 持久化機制

Redis 雖然是定義爲一個內存數據庫,可是其也支持數據的持久化,在 Redis 中提供了兩種持久化機制:RDB 持久化和 AOF 持久化。redis

RDB 持久化機制

RDB 全稱爲:Redis DataBase,是 Redis 當中默認的持久化方案。當觸發持久化條件時,Redis 默認會生成一個 dump.rdb 文件,Redis 在重啓的時候就會經過解析 dump.rdb 文件進行數據恢復。數據庫

RDB 機制觸發條件

RDB 持久化機制有兩種觸發方式:自動觸發和手動觸發。promise

自動觸發

自動觸發方式也能夠分爲三種:緩存

  • 執行 flushall 命令(flushdb 命令不會觸發)時,不過此時生成的 dump 文件內的數據是空的(dump 文件還會存儲一些頭信息,因此文件自己是有內容的,只是沒有數據),沒有什麼太大的實際意義。
  • 執行 shutdown 命令時會觸發生成 dump 文件。
  • 經過配置文件自動生成,Redis 中配置文件默認配置以下,只要達到這三個條件中的任意一個,就會觸發 RedisRDB 持久化機制。
save 900 1 //900秒內至少有1個key被添加或者更新
save 300 10 //300秒內至少有10個key被添加或者更新
save 60 10000 //60秒內至少有10000個key被添加或者更新

手動觸發

除了自動觸發,Redis 中還提供了 2 個手動觸發 RDB 機制的命令(這兩個命令不能同時被執行,一旦一個命令正在執行中,另外一個命令會被拒絕執行):服務器

  • save:這個命令會阻塞 Redis 服務器進程,直到成功建立 RDB 文件,也就是說在生成 RDB 文件以前,服務器不能處理客戶端發送的任何命令。
  • bgsave:父進程會執行 fork 操做來建立一個子進程。RDB 文件由子進程來負責生成,父進程能夠正常處理客戶端發送的命令(這裏也是 Redis 不只僅只是單線程的一個體現)。

若是想要知道上一次成功執行 save 或者 bgsave 命令的時間,能夠執行 lastsave 命令進行查看,lastsave 命令返回的是一個 unix 時間戳。app

RDB 機制相關配置文件

除了上面提到的觸發生成 rdb 文件的配置參數,RDB 持久化機制還有以下一些相關命令:分佈式

  • dirrdb 文件生成目錄。默認是 ./(當前目錄),能夠執行命令 config get dir 進行查看,以下圖所示說明當前 dump 文件生成目錄爲 /usr/local/redis-5.0.5/bin工具

  • dbfilenamerdb 文件名。默認是 dump.rdb性能

  • rdbcompressionrdb 文件是不是 LZF 壓縮文件。默認是 yes

  • rdbchecksum:是否開啓數據校驗。默認是 yes

RDB 機制優勢

  • RDB 是一個很是緊湊的壓縮文件,保存了不一樣時間點上的文件,很是適合用來災備和數據恢復。
  • RDB 最大限度地提升了 Redis 的性能,由於 Redis 父進程須要作的惟一的工做就是派生一個子進程來完成剩下的工做,父進程永遠不會執行磁盤 I/O 或相似的耗時操做。
  • 與後面介紹的 AOF 持久化機制比較,RDB 方式恢復數據的速度更快。

RDB 機制缺點

  • RDB 沒法作到實時備份,因此若是 Redis 因異常中止工做而沒有正確的關機,那麼從上一次備份的到異常宕機的這一段時間的數據將會丟失。
  • 二、RDB 一般須要父進程來執行 fork 操做建立子線程,因此若是頻繁執行 fork 操做而 CPU 性能又不是很高的話可能會形成短期內父進程不可用。

AOF 持久化機制

AOF 全稱爲:Append Only File,是 Redis 當中提供的另外一種持久化機制。AOF 採用日誌的形式將每一個寫操做追加到文件中。開啓 AOF 機制後,只要執行更改 Redis 數據的命令時,命令就會被寫入到 AOF 文件中。在 Redis 重啓的時候會根據日誌內容依次執行 AOF 文件中的命令來恢復數據。

AOFRDB 最大的不一樣是:AOF 記錄的是執行命令(相似於 MySQLbinlogstatement 格式),而RDB 記錄的是數據(相似於 MySQLbinlogrow 格式)。

須要注意的是:假如同時開啓了 RDBAOF 兩種機制,那麼 Redis 會優先選擇 AOF 持久化文件來進行數據恢復。

AOF 機制如何開啓

AOF 機制默認是關閉的,能夠經過如下配置文件進行修改

appendonly no  //是否開啓AOF機制,默認是no表示關閉,修改成yes則表示開啓
appendfilename "appendonly.aof"  //AOF文件名

PS:和 RDB 機制同樣,其生成文件的路徑也是經過 dir 屬性進行配置。

AOF 機制數據是否實時寫入磁盤

AOF 機制下數據是否實時寫入磁盤,這個和 MySQLredo log 機制很相似,也是須要經過參數來進行控制。

AOF 數據什麼時候寫入磁盤由參數 appendfsync 來進行控制:

appendfsync 描述 備註
always 寫入緩存的同時通知操做系統刷新(fsync)到磁盤(可是也可能會有部分操做系統只是儘快刷盤,而不是實時刷盤) Slow, Safest
everysec 先寫入緩存,而後每秒中刷一次盤(默認值),這種模式極端狀況可能會丟失 1s 的數據 Compromise
no 只寫入緩存,何時刷盤由操做系統本身決定 Faster

AOF 文件重寫

AOF 機制主要是經過記錄執行命令的方式來實現的,那麼隨着時間的增長,AOF 文件不可避免的會愈來愈大,並且可能會出現不少冗餘命令。好比同一個 key 值執行了 10000set 操做,實際上前面 9999 次對恢復數據來講都是沒用的,只須要執行最後一次命令就能夠把數據恢復,正是爲了不這種問題,AOF 機制就提供了文件重寫功能。

重寫原理分析

AOF 重寫時 Redis 並不會去分析原有的文件,由於若是原有文件過大,分析也會很耗時,因此 Redis 選擇的作法就是從新去 Redis 中讀取現有的鍵值對,而後用一條命令記錄鍵值對的值

只使用一條命令也有一個前提,那就是一個集合鍵或者列表鍵或者哈希鍵內包含的元素不能超過 64 個,一旦超過 64 個,就會使用多條命令來進行記錄。

AOF 重寫緩衝區

AOF 重寫的時候通常都會有大量的寫操做,因此爲了避免阻塞客戶端的命令請求,Redis 會把重寫操做放入到子進程中執行,可是放入子進程中執行也會帶來一個問題,那就是重寫期間若是同時又執行了客戶端發過來的命令,又該如何保證數據的一致性?

爲了解決數據不一致問題,Redis 中引入了一個 AOF 重寫緩衝區。當開始執行 AOF 文件重寫以後又接收到客戶端的請求命令,不但要將命令寫入本來的 AOF 緩衝區(根據上面提到的參數刷盤),還要同時寫 入 AOF 重寫緩衝區:

一旦子進程完成了 AOF 文件的重寫,此時會向父進程發出信號,父進程收到信號以後會進行阻塞(阻塞期間不執行任何命令),並進行如下兩項工做:

  1. AOF 重寫緩衝區的文件刷新到新的 AOF 文件內。
  2. 將新 AOF 文件進行更名並原子的替換掉舊的 AOF 文件。

完成了上面的兩項工做以後,整個 AOF 重寫工做完成,父進程開始正常接收命令。

AOF 機制觸發條件

AOF 機制的觸發條件一樣也分爲自動觸發和手動觸發。

  • 自動觸發:自動觸發能夠經過如下參數進行設置:
auto-aof-rewrite-percentag //文件大小超過上次AOF重寫以後的文件的百分比。默認100,也就是默認達到上一次AOF重寫文件的2倍以後會再次觸發AOF重寫
auto-aof-rewrite-min-size //設置容許重寫的最小AOF文件大小,默認是64M。主要是避免知足了上面的百分比,可是文件仍是很小的狀況。
  • 手動觸發:執行 bgrewriteaof 命令。

注意:bgrewriteaof 命令也不能和上面 RDB 持久化命令 bgsave 同時執行,這麼作是爲了不同時建立兩個子進程來同時執行大量寫磁盤操做,影響到 Redis 的性能。

AOF 機制機制優勢

  • 使用 AOF 機制,能夠自由選擇不一樣 fsync (刷盤)策略,並且在默認策略下最多也僅僅是損失 1s 的數據。
  • AOF 日誌是一個僅追加的日誌,所以若是出現斷電,也不存在查找或損壞問題。即便因爲某些緣由(磁盤已滿或其餘緣由),日誌已經寫了一半的命令結束,redis-check-aof工具也可以輕鬆地修復它。
  • AOF 文件變得太大時,Redis 可以在後臺自動重寫。
  • 不一樣於 RDB 的文件格式,AOF 是一種易於理解和解析的格式,依次包含全部操做的日誌。

AOF 機制機制缺點

  • 對於相同的數據集,AOF 文件一般比等效的 RDB 文件大。
  • 根據 fsync 的具體策略,AOF 機制可能比 RDB 機制慢。可是通常狀況下,fsync 設置爲每秒的性能仍然很高,禁用 fsync 後,即便在高負載下,它的速度也能和 RDB 同樣快。
  • 由於 AOF 文件是追加形式,可能會遇到 BRPOPLPUSH 等阻塞命令的錯誤,從而致使生成的 AOF 在從新加載時不能複製徹底相同的數據集,而 RDB 文件每次都是從新從頭建立快照,這在必定程度上來講 RDB 文件更加健壯。

總結

本文主要介紹了 Redis 的兩種持久化機制:RDBAOF,並分別介紹了兩種持久化機制的原理,經過對兩種持久化機制的對比分析了兩種持久化機制各自的優勢和缺點。

相關文章
相關標籤/搜索