Redis(四)持久化

官網介紹:http://www.redis.io

image-20220929143549023

Redis 提供了2個不同形式的持久化方式。

  • RDB(Redis DataBase)
  • AOF(Append Of File)

第一章 RDB(Redis DataBase)

1.1 官網介紹

img

1.2 RDB是什麼?

指定的時間間隔內將內存中的數據集快照寫入磁盤, 也就是行話講的Snapshot快照,它恢復時是將快照文件直接讀到內存裏

1.3 備份是如何執行的?

Redis會單獨創建(fork)一個子進程來進行持久化,會先將數據寫入到 一個臨時文件中,待持久化過程都結束了,再用這個臨時文件替換上次持久化好的文件。 整個過程中,主進程是不進行任何IO操作的,這就確保了極高的性能 如果需要進行大規模數據的恢復,且對於數據恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

RDB的缺點是最後一次持久化後的數據可能丟失

1.4 Fork

  • Fork的作用是複製一個與當前進程一樣的進程。新進程的所有數據(變量、環境變量、程序計數器等) 數值都和原進程一致,但是是一個全新的進程,並作爲原進程的子進程
  • 在Linux程序中,fork()會產生一個和父進程完全相同的子進程,但子進程在此後多會exec系統調用,出於效率考慮,Linux中引入了“寫時複製技術
  • 一般情況父進程和子進程會共用同一段物理內存,只有進程空間的各段的內容要發生變化時,纔會將父進程的內容複製一份給子進程。

1.5 RDB持久化流程

image-20220929144154832

1.6 dump.rdb文件

在redis.conf中配置文件名稱,默認爲dump.rdb

img

1.7 配置位置

rdb文件的保存路徑,也可以修改。默認爲Redis啓動時命令行所在的目錄下

dir "/myredis/"

img

1.8 如何觸發RDB快照;保持策略

配置文件中默認的快照配置

img

命令save VS bgsave

save :save時只管保存,其它不管,全部阻塞。手動保存。不建議。

bgsave:Redis會在後臺異步進行快照操作, 快照同時還可以響應客戶端請求。

可以通過lastsave 命令獲取最後一次成功執行快照的時間

flushall命令

執行flushall命令,也會產生dump.rdb文件,但裏面是空的,無意義

SNAPSHOTTING快照

Save

格式:save 秒鐘 寫操作次數

RDB是整個內存的壓縮過的Snapshot,RDB的數據結構,可以配置複合的快照觸發條件,

默認是1分鐘內改了1萬次,或5分鐘內改了10次,或1分鐘內改了1次。

禁用

不設置save指令,或者給save傳入空字符串

stop-writes-on-bgsave-error

img

當Redis無法寫入磁盤的話,直接關掉Redis的寫操作。推薦yes.

rdbcompression壓縮文件

img

對於存儲到磁盤中的快照,可以設置是否進行壓縮存儲。如果是的話,redis會採用LZF算法進行壓縮。

如果你不想消耗CPU來進行壓縮的話,可以設置爲關閉此功能。推薦yes.

rdbchecksum檢查完整性

img

在存儲快照後,還可以讓redis使用CRC64算法來進行數據校驗,但是這樣做會增加大約10%的性能消耗,如果希望獲取到最大的性能提升,可以關閉此功能

推薦yes.

rdb的備份

先通過config get dir 查詢rdb文件的目錄

將*.rdb的文件拷貝到別的地方

rdb的恢復

  • 關閉Redis
  • 先把備份的文件拷貝到工作目錄下 cp dump2.rdb dump.rdb
  • 啓動Redis, 備份數據會直接加載

1.9 RDB優勢

  • 適合大規模的數據恢復
  • 對數據完整性和一致性要求不高更適合使用
  • 節省磁盤空間
  • 恢復速度快

img

1.10 RDB劣勢

  • Fork的時候,內存中的數據被克隆了一份,大致2倍的膨脹性需要考慮
  • 雖然Redis在fork時使用了寫時拷貝技術,但是如果數據龐大時還是比較消耗性能。
  • 在備份週期在一定間隔時間做一次備份,所以如果Redis意外down掉的話,就會丟失最後一次快照後的所有修改(最後一次持久化後的數據可能丟失)。

1.11 如何停止

動態停止RDB:redis-cli config set save ""#save後給空值,表示禁用保存策略

1.12 RDB小總結

img

第二章 AOF(Append Only File)

2.1 AOF是什麼

日誌的形式來記錄每個寫操作(增量保存),將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加文件但不可以改寫文件,redis啓動之初會讀取該文件重新構建數據,換言之,redis 重啓的話就根據日誌文件的內容將寫指令從前到後執行一次以完成數據的恢復工作

2.2 AOF持久化流程

(1)客戶端的請求寫命令會被append追加到AOF緩衝區內;

(2)AOF緩衝區根據AOF持久化策略[always,everysec,no]將操作sync同步到磁盤的AOF文件中;

(3)AOF文件大小超過重寫策略或手動重寫時,會對AOF文件rewrite重寫,壓縮AOF文件容量;

(4)Redis服務重啓時,會重新load加載AOF文件中的寫操作達到數據恢復的目的;

img

2.3 AOF默認不開啓

可以在redis.conf中配置文件名稱,默認爲 appendonly.aof

AOF文件的保存路徑,同RDB的路徑一致。

2.4 AOF和RDB同時開啓,redis聽誰的?

AOF和RDB同時開啓,系統默認取AOF的數據(數據不會存在丟失)

2.5 AOF啓動/修復/恢復

AOF的備份機制和性能雖然和RDB不同, 但是備份和恢復的操作同RDB一樣,都是拷貝備份文件,需要恢復時再拷貝到Redis工作目錄下,啓動系統即加載。

正常恢復

  • 修改默認的appendonly no,改爲yes
  • 將有數據的aof文件複製一份保存到對應目錄(查看目錄:config get dir)
  • 恢復:重啓redis然後重新加載

異常恢復

  • 修改默認的appendonly no,改爲yes
  • 如遇到AOF文件損壞,通過/usr/local/bin/redis-check-aof--fix appendonly.aof進行恢復
  • 備份被寫壞的AOF文件
  • 恢復:重啓redis,然後重新加載

2.6 AOF同步頻率設置

appendfsync always

始終同步,每次Redis的寫入都會立刻記入日誌;性能較差但數據完整性比較好

appendfsync everysec

每秒同步,每秒記入日誌一次,如果宕機,本秒的數據可能丟失。

appendfsync no

redis不主動進行同步,把同步時機交給操作系統。

2.7 Rewrite壓縮

Rewrite壓縮是什麼

AOF採用文件追加方式,文件會越來越大爲避免出現此種情況,新增了重寫機制, 當AOF文件的大小超過所設定的閾值時,Redis就會啓動AOF文件的內容壓縮, 只保留可以恢復數據的最小指令集.可以使用命令bgrewriteaof

重寫原理,如何實現重寫

AOF文件持續增長而過大時,會fork出一條新進程來將文件重寫(也是先寫臨時文件最後再rename),redis4.0版本後的重寫,是指上就是把rdb 的快照,以二級制的形式附在新的aof頭部,作爲已有的歷史數據,替換掉原來的流水賬操作。

no-appendfsync-on-rewrite:

如果 no-appendfsync-on-rewrite=yes ,不寫入aof文件只寫入緩存,用戶請求不會阻塞,但是在這段時間如果宕機會丟失這段時間的緩存數據。(降低數據安全性,提高性能)

​ 如果 no-appendfsync-on-rewrite=no, 還是會把數據往磁盤裏刷,但是遇到重寫操作,可能會發生阻塞。(數據安全,但是性能降低)

觸發機制,何時重寫

Redis會記錄上次重寫時的AOF大小,默認配置是當AOF文件大小是上次rewrite後大小的一倍且文件大於64M時觸發重寫雖然可以節約大量磁盤空間,減少恢復時間。但是每次重寫還是有一定的負擔的,因此設定Redis要滿足一定條件纔會進行重寫。

auto-aof-rewrite-percentage:設置重寫的基準值,文件達到100%時開始重寫(文件是原來重寫後文件的2倍時觸發)

auto-aof-rewrite-min-size:設置重寫的基準值,最小文件64MB。達到這個值開始重寫。

例如:文件達到70MB開始重寫,降到50MB,下次什麼時候開始重寫?100MB

系統載入時或者上次重寫完畢時,Redis會記錄此時AOF大小,設爲base_size,

如果Redis的AOF當前大小>= base_size +base_size*100% (默認)且當前大小>=64mb(默認)的情況下,Redis會對AOF進行重寫。

重寫流程

類似RDB的寫時複製機制

(1)bgrewriteaof觸發重寫,判斷是否當前有bgsave或bgrewriteaof在運行,如果有,則等待該命令結束後再繼續執行。

(2)主進程fork出子進程執行重寫操作,保證主進程不會阻塞。

(3)子進程遍歷redis內存中數據到臨時文件,客戶端的寫請求同時寫入aof_buf緩衝區和aof_rewrite_buf重寫緩衝區保證原AOF文件完整以及新AOF文件生成期間的新的數據修改動作不會丟失。

(4)

1).子進程寫完新的AOF文件後,向主進程發信號,父進程更新統計信息。

2).主進程把aof_rewrite_buf中的數據寫入到新的AOF文件。

(5)使用新的AOF文件覆蓋舊的AOF文件,完成AOF重寫。

img

2.8 AOF優勢

img

  • 備份機制更穩健,丟失數據概率更低。
  • 可讀的日誌文本,通過操作AOF穩健,可以處理誤操作。

2.9 AOF劣勢

  • 比起RDB佔用更多的磁盤空間。
  • 恢復備份速度要慢。
  • 每次讀寫都同步的話,有一定的性能壓力。
  • 存在個別Bug,造成恢復不能。

2.10 AOF小總結

img

第三章 RDB和AOF總結(Which one)

3.1 用哪個好

官方推薦兩個都啓用。(同時啓用就是使用AOF進行恢復,RDB做容災備份)

如果對數據不敏感,可以選單獨用RDB。

不建議單獨用 AOF,因爲可能會出現Bug。

如果只是做純內存緩存,可以都不用。

3.2 官網建議

img

  • RDB持久化方式能夠在指定的時間間隔能對你的數據進行快照存儲

  • AOF持久化方式記錄每次對服務器寫的操作,當服務器重啓的時候會重新執行這些命令來恢復原始的數據,AOF命令以redis協議追加保存每次寫的操作到文件末尾.

  • Redis還能對AOF文件進行後臺重寫,使得AOF文件的體積不至於過大

  • 只做緩存:如果你只希望你的數據在服務器運行的時候存在,你也可以不使用任何持久化方式.

  • 同時開啓兩種持久化方式

    在這種情況下,當redis重啓的時候會優先載入AOF文件來恢復原始的數據, 因爲在通常情況下AOF文件保存的數據集要比RDB文件保存的數據集要完整.

  • RDB的數據不實時,同時使用兩者時服務器重啓也只會找AOF文件。那要不要只使用AOF呢?

    建議不要,因爲RDB更適合用於備份數據庫(AOF在不斷變化不好備份), 快速重啓,而且不會有AOF可能潛在的bug,留着作爲一個萬一的手段。

  • 性能建議

因爲RDB文件只用作後備用途,建議只在Slave上持久化RDB文件,而且只要15分鐘備份一次就夠了,只保留save 900 1這條規則。 如果使用AOF,好處是在最惡劣情況下也只會丟失不超過兩秒數據,啓動腳本較簡單隻load自己的AOF文件就可以了。代價,一是帶來了持續的IO,二是AOF rewrite的最後將rewrite過程中產生的新數據寫到新文件造成的阻塞幾乎是不可避免的。只要硬盤許可,應該儘量減少AOF rewrite的頻率,AOF重寫的基礎大小默認值64M太小了,可以設到5G以上。默認超過原大小100%大小時重寫可以改到適當的數值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章