主頁 > 資料庫 > Redis系列(三):Redis的持久化機制(RDB、AOF)

Redis系列(三):Redis的持久化機制(RDB、AOF)

2020-09-13 03:57:38 資料庫

本篇博客是Redis系列的第3篇,主要講解下Redis的2種持久化機制:RDB和AOF,

本系列的前2篇可以點擊以下鏈接查看:

Redis系列(一):Redis簡介及環境安裝,

Redis系列(二):Redis的5種資料結構及其常用命令

1. 為什么需要持久化?

因為Redis是記憶體資料庫,它將自己的資料存盤在記憶體里面,一旦Redis服務器行程退出或者運行Redis服務器的計算機停機,Redis服務器中的資料就會丟失,

為了避免資料丟失,所以Redis提供了持久化機制,將存盤在記憶體中的資料保存到磁盤中,用于在Redis服務器行程退出或者運行Redis服務器的計算機停機導致資料丟失時,快速的恢復之前Redis存盤在記憶體中的資料,

Redis提供了2種持久化方式,分別為:

  1. RDB持久化
  2. AOF持久化

接下來,我們一一詳解,

2. RDB持久化

RDB持久化是將某個時間點上Redis中的資料保存到一個RDB檔案中,如下所示:

基于RDB持久化的上述性質,所以RDB持久化也叫做快照持久化,

該檔案是一個經過壓縮的二進制檔案,通過該檔案可以還原生成RDB檔案時Redis中的資料,如下所示:

2.1 創建RDB檔案

Redis提供了2個命令來創建RDB檔案,一個是SAVE,另一個是BGSAVE,

SAVE命令會阻塞Redis服務器行程,直到RDB檔案創建完畢為止,在服務器行程阻塞期間,服務器不能處理任何命令請求,如下所示:

BGSAVE命令會派生出一個子行程,然后由子行程負責創建RDB檔案,服務器行程(父行程)繼續處理命令請求,如下所示:

以上描述也是這2個命令的區別,這里是重點,面試經常會問到

因為BGSAVE命令可以在不阻塞服務器行程的情況下執行,所以推薦使用BGSAVE命令,

我們可以手動執行該命令,如上面截圖所示,但還是推薦設定下Redis服務器組態檔的save選項,讓服務器每隔一段時間自動執行一次BGSAVE命令,

我們可以通過save選項設定多個保存條件,只要其中任意一個條件被滿足,服務器就會執行BGSAVE命令,

save選項設定的默認條件如下所示:

save 900 1

save 300 10

save 60 10000

默認的配置條件表示,只要滿足以下3個條件中的任意1個,BGSAVE命令就會被執行:

  • 服務器在900s(即15分鐘)之內,對資料庫進行了至少1次修改
  • 服務器在300s(即5分鐘)之內,對資料庫進行了至少10次修改
  • 服務器在60s(即1分鐘)之內,對資料庫進行了至少10000次修改

當滿足條件執行BGSAVE命令時,輸出日志如下圖所示:

生成的RDB檔案會根據Redis組態檔中的名稱和路徑來保存,相關的2個配置如下所示:

最終生成的RDB檔案如下所示(截圖為本機Windows環境,Linux環境下路徑會稍有不同):

2.2 載入RDB檔案

首先,我們要明確的是,載入RDB檔案的目的是為了在Redis服務器行程重新啟動之后還原之前存盤在Redis中的資料,

然后,Redis載入RDB檔案并沒有專門的命令,而是在Redis服務器啟動時自動執行的,

而且,Redis服務器啟動時是否會載入RDB檔案還取決于服務器是否啟用了AOF持久化功能,具體判斷邏輯為:

  1. 只有在AOF持久化功能處于關閉狀態時,服務器才會使用RDB檔案來還原資料,
  2. 如果服務器開啟了AOF持久化功能,那么服務器會優先使用AOF檔案來還原資料,

以上判斷邏輯如下圖所示:

默認情況下,Redis服務器的AOF持久化功能是關閉的,所以Redis服務器在啟動時會載入RDB檔案,

啟動日志如下所示:

2.3 服務器狀態

創建和載入RDB檔案,可能存在的服務器狀態有以下3種:

  1. 當執行SAVE命令時,Redis服務器會被阻塞,此時客戶端發送的所有命令請求都會被阻塞,只有在服務器執行完SAVE命令,重新開始接受命令請求之后,客戶端發送的命令請求才會被處理,
  2. 當執行BGSAVE命令時,Redis服務器不會被阻塞,Redis服務器仍然可以繼續處理客戶端發送的命令請求,
  3. 服務器在載入RDB檔案期間,會一直處于阻塞狀態,直到RDB檔案載入成功,

3. AOF持久化

AOF持久化是通過保存Redis服務器所執行的寫命令來記錄資料庫資料的,如下圖所示:

默認情況下,AOF持久化功能是關閉的,如果想要打開,可以修改下圖所示的配置:

舉個例子,假設Redis中還沒有存盤任何資料,我們執行了如下所示的命令:

然后我們會發現Redis服務器生成了1個名為appendonly.aof的檔案,打開該檔案,我們可以看到上面執行的3個寫命令都存盤在該檔案中:

3.1 AOF持久化的實作

當AOF持久化功能處于打開狀態時,Redis服務器在執行完一個寫命令之后,會以協議格式(如上面截圖中AOF檔案里保存寫命令的格式)將被執行的寫命令追加到服務器狀態的AOF緩沖區的末尾,然后Redis服務器會根據組態檔中appendfsync選項的值來決定何時將AOF緩沖區中的內容寫入和同步到AOF檔案里面,

appendfsync選項有以下3個值:

  1. always

    從安全性來說,always是最安全的(丟失資料最少),因為即使出現故障停機,資料庫也只會丟失一個事件回圈中所產生的命令資料,

    從效率來說,always的效率最慢,因為服務器在每個事件回圈都要將AOF緩沖區中的所有內容寫入到AOF檔案,并且同步AOF檔案,

  2. everysec

    從安全性來說,everysec模式下,即使出現故障停機,資料庫只會丟失一秒鐘的命令資料,

    從效率來說,everysec模式足夠快,因為服務器在每個事件回圈都要將AOF緩沖區中的所有內容寫入到AOF檔案,并且每隔一秒就要在子執行緒中對AOF檔案進行同步,

  3. no

    從安全性來說,no模式下,如果出現故障停機,資料庫會丟失上次同步AOF檔案之后的所有寫命令資料,具有不確定性,因為服務器在每個事件回圈都要將AOF緩沖區中的所有內容寫入到AOF檔案,至于何時對AOF檔案進行同步,則由作業系統控制,

    從效率來說,no模式和everysec模式的效率差不多,

appendfsync選項的默認值是everysec,也推薦使用這個值,因為既保證了效率又保證了安全性,

3.2 載入AOF檔案

因為AOF檔案包含了重建資料庫所需的所有寫命令,所以Redis服務器只要讀入并重新執行一遍AOF檔案里面保存的寫命令,就可以還原Redis服務器關閉之前的資料,

Redis讀取AOF檔案并還原資料庫的詳細步驟如下:

  1. 創建一個不帶網路連接的偽客戶端

    因為Redis的命令只能在客戶端背景關系中執行,而載入AOF檔案時所使用的命令直接來源于AOF檔案而不是網路連接,所以服務器使用了一個沒有網路連接的偽客戶端來執行AOF檔案保存的寫命令,

    偽客戶端執行命令的效果和帶網路連接的客戶端執行命令的效果完全一樣,

  2. 從AOF檔案中分析并讀取出一條寫命令,

  3. 使用偽客戶端執行被讀取出的寫命令,

  4. 一直執行步驟2和步驟3,直到AOF檔案中的所有寫命令都被執行完畢,

以上步驟如下圖所示:

如果Redis服務器開啟了AOF持久化功能,那么Redis服務器在啟動時會載入AOF檔案,

啟動日志如下所示:

3.3 AOF重寫

因為AOF持久化是通過保存被執行的寫命令來記錄資料庫資料的,所以隨著Redis服務器運行時間的增加,AOF檔案中的內容會越來越多,檔案的體積會越來越大,如果不做控制,會有以下2點壞處:

  1. 過多的占用服務器磁盤空間,可能會對Redis服務器甚至整個宿主計算機造成影響,
  2. AOF檔案的體積越大,使用AOF檔案來進行資料庫還原所需的時間就越多,

舉個例子,在客戶端執行如下命令:

為了記錄這個list鍵的狀態,AOF檔案就需要保存上面執行的6條命令,

為了解決AO檔案體積越來越大的問題,Redis提供了AOF檔案重寫功能,即Redis服務器會創建一個新的AOF檔案來替代現有的AOF檔案,新舊兩個AOF檔案所保存的資料庫資料相同,但新AOF檔案不會包含任何浪費空間的冗余命令,所以新AOF檔案的體積通常會比舊AOF檔案的體積要小很多,

3.3.1 AOF重寫的實作原理

AOF檔案重寫并不需要對現有的AOF檔案進行任何讀取、分析或者寫入操作,而是通過讀取服務器當前的資料庫資料來實作的,

仍然以上面的list鍵為例,舊的AOF檔案保存了6條命令來記錄list鍵的狀態,但list鍵的結果是“C” "D" "E" "F" "G"這樣的資料,所以AOF檔案重寫時,可以用一條RPUSH list “C” "D" "E" "F" "G"命令來代替之前的六條命令,這樣就可以將保存list鍵所需的命令從六條減少為一條了,

按照上面的原理,如果Redis服務器存盤的鍵值對足夠多,AOF檔案重寫生成的新AOF檔案就會減少很多很多的冗余命令,進而大大減小了AOF檔案的體積,

綜上所述,AOF檔案重寫功能的實作原理為:

首先從資料庫中讀取鍵現在的值,然后用一條命令去記錄鍵值對,代替之前記錄這個鍵值對的多條命令,

3.3.2 AOF后臺重寫

因為AOF檔案重寫會進行大量的檔案寫入操作,所以執行這個操作的執行緒將被長時間阻塞,

因為Redis服務器使用單個執行緒來處理命令請求,所以如果由服務器行程直接執行這個操作,那么在重寫AOF檔案期間,服務器將無法處理客戶端發送過來的命令請求,

為了避免上述問題,Redis將AOF檔案重寫功能放到子行程里執行,這樣做有以下2個好處:

  1. 子行程進行AOF檔案重寫期間,服務器行程(父行程)可以繼續處理命令請求,
  2. 子行程帶有服務器行程的資料副本,使用子行程而不是執行緒,可以在避免使用鎖的情況下,保證資料的安全性,

AOF后臺重寫的步驟如下所示:

  1. 服務器行程創建子行程,子行程開始AOF檔案重寫

  2. 從創建子行程開始,服務器行程執行的所有寫命令不僅要寫入AOF緩沖區,還要寫入AOF重寫緩沖區

    寫入AOF緩沖區的目的是為了同步到原有的AOF檔案,

    寫入AOF重寫緩沖區的目的是因為子行程在進行AOF檔案重寫期間,服務器行程還在繼續處理命令請求,

    而新的命令可能會對現有的資料庫進行修改,從而使得服務器當前的資料庫資料和重寫后的AOF檔案所

    保存的資料庫資料不一致,

  3. 子行程完成AOF重寫作業,向父行程發送一個信號,父行程在接收到該信號后,會執行以下操作:

    1.將AOF重寫緩沖區中的所有內容寫入到新AOF檔案中,這樣就保證了新AOF檔案所保存的資料庫資料和服務器當前的資料庫資料是一致的,

    2.對新的AOF檔案進行改名,原子地覆寫現有的AOF檔案,完成新舊兩個AOF檔案的替換,

Redis提供了BGREWRITEAOF命令來執行以上步驟,如下圖所示:

執行完成后,打開appendonly.aof檔案,發現保存list鍵的命令從六條變為了一條:

除了手動執行BGREWRITEAOF命令外,Redis還提供了2個配置項用來自動執行BGREWRITEAOF命令:

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

該配置表示,當AOF檔案的體積大于64MB,并且AOF檔案的體積比上一次重寫之后的體積大了至少一倍(100%),Redis將自動執行BGREWRITEAOF命令,

4. RDB持久化、AOF持久化的區別

通過上面的講解,我們會發現Redis提供的2種持久化方法是有區別的,可以總結為以下4點:

  1. 實作方式
  2. 檔案體積
  3. 安全性
  4. 優先級

接下來一一講解,

4.1 實作方式

RDB持久化是通過將某個時間點Redis服務器存盤的資料保存到RDB檔案中來實作持久化的,

AOF持久化是通過將Redis服務器執行的所有寫命令保存到AOF檔案中來實作持久化的,

4.2 檔案體積

由上述實作方式可知,RDB持久化記錄的是結果,AOF持久化記錄的是程序,所以AOF持久化生成的AOF檔案會有體積越來越大的問題,Redis提供了AOF重寫功能來減小AOF檔案體積,

4.3 安全性

AOF持久化的安全性要比RDB持久化的安全性高,即如果發生機器故障,AOF持久化要比RDB持久化丟失的資料要少,

因為RDB持久化會丟失上次RDB持久化后寫入的資料,而AOF持久化最多丟失1s之內寫入的資料(使用默認everysec配置的話),

4.4 優先級

由于上述的安全性問題,如果Redis服務器開啟了AOF持久化功能,Redis服務器在啟動時會使用AOF檔案來還原資料,如果Redis服務器沒有開啟AOF持久化功能,Redis服務器在啟動時會使用RDB檔案來還原資料,所以AOF檔案的優先級比RDB檔案的優先級高,

5. 原始碼及參考

Josiah L. Carlson 《Reids實戰》

黃健宏 《Redis設計與實作》

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/19772.html

標籤:NoSQL

上一篇:[MongoDB]mongodb的命令列操作

下一篇:Java 操作Redis

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more