成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Redis持久化:RDB和AOF

數據庫 Redis
重啟 Redis 時,我們很少使用 RDB 來恢復內存狀態,因為可能丟失大量數據。通常采用 AOF 日志重放,但是重放 AOF 日志性能相對 RDB 來說要慢很多,在Redis實例很大的情況下,啟動需要花費很長時間。

Redis 數據存儲在內存中,如果不想辦法將數據保存到硬盤上,一旦Redis重啟(退出/故障),內存的數據將會全部丟失。我們肯定不想 Redis 里的數據由于某些故障全部丟失(導致所有請求都走 MySQL),即便發生了故障也希望可以將Redis原有的數據恢復過來,這就是持久化的作用。

Redis 提供了兩種不同的持久化方法來將數據存儲到硬盤里邊:

  • **RDB(Redis Database)**,將某一時刻的所有數據保存到一個 RDB 文件中。
  • **AOF(append-only-file)**,當Redis服務器執行寫命令的時候,將執行的寫命令保存到 AOF 文件中。

RDB內存快照,讓宕機快速恢復

1.什么是RDB內存快照?

在 Redis 執行“寫”指令的過程中,內存數據一直會變化,所謂內存快照,指的就是 Redis 內存中數據在某一時刻的狀態數據,好比時間定格在某一時刻。當我們拍照時,通過照片就能把某一時刻的瞬間畫面完全記錄下來。Redis 跟這個類似,就是把某一刻的數據以文件的形式拍下來,寫到磁盤上,這個快照文件叫做 RDB 文件,RDB 就是 Redis Database 的縮寫。

圖片


2.生成RDB的策略

Redis 并不會在每次執行“寫”指令的時候都觸發 RDB 寫磁盤,只需要在執行內存快照的時候寫磁盤,這樣既保證了唯快不破,還實現了持久化,宕機快速恢復。

我們知道 Redis 的單線程模型決定了我們要盡可能地避免會阻塞主線程的操作,所以就需要盡可能地避免 RDB 文件生成阻塞主線程。為此Redis提供了兩個指令用于生成 RDB 文件:

  • SAVE:會阻塞 Redis 服務器進程,服務器不能接收任何請求,直到 RDB 文件創建完畢為止。
  • BGSAVE:fork 出一個子進程,由子進程來負責創建 RDB 文件,服務器進程可以繼續接收請求。

除了手動調用 SAVE 或者 BGSAVE 命令生成 RDB 文件之外,我們可以使用配置的方式來定期執行:在默認的配置下,如果以下的條件被觸發,就會執行 BGSAVE 命令。

save 900 1              #在900秒(15分鐘)之后,至少有1個key發生變化,
save 300 10             #在300秒(5分鐘)之后,至少有10個key發生變化
save 60 10000           #在60秒(1分鐘)之后,至少有10000個key發生變化

3.RDB實現原理

在RDB執行期間為了保證快照的數據一致性,只能處理讀操作,不能修改正在執行快照的數據,這種場景,Redis 是允許的。那 Redis 是如何實現一邊處理寫請求,同時生成RDB文件的呢?

Redis 使用操作系統的多進程寫時復制技術 COW(Copy On Write)來實現快照的持久化。

Redis 在持久化是會調用 glibc 的函數(linux系統中最底層的api)fork產生一個子進程,快照持久化完全交給子進程來處理,父進程繼續處理客戶端請求。子進程剛剛產生時,它和父進程共享內存里面的代碼段和數據段,這時可以將父子進程想象成一個連體嬰兒,共享身體。這是Linux操作系統的機制,為了節約內存資源,所以盡可能讓它們共享起來,在進程分離的一瞬間,內存的增長幾乎沒有明顯的變化。

BGSAVE 子進程可以共享主線程的所有內存數據,讀取主線程的數據并寫入到 RDB 文件。當主線程執行寫指令修改數據的時候,這個數據就會復制一份副本,BGSAVE 子進程讀取這個副本數據寫到 RDB 文件。

在執行 SAVE 或 BGSAVE 命令創建一個新的 RDB 文件時,程序會對數據庫中的鍵進行檢查,已過期的鍵不會被保存到新創建的RDB 文件中。這既保證了快照的完整性,也允許主線程同時對數據進行修改,避免了對正常業務的影響。

圖片


4.RDB的優缺點

優點

  • RDB 文件是一個很簡潔的單文件,采用 二進制 + 數據壓縮 的方式寫磁盤,文件體積小,數據恢復速度快。
  • RDB 的性能很好,需要進行持久化時,主進程會 fork 一個子進程出來,然后把持久化的工作交給子進程,自己不會有相關的I/O操作。

缺點

  • RDB 容易造成數據的丟失。假設每5分鐘保存一次快照,如果 Redis 因為某些原因不能正常工作,那么從上次產生快照到 Redis 出現問題這段時間的數據就會丟失了。
  • RDB 使用 fork() 產生子進程進行數據的持久化,會阻塞主線程,如果數據比較大的話可能就會花費點時間,造成 Redis 停止服務幾毫秒。如果數據量很大且CPU性能不是很好的時候,停止服務的時間甚至會到1秒。

另外,過于頻繁的執行全量數據快照,有兩個嚴重的性能開銷:

  • 頻繁生成 RDB 文件寫入磁盤,磁盤壓力過大。可能會出現上一個 RDB 還未完成,下一個又開始生成,陷入死循環。
  • fork 出 BGSAVE 子進程這個動作本身會阻塞主線程,主線程的內存越大,阻塞時間越長。

AOF寫后日志,避免宕機數據丟失

1.什么是AOF寫后日志?

AOF(Append Only File)寫后日志,AOF 持久化就是將修改數據庫狀態的命令保存到 AOF 文件中,被寫入的命令都是以 Redis 的命令請求協議格式保存的,Redis 的命令請求協議是純文本格式。

假設 AOF 日志記錄了 Redis 實例創建以來所有的修改指令序列,那么就可以通過一個空的 Redis 實例順序執行所有的指令,也就是“重放”,來恢復Redis當前實例的內存數據結構的狀態。

寫后日志和寫前日志的對比

寫前日志(WAL,Write Ahead Log):在實際寫數據之前,將修改的數據寫到日志文件中,故障恢復得以保證。比如 MySQL Innodb 存儲引擎中的 redo log(重做日志)便是記錄修改的數據日志,在實際修改數據前先記錄修改日志再執行修改數據。

寫后日志:先執行“寫”指令請求,將數據寫入內存,再記錄日志。

圖片


日志格式

當 Redis 接收到 “set key value” 命令將數據寫入到內存之后,會按照如下格式寫入 AOF 文件:

  • *3:表示當前指令分為三個部分,每部分都是 “$ + 數字” 開頭,緊跟后面是該部分具體的命令、鍵、值
  • 數字:表示這部分的命令、鍵、值占用的字節大小。比如 “$3” 表示這部分包含三個字節,也就是 set 指令。

圖片


寫后日志的好處

寫后日志避免了額外的檢查開銷,不需要對執行的命令進行語法檢查。如果使用寫前日志的話,就需要先檢查語法是否有誤,否則日志記錄了錯誤的命令,在使用日志恢復的時候就會報錯。另外,寫后記錄日志,避免了阻塞當前“寫”指令的執行。

2.寫回策略

使用 AOF 也不是萬無一失的,假如 Redis 剛執行完指令,還沒記錄日志就宕機了,就有可能丟失這個命令的相關數據;還有, AOF 避免了當前命令的阻塞,但是可能會給下一個命令帶來阻塞的風險。AOF 日志是主線程執行的,將日志寫入磁盤過程中,如果磁盤壓力過大就會導致磁盤寫操作很慢,導致后續的“寫”指令阻塞。

發現了沒,這兩個問題與磁盤寫回有關,如果能合理控制“寫”指令執行完后 AOF 日志寫回磁盤的時機,問題就可以迎刃而解。

為了提高文件的寫入效率,當用戶調用 write 函數,將一些數據寫入到文件時候,操作系統通常會將寫入數據暫時保存在一個內存緩沖區里,等到緩沖區的空間被填滿或者超過了制定的限制之后,才真正將緩沖區中的數據寫入到磁盤里面。

這種做法雖然提高了效率,但也為寫入數據帶來了安全問題,因為如果計算機發生停機,那么保存在內存緩沖區里的寫入數據將會丟失。為此系統提供了 fsync 和 fdatasync 兩個同步函數,它們可以強制讓操作系統立即將緩沖區中的數據寫入到硬盤里,從而確保寫入數據的安全性。

與之相對應 Redis 提供了 AOF 配置項 appendfsync 寫回策略來控制 AOF 持久化功能的效率和安全性。

appendfsync always     # 同步寫回,寫指令執行完畢立即將 aof_buf 緩沖區中的內容寫到 AOF 文件。
appendfsync everysec   # 每秒寫回,寫指令執行完畢,把日志寫到 aof_buf 緩沖區,每隔一秒同步到磁盤,該策略為AOF的默認策略。
appendfsync no         # 操作系統控制,寫指令執行完畢,把日志寫到 aof_buf 緩沖區,由操作系統決定何時寫回磁盤。

3.AOF重寫機制

由于 AOF 記錄的是一個個指令的內容,這就會導致保存的文件太大,另外,故障恢復的時候需要執行每一個指令,如果日志文件太大,整個恢復過程就會非常慢。為此,Reids 設計了 AOF 重寫機制,提供了 bgrewriteaof 命令用于對 AOF 文件進行瘦身。

其原理就是開辟一個子進程對內存進行遍歷轉換成一系列 Redis 的操作指令,序列化到一個新的 AOF 日志文件中,序列化完畢后再將操作期間發生的增量 AOF 日志追加到這個新的 AOF 日志文件中,追加完畢后立即替換舊的 AOF 日志文件。瘦身工作就完成了。

重寫機制有“多變一”的功能,將舊日志中的多條指令,在重寫后就變成了一條指令。如下所示:三條 lpush 命令,經過 AOF 重寫后生成一條,對于多次修改的場景,縮減效果明顯。

圖片

重寫過程

和 AOF 日志由主線程寫回不同,重寫過程實際是由后臺子進程 bgrewriteof 完成的,這也是為了避免阻塞主線程,導致性能下降。

總的來說,一共出現兩個日志,一次內存數據拷貝,分別是舊的 AOF 日志和新的 AOF 重寫日志和Redis 數據拷貝。大致流程如下圖所示:

圖片


在上圖中,Redis 會將重寫過程中接收到的“寫”指令操作同時記錄到舊的 AOF 緩沖區和新的 AOF 重寫緩沖區,這樣重寫日志也保存了最新的操作,等到拷貝數據的所有操作記錄重寫完成后,重寫緩沖區記錄的最新操作也會寫到新的 AOF 文件中。

每次 AOF 重寫時,Redis 會先執行一次內存拷貝,用于遍歷數據生成重寫記錄。防止 AOF 重寫過程失敗,導致原 AOF 文件被污染,無法做恢復使用。

使用兩個日志可以保證在重寫過程中,新寫入的數據不會丟失,并且保持數據的一致性。

4.AOF 的優點和缺點

優點

  • AOF比RDB可靠。可以靈活制定不同的fsync策略。
  • AOF日志文件是一個純追加的文件。就算是遇到突然停電的情況,也不會出現日志的定位或者損壞問題。
  • 當AOF文件過大時,Redis會自動在后臺進行重寫。
  • AOF以命令格式存儲于文件中,在數據恢復時,AOF文件比RDB文件更容易讓開發人員看懂,并加以修改。

缺點

  • 在相同的數據集下,AOF文件的大小一般會比RDB文件大。
  • 在某些fsync策略下,AOF的速度會比RDB慢。通常fsync設置為每秒一次就能獲得比較高的性能,而在禁止fsync的情況下速度可以達到RDB的水平。

混合日志模型

重啟 Redis 時,我們很少使用 RDB 來恢復內存狀態,因為可能丟失大量數據。通常采用 AOF 日志重放,但是重放 AOF 日志性能相對 RDB 來說要慢很多,在Redis實例很大的情況下,啟動需要花費很長時間。

Redis 4.0 為了解決這個問題,提供了一個新的持久化選項--混合持久化,將 RDB 文件的內容和增量 AOF 日志文件存放到一起,這里的 AOF 日志不再是全量的日志,而是自持久化開始到持久化結束的這段時間發生的增量 AOF 日志,通常這部分日志很小。

圖片


在 Redis 重啟的時候,先加載 RDB 的內容,然后再重放增量 AOF 日志,這樣的操作既保證了 Redis 重啟速度,又降低數據丟失風險。

總結

  • Redis 提供 RDB 快照持久化方案,記錄某一時刻數據狀態
  • Redis 通過寫時復制技術設計了BGSAVE,避免執行快照期間對讀寫指令的影響。
  • Redis 提供了 AOF 寫后日志持久化方案,記錄每一條操作指令。
  • Redis 通過 AOF 重寫方案,避免 AOF文件過大。
  • Redis 提供了混合持久化的方案,RDB + AOF 實現持久化保證數據可靠性,同時支持故障后的數據快速恢復。

參考

Redis設計與實(https://weread.qq.com/web/reader/d35323e0597db0d35bd957bk73532580243735b90b45ac8)

Redis核心技術與實戰(https://time.geekbang.org/column/intro/329)

圖片

責任編輯:武曉燕 來源: 政采云技術
相關推薦

2021-07-18 07:59:42

RedisRDBAOF

2019-05-17 08:55:49

RedisRDBAOF

2021-03-10 00:02:01

Redis

2024-03-26 00:03:08

Redis數據RDB

2020-01-06 14:54:31

RDBAOFRedis

2024-09-12 08:49:53

2020-12-11 11:40:37

RDBAOFRedis

2021-10-18 07:43:30

RedisAOF日志RDB快照

2024-09-06 17:49:46

2023-03-13 08:08:48

數據庫Redis

2021-02-04 08:01:35

RedisRDBAOF

2025-01-22 10:16:46

RedisRDBAOF

2024-09-29 09:25:53

2024-12-20 12:15:06

RedisRDB持久化

2021-12-12 10:29:41

AOFRedisAOF日志

2023-09-12 10:49:44

Redis數據庫

2021-05-28 10:25:39

Redis數據庫內存

2024-11-22 08:31:32

Redis數據持久化高可用

2025-03-14 08:00:00

AOFRedis數據庫

2019-11-18 16:20:48

RedisRDB數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 户外露出一区二区三区 | 青青草网 | 精品国产31久久久久久 | 男女免费视频网站 | 日韩欧美精品 | 国产在线一区二区 | 日韩有码在线观看 | 久久国产精品视频 | 在线一区二区三区 | 国产高清精品一区二区三区 | 中文字幕亚洲精品 | 91文字幕巨乱亚洲香蕉 | 亚洲视频欧美视频 | 蜜桃视频一区二区三区 | 亚洲综合大片69999 | 久久狼人天堂 | 日本黄色免费视频 | 91精品国产91久久综合桃花 | 欧美国产日韩在线观看 | 精品福利一区二区三区 | 91精品久久久久久久久 | 成年人黄色一级片 | 天天躁日日躁狠狠的躁天龙影院 | 色狠狠桃花综合 | 免费黄色录像视频 | 国产999精品久久久久久绿帽 | 国产欧美日韩视频 | 久久国产精品久久 | 久久99精品国产麻豆婷婷 | av日韩一区 | 日韩中文一区 | 精品无码久久久久久国产 | 亚洲欧美中文日韩在线v日本 | 日韩在线中文字幕 | www.性色| 亚洲精品91 | 亚洲欧美一区二区三区情侣bbw | 天天看天天爽 | 视频在线亚洲 | 日韩精品一二三区 | 精品国产女人 |