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

Redis宕機后,Redis如何實現快速恢復?

數據庫 Redis
在本篇文章中,我們深入學習了Redis用于避免數據丟失的內存快照方法。這種持久化方式具有快速恢復數據庫的顯著優勢,只需將RDB文件直接加載到內存中,避免了AOF方式需要逐一重新執行操作命令所帶來的性能低效問題。

當前,我們已經深入了解了Redis中的AOF(Append-Only File)持久化方法,它的優勢在于記錄操作命令,不會顯著增加持久化數據量。通常情況下,只要你沒有選擇always的持久化策略,AOF方法對性能的影響是相對較小的。

然而,由于AOF方法記錄的是操作命令而不是實際的數據,所以在使用AOF進行故障恢復時,需要逐一執行所有的操作日志。當操作日志非常龐大時,這個恢復過程會變得非常緩慢,從而影響了正常的使用體驗。顯然,這并不是我們理想的情況。那么,是否有其他方法既可以保障數據可靠性,又能在宕機后實現快速恢復呢?

當然有,這就是我們今天要一同探討的另一種持久化方法:內存快照。內存快照的概念很像拍照,它記錄了某一時刻的內存中數據狀態,就像照片一樣。當你給朋友拍照時,一張照片能完美地捕捉朋友的瞬間。對于Redis,它通過將某一時刻的數據狀態以文件形式寫入磁盤來實現這種效果,這個文件就是快照,通常稱為RDB文件,其中RDB代表Redis數據庫。

RDB文件的優勢在于,即使發生宕機,快照文件也不會丟失,因此可靠性得到了保證。接下來,我們將深入了解RDB持久化方法,包括它的工作原理和配置等方面的細節。這將有助于你更好地理解如何選擇適當的持久化方法,以滿足你的特定需求。

與AOF持久化相比,RDB持久化記錄的是某一時刻的數據狀態,而不是每個操作命令。這意味著在數據恢復過程中,我們可以直接將RDB文件加載到內存中,迅速完成恢復。聽起來似乎非常理想,但內存快照也并不是毫無缺點的最佳選項。為什么會這樣呢?

我們需要考慮兩個關鍵問題:

  1. 哪些數據進行快照?這關系到快照執行的效率問題。
  2. 在進行快照時,數據是否能夠被修改、新增或刪除?這關系到Redis是否會被阻塞,以及是否能夠同時處理其他請求。

這或許還不夠清晰,我來用拍照的例子進行解釋。當我們拍照時,通常要思考兩個問題:

  • 如何構圖?也就是我們打算在照片中捕捉哪些人或物體。
  • 在按下快門之前,需要確保拍攝對象不亂動,以避免照片模糊。

你可以看到,這兩個問題非常重要,接下來,我們將詳細討論這兩個問題,首先是“構圖”問題,即我們應該選擇哪些數據進行快照。

給哪些內存數據做快照?

Redis 的數據都在內存中,為了提供所有數據的可靠性保證,它執行的是全量快照,也就是說,把內存中的所有數據都記錄到磁盤中,這就類似于給 100 個人拍合影,把每一個人都拍進照片里。這樣做的好處是,一次性記錄了所有數據,一個都不少。

當你給一個人拍照時,只用協調一個人就夠了,但是,拍 100 人的大合影,卻需要協調 100 個人的位置、狀態,等等,這當然會更費時費力。同樣,給內存的全量數據做快照,把它們全部寫入磁盤也會花費很多時間。而且,全量數據越多,RDB 文件就越大,往磁盤上寫數據的時間開銷就越大。

對于 Redis 而言,它的單線程模型就決定了,我們要盡量避免所有會阻塞主線程的操作,所以,針對任何操作,我們都會提一個靈魂之問:“它會阻塞主線程嗎?”RDB 文件的生成是否會阻塞主線程,這就關系到是否會降低 Redis 的性能。

Redis 提供了兩個命令來生成 RDB 文件,分別是 save 和 bgsave。

save:在主線程中執行,會導致阻塞;

bgsave:創建一個子進程,專門用于寫入 RDB 文件,避免了主線程的阻塞,這也是 Redis RDB 文件生成的默認配置。

好了,這個時候,我們就可以通過 bgsave 命令來執行全量快照,這既提供了數據的可靠性保證,也避免了對 Redis 的性能影響。

接下來,我們要關注的問題就是,在對內存數據做快照時,這些數據還能“動”嗎? 也就是說,這些數據還能被修改嗎?這個問題非常重要,這是因為,如果數據能被修改,那就意味著 Redis 還能正常處理寫操作。否則,所有寫操作都得等到快照完了才能執行,性能一下子就降低了。

快照時數據能修改嗎?

在給別人拍照時,一旦對方動了,那么這張照片就拍糊了,我們就需要重拍,所以我們當然希望對方保持不動。對于內存快照而言,我們也不希望數據“動”。

舉個例子。我們在時刻 t 給內存做快照,假設內存數據量是 4GB,磁盤的寫入帶寬是 0.2GB/s,簡單來說,至少需要 20s(4/0.2 = 20)才能做完。如果在時刻 t+5s 時,一個還沒有被寫入磁盤的內存數據 A,被修改成了 A’,那么就會破壞快照的完整性,因為 A’不是時刻 t 時的狀態。因此,和拍照類似,我們在做快照時也不希望數據“動”,也就是不能被修改。

但是,如果快照執行期間數據不能被修改,是會有潛在問題的。對于剛剛的例子來說,在做快照的 20s 時間里,如果這 4GB 的數據都不能被修改,Redis 就不能處理對這些數據的寫操作,那無疑就會給業務服務造成巨大的影響。

你可能會想到,可以用 bgsave 避免阻塞啊。這里我就要說到一個常見的誤區了,避免阻塞和正常處理寫操作并不是一回事。此時,主線程的確沒有阻塞,可以正常接收請求,但是,為了保證快照完整性,它只能處理讀操作,因為不能修改正在執行快照的數據。

為了快照而暫停寫操作,肯定是不能接受的。所以這個時候,Redis 就會借助操作系統提供的寫時復制技術(Copy-On-Write, COW),在執行快照的同時,正常處理寫操作。

簡單來說,bgsave 子進程是由主線程 fork 生成的,可以共享主線程的所有內存數據。bgsave 子進程運行后,開始讀取主線程的內存數據,并把它們寫入 RDB 文件。

此時,如果主線程對這些數據也都是讀操作(例如圖中的鍵值對 A),那么,主線程和 bgsave 子進程相互不影響。但是,如果主線程要修改一塊數據(例如圖中的鍵值對 C),那么,這塊數據就會被復制一份,生成該數據的副本。然后,bgsave 子進程會把這個副本數據寫入 RDB 文件,而在這個過程中,主線程仍然可以直接修改原來的數據。

圖片

寫時復制機制保證快照期間數據可修改

這既保證了快照的完整性,也允許主線程同時對數據進行修改,避免了對正常業務的影響。

到這里,我們就解決了對“哪些數據做快照”以及“做快照時數據能否修改”這兩大問題:Redis 會使用 bgsave 對當前內存中的所有數據做快照,這個操作是子進程在后臺完成的,這就允許主線程同時可以修改數據。

現在,我們再來看另一個問題:多久做一次快照?我們在拍照的時候,還有項技術叫“連拍”,可以記錄人或物連續多個瞬間的狀態。那么,快照也適合“連拍”嗎?

可以每秒做一次快照嗎?

對于內存快照,所謂的“連拍”即連續執行多次快照。這將大大減小快照之間的時間間隔,即使在某一刻發生宕機,由于上一刻的快照剛剛執行,所丟失的數據也會降至最低。然而,快照間隔時間的選擇成為關鍵。

如下圖所示,我們在T0時刻首次執行了一次快照,然后在T0+t時刻再次執行了快照。在這段時間內,數據塊5和9發生了修改。如果在t時間內出現宕機,只能按照T0時刻的快照進行恢復。這時,由于數據塊5和9的修改沒有被記錄在快照中,它們的值將無法完全恢復。


圖片

快照機制下的數據丟失

所以,要想盡可能恢復數據,t 值就要盡可能小,t 越小,就越像“連拍”。那么,t 值可以小到什么程度呢,比如說是不是可以每秒做一次快照?畢竟,每次快照都是由 bgsave 子進程在后臺執行,也不會阻塞主線程。

這種想法其實是錯誤的。雖然 bgsave 執行時不阻塞主線程,但是,如果頻繁地執行全量快照,也會帶來兩方面的開銷。

首先,頻繁將完整的數據寫入磁盤會對磁盤造成巨大的壓力。多個快照爭相使用有限的磁盤帶寬,這可能導致前一個快照尚未完成,后一個快照已經開始,從而產生惡性循環。

另一方面,bgsave子進程需要通過fork操作從主線程中創建。雖然子進程在創建后不會再次阻塞主線程,但是fork這個創建過程本身會阻塞主線程。而且主線程的內存越大,阻塞時間越長。如果頻繁進行fork以創建bgsave子進程,這將頻繁地阻塞主線程。那么,有沒有更好的方法呢?

在這種情況下,可以考慮使用增量快照。增量快照指的是在生成完整快照后,后續的快照只記錄已更改的數據,從而避免每次生成完整快照的開銷。

在第一次做完全量快照后,T1 和 T2 時刻如果再做快照,我們只需要將被修改的數據寫入快照文件就行。但是,這么做的前提是,我們需要記住哪些數據被修改了。你可不要小瞧這個“記住”功能,它需要我們使用額外的元數據信息去記錄哪些數據被修改了,這會帶來額外的空間開銷問題。如下圖所示:

圖片

增量快照示意圖

如果我們為每個鍵值對的修改都記錄一條記錄,那么當有1萬個鍵值對被修改時,我們就需要額外記錄1萬條記錄。有時,鍵值對可能非常小,例如只有32字節,而為了記錄它們的修改,我們可能需要8字節的元數據信息。在某些情況下,為了記錄修改所引入的額外空間開銷會相當大。對于內存資源寶貴的Redis來說,這可能不是一個劃算的選擇。

從這里可以看出,雖然與AOF相比,快照的恢復速度更快,但快照的頻率很難確定。如果頻率太低,一旦在兩次快照之間發生宕機,可能會有大量數據丟失。如果頻率太高,將導致額外的開銷。那么,有沒有一種方法既能利用RDB的快速恢復,又能以較小的開銷盡量減少數據丟失呢?

Redis 4.0 中提出了一個混合使用 AOF 日志和內存快照的方法。簡單來說,內存快照以一定的頻率執行,在兩次快照之間,使用 AOF 日志記錄這期間的所有命令操作。

這樣一來,快照不用很頻繁地執行,這就避免了頻繁 fork 對主線程的影響。而且,AOF 日志也只用記錄兩次快照間的操作,也就是說,不需要記錄所有操作了,因此,就不會出現文件過大的情況了,也可以避免重寫開銷。

如下圖所示,T1 和 T2 時刻的修改,用 AOF 日志記錄,等到第二次做全量快照時,就可以清空 AOF 日志,因為此時的修改都已經記錄到快照中了,恢復時就不再用日志了。

圖片

內存快照和AOF混合使用

這個方法既能享受到 RDB 文件快速恢復的好處,又能享受到 AOF 只記錄操作命令的簡單優勢,頗有點“魚和熊掌可以兼得”的感覺,建議你在實踐中用起來。

小結

在本篇文章中,我們深入學習了Redis用于避免數據丟失的內存快照方法。這種持久化方式具有快速恢復數據庫的顯著優勢,只需將RDB文件直接加載到內存中,避免了AOF方式需要逐一重新執行操作命令所帶來的性能低效問題。

然而,內存快照方法也存在一些限制。它類似于拍攝內存的“大合影”,這不可避免地會占用較多的時間和計算資源。雖然Redis采用了bgsave和寫時復制等方式來最小化內存快照對正常讀寫操作的影響,但頻繁的快照仍然可能對性能產生不可接受的壓力。因此,將RDB和AOF方式混合使用,可以充分利用它們各自的優勢,規避它們的弱點,以較小的性能開銷來同時保證數據的可靠性和性能。

最后,關于選擇AOF和RDB的問題,我愿意提供三點建議:

  1. 當數據絕不能丟失時,混合使用內存快照和AOF方式是一個明智的選擇。
  2. 如果可以容忍分鐘級別的數據丟失,可以只使用RDB方式。
  3. 如果決定僅采用AOF方式,首選使用everysec的配置選項,因為它在可靠性和性能之間取得了較好的平衡。
責任編輯:武曉燕 來源: 碼農本農
相關推薦

2021-02-22 09:01:13

Redis宕機日志

2021-03-18 10:31:27

Redis宕機日志

2023-10-23 11:22:06

Redis數據持久化

2017-05-31 16:10:45

MySQL誤操作恢復數據

2020-07-14 11:00:12

Spring BootRedisJava

2020-03-31 17:05:39

Redis熱 key代理

2016-04-19 18:20:29

阿里巴巴HBase宕機恢復

2021-11-30 06:32:19

Redis宕機集群

2015-10-29 15:36:19

Redis入門

2020-12-31 07:34:04

Redis數據宕機

2020-09-02 17:28:26

Spring Boot Redis集成

2021-01-05 10:48:38

RedisAOF日志RDB快照

2018-07-24 16:40:29

MySQL主從架構主庫宕機

2018-11-01 14:50:01

RedisNoSQL數據庫

2024-12-17 15:39:33

2015-06-29 11:29:08

2024-03-22 12:10:39

Redis消息隊列數據庫

2020-11-25 08:57:29

Redis Docke

2023-08-21 19:10:34

Redis分布式

2024-11-04 16:01:01

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 偷拍自拍第一页 | 国产精品久久久久久妇女6080 | 欧美精品在线播放 | 精品国产1区2区3区 一区二区手机在线 | 欧美二区在线 | 精品国产一区二区三区免费 | 亚洲影视在线 | 日韩在线播放网址 | 色免费在线视频 | 国产99久久精品一区二区永久免费 | 91在线免费视频 | 国产黄色在线观看 | 久久毛片 | 成人在线小视频 | 日韩一二三区视频 | 欧美亚洲第一区 | 请别相信他免费喜剧电影在线观看 | 国产精品欧美大片 | 亚洲欧美国产精品久久 | 精品一区二区三区四区五区 | 九九精品在线 | 日韩av免费看 | 欧美成人手机在线 | 九一国产精品 | 国产精品久久久久久久久久久免费看 | 欧美精品一区二区三区在线四季 | 国产女人与拘做受视频 | 宅女噜噜66国产精品观看免费 | 国内精品久久影院 | 国产91精品久久久久久久网曝门 | 国产一区二区在线播放 | 国产在线精品一区 | www.日韩| 天天拍天天操 | 精彩视频一区二区三区 | 天天干天天爱天天爽 | 久久久91精品国产一区二区三区 | 久久久久网站 | 亚洲午夜精品视频 | 久久久久久91 | 免费在线黄色av |