一篇解決Redis:持久化機制

目錄

認識持久化

持久化方案

RDB(Redis DataBase)

手動觸發

自動觸發

小結

AOF(Append-Only File)

AOF緩沖區刷新機制

AOF重寫機制

AOF重寫流程

?編輯

混合持久化


認識持久化

我們都知道Mysql有四大特征,原子性,持久性,隔離性,一致性。其中持久性就是因為mysql會把數據存到硬盤中,即使計算機掉電數據也不會丟失。如果把數據存儲到內存中,那么就是不持久的了。而我們的redis剛好就是這樣,所以要想讓redis持久化,就要想辦法把redis的數據存儲到硬盤上。

但是redis的一個很重要的特點就是效率高,而效率高又離不開將數據存儲到內存,所以該怎么辦呢?答案就是‘我全都要’,將數據同時存儲在內存和硬盤中,當重新打開機器后只需要從硬盤中把數據讀取到內存即可,這樣既保證了效率右讓redis可以持久化儲存數據,不過這樣的方法必然會付出更大的硬盤資源。?

持久化方案

redis提供的持久化方式主要有兩種RDB和AOF

RDB(定期備份):redis會定期將內存里的所有數據都寫入硬盤中,并生成一個快照。

AOF:redis會將每個寫操作記錄下來當重啟后會將這些操作自動再執行一遍

RDB(Redis DataBase)

?redis會定期將內存里的所有數據都寫入硬盤中,并生成一個快照。這個快照就類似于一張照片,將這一時刻的數據和狀態以文件的形式寫到硬盤上

這個定期又分為兩種方式手動觸發和自動觸發

手動觸發

程序員通過特定的命令來手動觸發快照

  • save:當redis執行save操作時,就會全力以赴的進行快照生成,也就會阻塞其他redis的客戶端命令,就可能會使redis直接阻塞(一般不建議使用)
  • bgsave(background save):這個操作的效果和save一樣,但是不會阻塞其他命令,因為此處redis采取了多進程的方式,會單獨生成一個子進程來完成快照生成的操作,而父進程則繼續處理客戶端的請求

bgsave的執行過程

  1. 首先判定當前是否還存在其他的子進程,如果已經在執行一個bgsave命令的話,這個bgsave就會直接返回,保證只有一個子進程
  2. 如果沒有其他子進程,就會通過fork操作創建出一個子進程來
  3. 子進程復制寫文件,生成快照的過程,而父進程則是繼續接受客戶端請求
  4. 最后zjc完成持久化后,會通知父進程,父進程更新一些統計信息后,子進程就可以銷毀了

//fork是linux提供的創建子進程的api,如果在其他系統上則行不通,fork會直接將父進程克隆一份,包括pcd,內存中的數據,文件描述符表等等,所以克隆出來的子進程就和父進程是完全一樣的,此時就可以讓父進程繼續處理客戶端請求,讓子進程去進行持久化操作,因為內存數據完全一樣,所以將子進程持久化就相當于持久化了父進程。而克隆完后的兩個進程是互相獨立,互不干擾的。

但是你會不會有疑問,完全拷貝下來如果有100G的內存那么開銷豈不是很大?實際上,redis這里并不是直接無腦的拷貝,而是利用’寫時拷貝‘,也就是如果子進程和父進程的內存數據完全一樣,那么這兩個進程共用一份內存,也就是不會觸發真正的拷貝操作,只是在效果上像是兩份,當有一方對內存數據進行了修改才會觸發真正的拷貝操作,比如當fork拷貝進程時父進程來了一條指令對數據進行了修改,那么就會將數據拷貝到子進程。

舉個例子假如父進程有一個int i = 1;那么子進程并不會拷貝而是和父進程共用這個數據的內存地址,如果在拷貝的過程中父進程發生了修改變成了int i = 2;那么fork就會觸發真正的拷貝,將原來的int i = 1復制到一個新的內存空間,而原來的則被修改為int i = 2。(一般整個持久化過程很快,父進程不會有很多數據發生改變)

這樣既不會有很大的開銷,也讓這兩個進程可以互相獨立。

當子進程寫入數據時會把數據寫入redis的工作目錄里的dump.rdb文件,這個文件是rdb機制生成的鏡像文件,而且只一個二進制的文件無法用一般的文本編輯器查看,當寫入完成后就會把新的rdb文件替換舊的rdb文件。如果是save則不會觸發文件替換而是直接在當前進程中往剛才的文件中寫入數據

具體過程是當執行rdb鏡像操作時,會把要生成的快照數據,先保存到一個臨時文件中,當快照整成完畢后,再刪除之前的rdb文件,把新生成的臨時的rdb文件名字改成剛才的dump.rdb文件

自動觸發

RDB會在Redi數據發生修改時自動保存快照進行持久化操作,不過生成一次rdb快照是一次成本比較大的操作,所以肯定不能每次修改都生成一次快照。redis是根據配置文件中的save選項來決定什么時候自動觸發持久化操作的,當達到選項中的條件后redis就會自動進行快照生成

解釋:

save選項有三個,分別是

  • 距離上次更新超過了900秒在這段時間內進行1次修改操作后進行自動觸發
  • 距離上次更新超過了300秒在這段時間內進行10次修改操作后進行自動觸發
  • 距離上次更新超過了60秒在這段時間內進行10000次修改操作后進行自動觸發

//如果給save設置成' ',就代表取消自動觸發

從選項中可以看到,最快的生成快照的時間是60秒,換句話說redis每兩次快照之間的最短時間是60秒,假如現在完成一次快照生成,此時快照和內存的數據是一樣的,但是redis突然進行了大量的修改,不過時間還沒到60秒,如果這時redis突然掛了或者機器掉電,那么在這段時間內的數據因為還沒來得及進行持久化操作就會直接丟失掉

//如果是通過正常流程重新啟動redis服務器,此時redis服務器會在退出的時候自動觸發生成rdb操作,但是如果是異常重啟(kill-9或者服務器掉電)此時服務器來不及生成rdb,內存中尚未保存到快照中的數據就會隨著重啟丟失

小結

  • RDB是一個緊湊的二進制文件,代表redis某一個時間點上的數據快照,非常適用于備份,全量復制等場景。比如固定時間執行bgsave,并把RDB文件復制到遠程機器或者文件中用于災難恢復
  • redis加載RDB文件的速度比AOF的方式快,因為RDB使用的是二進制的方式組織數據,可以直接把數據讀到內存中,按照字節的格式取出來,而AOF則是使用文本的方式。
  • RDB沒法做到實時持久化,因為redis每次都要執行fork創建子進程,開銷較大,也因此RDB可能會有數據丟失的風險,當數據來沒來得及持久化redis就掛掉或者掉電,這部分數據就會丟失

AOF(Append-Only File)

AOF是Redis的一種替代的、完全持久化的策略。AOF機制的作用是,每當redis客戶端執行寫操作時,都會被記錄再aof文件里通過特殊符號區分,如果發生服務器掛掉或者掉電后重啟,redis就可以通過將這些命令再執行一遍而達到恢復數據的效果。

AOF的啟動需要在配置文件里將appendonly.aof選項改成yes默認情況下是no,而且當啟動aof機制時rdb機制是關閉的

AOF緩沖區刷新機制

引入AOF之后,redis既要寫內存,又要寫硬盤會不會影響效率?

AOF并不會對效率有太大的影響,實際上AOF機制并不是直接將數據寫入硬盤,而是先寫入內存中的一個緩沖區,積累了一定量的數據后再一次性寫入硬盤,這樣做就大大降低了redis寫硬盤的次數(寫硬盤的次數要比一次寫多少數據對效率的影響大得多)。而且AOF是把每次的操作寫在文件的末尾是順序寫入,要比隨機寫入快得多。

雖然通過剛剛的方法大大提高了AOF的效率,但是同時也帶來了一個問題,緩沖區說到底還是在內存中,如果AOF正在將指令寫入緩沖區時,redis掛掉或者掉電,那么此時緩沖區中的數據還沒來得及寫入硬盤中,也就全部丟失掉了。雖然緩沖區的方法可以提高效率,但是相應的也會來帶來一些數據可靠性的問題,所謂魚和熊掌不可兼得。

Redis提供了多種AOF緩沖區刷新策略,由參數appedfsync控制,可配置項如下:

  • always:每寫入一個命令到緩沖區,就放入硬盤,刷新緩沖區的頻率最高,數據可靠性最高,性能最低
  • everysec(默認):每秒清理一次緩沖區,刷新緩沖區頻率低一些,數據可靠性也降低,性能相應的也提高了
  • no:redis不進行刷新緩沖區,由操作系統自行刷新,刷新頻率最低,數據可靠性最低,性能最高

AOF重寫機制

隨著我們的服務器一直運行,aof文件也會越來越大,雖然這個文件大小對aof效率沒有什么影響,但是會影響redis的開機速度,redis啟動就會讀取這個文件里記錄的指令操作如果文件較大,執行的操作就變多,啟動之間也就變長。雖然aof文件變大是不可避免的,但是這個文件里會有很多多余的內容。比如

如果redis客戶端執行指令,lpush key?aaa,lpush?key bbb,lpush?key ccc,就相當于只執行了lpush key aaa bbb ccc。再或者一些數據插入后又刪除,這樣的操作對于結果顯然是沒用的,而redis啟動時卻會執行一遍,也就拖長了啟動時間。所以實際上我們的aof不在乎中間過程,只在乎最終的數據結果

所以aof就針對上面問題做出了應對,也就是重寫機制,可以將aof中一些多余的操作指令給剔除掉,并且合并一些操作,從而縮小aof文件。

重寫機制的觸發方式也分為手動觸發和自動觸發

  • 手動觸發:調用bgrewriteaof命令redis就會對文件進行重寫
  • 自動觸發:根據auto-aof-rewrite-min-size和auto-aof-rewrite-percentage的參數決定觸發時機,auto-aof-rewrite-min-size表示觸發重寫時AOF的最小文件大小(默認是64mb)。auto-aof-rewrite-percentage代表AOF占用大小相比上次重寫時增加的比例。

AOF重寫流程

aof重寫的方法和rdb很像,也是先fork一個子進程,子進程負責AOF文件的重寫父進程依舊繼續負責處理redis客戶端的命令。但是我們重寫的時候并不關心當前aof文件里都有啥,而只在乎內存中的數據狀態,子進程只需要獲取當前內存中的數據,然后以aof的形式寫入一個新的aof文件,然后替換掉舊的文件即可。

這里的方法和RDB的快照也挺像,都是記錄當前時間點的內存狀態。只不過RDB是以二進制的形式,而AOF是以文本形式。

在fork創建子進程的一瞬間,子進程就繼承了父進程當前的內存狀態,但是重寫也要一定時間,可能在重寫的時候redis客戶端會對內存進行一些修改

換句話說,我們的子進程記錄的是fork之前的內存,但是fork之后的數據并不會丟失,父進程會再準備一個緩沖區aof_rewrite_buf當創建完子進程后,父進程就會將一些aof數據先存儲到這個緩沖區。

子進程完成重寫后會通知父進程,然后父進程再將aof_rewrite_buf中的數據寫入新的aof文件,最后再讓新的aof文件代替舊的aof文件

假如在redis正在重寫的時候,又來了一個重寫操作會怎么樣??

答案是,新的重寫操作會直接返回不執行,而且如果在要進行AOF操作時發現redis正在進行RDB快照操作,那么aof將會阻塞等待,等到RDB操作完成后再啟動AOF操作。

父進程在重寫的時候依然維護寫入舊的aof文件是否有必要?

?答案是,有必要因為假如redis在進行重寫操作時,這時redis服務器掛掉了的話,新的aof文件還沒有寫入完全,緩沖區里的數據也都丟失,如果舊的aof文件再被銷毀的話就會造成一部分數據的丟失。

混合持久化

雖然aof是以文本方式寫入,但是當我們查看aof文件時會發現這里是用二進制存儲,這是因為aof原本按照文本方式寫入文件但是這樣的成本較高,于是redis就引入混合持久化,也就是同時結合了rdb和aof。

按照aof的方式每個請求操作都寫入文件,觸發aof重寫后,就會把當前內存狀態按照rdb的二進制格式寫入到新的aof文件中,后續在進行的操作還是按照aof文本的方式追加到文件后面。

混合持久化在配置文件里默認開啟,當同時存在aof文件和rdb快照時,則以aof為主

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80997.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80997.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80997.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從 Vue3 回望 Vue2:事件總線的前世今生

從 Vue3 回望 Vue2:事件總線的前世今生 以 Vue3 開發者視角回顧 Vue2 中事件總線機制 的文章。文章將圍繞事件總線的緣起、用法、局限與演進展開,幫助 Vue3 開發者理解 Vue2 通信方式的歷史意義及現代替代方案。 一、前言:Vue3 時代&#xff…

CSS結構性偽類、UI偽類與動態偽類全解析:從文檔結構到交互狀態的精準選擇

一、結構性偽類選擇器:文檔樹中的位置導航器 結構性偽類選擇器是CSS中基于元素在HTML文檔樹中的層級關系、位置索引或結構特征進行匹配的一類選擇器。它們無需依賴具體的類名或ID,僅通過文檔結構即可精準定位元素,是實現響應式布局和復雜文檔…

【SSL證書系列】SSL證書工作原理解讀

SSL(Secure Sockets Layer)及其繼任者TLS(Transport Layer Security)是用于保護網絡通信安全的加密協議。SSL證書是實現HTTPS協議的核心,其工作原理涉及加密技術、身份驗證和信任機制。以下是其工作原理的詳細分步解析…

第二十四天打卡

import os os.getcwd() os.listdir() path_a r"C:\Users\renshuaicheng\Documents" path_b "MyProjectData" file "results.csv" file_path os.path.join(path_a,path_b,file) file_path import osstart_directory os.getcwd() # 假設這個目…

【CUDA】Sgemm單精度矩陣乘法(下)

目錄 前言1. 優化技巧5:使用register模擬二級緩存(內積轉外積)2. 優化技巧6:使用register模擬二級緩存 float43. 優化技巧7:global memory轉置再存放shared memory4. 優化技巧8:使用double buffer加速矩陣…

【1000以內具有12個以上因子的整數并輸出它的因子】2021-12-27

緣由c語言輸入1000以內具有12個以上因子的整數 并輸出它的因子-編程語言-CSDN問答 int 求因子個數(int 數, int* 因子 { 0 }) {//緣由https://bbs.csdn.net/topics/399168406int 和 0, 求 1, 商 0, 含 0;//因子不含1和數本身while (求 < (商 數 / 求))if (!(數 % 求)…

C#中的dynamic與var:看似相似卻迥然不同

在C#編程的世界里&#xff0c;var和dynamic這兩個關鍵字常常讓初學者感到困惑。它們看起來都在定義變量時省略了顯式類型聲明&#xff0c;但實際上它們的工作方式和應用場景有著天壤之別。今天&#xff0c;讓我們一起揭開這兩個關鍵字的神秘面紗。 var&#xff1a;編譯時的類型…

流速儀數據處理及流量斷面線繪制

1 需求描述 在實際航道測量項目中&#xff0c;有測量斷面線流量流速的需求&#xff0c;得使用流速儀在現場進行測量&#xff0c;相關操作在之前已經寫了記錄。本次手冊記錄后期數據處理與流量線繪制&#xff0c;以該區域為例。 流速儀設備操作說明 2 規范要求 3 流量斷面表格…

購物車構件示例

通用購物車構件設計 注:代碼僅用于演示原理,不可用于生產環境。 一、設計目標 設計一個高度可復用的購物車構件,具備以下特點: 與具體業務系統解耦支持多種應用場景(商城、積分系統等)提供標準化接口易于集成和擴展二、核心架構設計 1. 分層架構 ┌─────────…

數據結構·字典樹

字典樹trie 顧名思義&#xff0c;在一個字符串的集合里查詢某個字符串是否存在樹形結構。 樹存儲方式上用的是結構體數組&#xff0c;類似滿二叉樹的形式。 模板 定義結構體和trie 結構體必須的內容&#xff1a;當前結點的字符&#xff0c;孩子數組可選&#xff1a;end用于查…

ES面試題系列「一」

1、Elasticsearch 是什么&#xff1f;它與傳統數據庫有什么區別&#xff1f; 答案&#xff1a;Elasticsearch 是一個基于 Lucene 的分布式、開源的搜索和分析引擎&#xff0c;主要用于處理大量的文本數據&#xff0c;提供快速的搜索和分析功能。與傳統數據庫相比&#xff0c;E…

2025年6月一區SCI-不實野燕麥優化算法Animated Oat Optimization-附Matlab免費代碼

引言 近年來&#xff0c;在合理框架內求解優化問題的元啟發式算法的發展引起了全球科學界的極大關注。本期介紹一種新的元啟發式算法——不實野燕麥優化算法Animated Oat Optimization algorithm&#xff0c;AOO。該算法模擬了不實野燕麥的3種獨特行為&#xff0c;于2025年6月…

Agent Builder API - Agent Smith 擴展的后端服務(開源代碼)

?一、軟件介紹 文末提供程序和源碼下載 Agent Builder API - Agent Smith 擴展的后端服務&#xff08;開源代碼&#xff09;手動設置&#xff1a;在本地計算機中克隆此存儲庫并啟動 python FAST API 服務器。&#xff08;可選&#xff09;安裝并設置 Mongo DB。Dev Container…

C及C++的SOAP協議庫

一.gSOAP gSOAP 是一個功能強大的開源工具包&#xff0c;專為 C 和 C 設計&#xff0c;用于快速開發基于 SOAP 協議的 Web 服務和客戶端。 1.協議支持 SOAP 版本&#xff1a;完整支持 SOAP 1.1/1.2 規范&#xff0c;包括消息格式、編碼規則和錯誤處理。 傳輸協議&#xff1a…

html5+css3實現傅里葉變換的動態展示效果(僅供參考)

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>傅里葉變換的動態展示效果</title><sty…

ECharts中Map(地圖)樣式配置、漸變色生成

前言 在日常開發中&#xff0c;ECharts 幾乎成了我們繪制數據圖表的標配工具&#xff0c;功能強大到幾乎無所不能。不過每次用的時候都要翻官方文檔查配置項&#xff0c;確實有點小繁瑣 &#x1f605; 為了提升效率&#xff0c;也方便以后快速復用&#xff0c;這里就整理記錄…

內存分配器ptmalloc2、tcmalloc、jemalloc,結構設計、內存分配過程詳解

1. 引言 博主之前做過一個高并發內存池的項目實踐&#xff0c;在實踐中對于內存分配器的內存分配過程理解更加深刻了。在此期間&#xff0c;翻查了不少資料以及博客&#xff0c;發現源碼分享的博客不多&#xff0c;能生動完整的講述ptmalloc2、tcmalloc、jemalloc它們的結構設…

【擁抱AI】Deer-Flow字節跳動開源的多智能體深度研究框架

最近發現一款可以對標甚至可能超越GPT-Researcher的AI深度研究應用&#xff0c;Deer-Flow&#xff08;Deep Exploration and Efficient Research Flow&#xff09;作為字節跳動近期開源的重量級項目&#xff0c;正以其模塊化、靈活性和人機協同能力引發廣泛關注。該項目基于 La…

openfeign與dubbo調用下載excel實踐

一、前言 openfeign和dubbo均是rpc框架 RPC&#xff08;Remote Procedure Call&#xff0c;遠程過程調用&#xff09;框架 是一種允許程序像調用本地方法一樣調用遠程服務器上函數的技術。它隱藏了底層網絡通信的復雜性&#xff0c;讓開發者可以專注于業務邏輯&#xff0c;實現…

解密企業級大模型智能體Agentic AI 關鍵技術:MCP、A2A、Reasoning LLMs-強化學習算法

解密企業級大模型智能體Agentic AI 關鍵技術&#xff1a;MCP、A2A、Reasoning LLMs-強化學習算法 現在我們的核心問題是有一些同學會知道要才能強化學習。為什么才能強化學習&#xff1f;是實現AGI。例如從這個其實你從第一階段開始以后&#xff0c;就是chatbot&#xff0c;這…