redis rdb aof區別_理解Redis的持久化機制:RDB和AOF

什么是Redis持久化?

Redis作為一個鍵值對內存數據庫(NoSQL),數據都存儲在內存當中,在處理客戶端請求時,所有操作都在內存當中進行,如下所示:

793586f52194949b58ed54e57284cc68.png

這樣做有什么問題呢?

注 意

文末有:3625頁互聯網大廠面試題

其實,只要稍微有點計算機基礎知識的人都知道,存儲在內存當中的數據,只要服務器關機(各種原因引起的),內存中的數據就會消失了

不僅服務器關機會造成數據消失,Redis服務器守護進程退出,內存中的數據也一樣會消失。

f520c541138230fd1f4d38818be2ee03.png

對于只把Redis當緩存來用的項目來說,數據消失或許問題不大,重新從數據源把數據加載進來就可以了

但如果直接把用戶提交的業務數據存儲在Redis當中,把Redis作為數據庫來使用,在其放存儲重要業務數據,那么Redis的內存數據丟失所造成的影響也許是毀滅性。

為了避免內存中數據丟失,Redis提供了對持久化的支持,我們可以選擇不同的方式將數據從內存中保存到硬盤當中,使數據可以持久化保存。

ad1f8581a0ee1c096214ae21df4560ce.png

Redis提供了RDB和AOF兩種不同的數據持久化方式,下面我們就來詳細介紹一下這種不同的持久化方式吧。


RDB

RDB是一種快照存儲持久化方式,具體就是將Redis某一時刻的內存數據保存到硬盤的文件當中,默認保存的文件名為dump.rdb,而在Redis服務器啟動時,會重新加載dump.rdb文件的數據到內存當中恢復數據。

開啟RDB持久化方式

開啟RDB持久化方式很簡單,客戶端可以通過向Redis服務器發送save或bgsave命令讓服務器生成rdb文件,或者通過服務器配置文件指定觸發RDB條件。

1. save命令

save命令是一個同步操作。

#?同步數據到磁盤上>?save?

a93609b50fad10bb8cfe1ed821c2fb1b.png

當客戶端向服務器發送save命令請求進行持久化時,服務器會阻塞save命令之后的其他客戶端的請求,直到數據同步完成。

如果數據量太大,同步數據會執行很久,而這期間Redis服務器也無法接收其他請求,所以,最好不要在生產環境使用save命令。

2. bgsave

與save命令不同,bgsave命令是一個異步操作。

#?異步保存數據集到磁盤上>?bgsave

e0b3a4e5801834bd46a5fd0b722bf5cc.png

當客戶端發服務發出bgsave命令時,Redis服務器主進程會forks一個子進程來數據同步問題,在將數據保存到rdb文件之后,子進程會退出。

所以,與save命令相比,Redis服務器在處理bgsave采用子線程進行IO寫入,而主進程仍然可以接收其他請求,但forks子進程是同步的,所以forks子進程時,一樣不能接收其他請求

這意味著,如果forks一個子進程花費的時間太久(一般是很快的),bgsave命令仍然有阻塞其他客戶的請求的情況發生。

3. 服務器配置自動觸發

除了通過客戶端發送命令外,還有一種方式,就是在Redis配置文件中的save指定到達觸發RDB持久化的條件,比如【多少秒內至少達到多少寫操作】就開啟RDB數據同步。

例如我們可以在配置文件redis.conf指定如下的選項:

#?900s內至少達到一條寫命令save?900?1#?300s內至少達至10條寫命令
save?300?10#?60s內至少達到10000條寫命令
save?60?10000

之后在啟動服務器時加載配置文件。

#?啟動服務器加載配置文件redis-server?redis.conf

這種通過服務器配置文件觸發RDB的方式,與bgsave命令類似,達到觸發條件時,會forks一個子進程進行數據同步

不過最好不要通過這方式來觸發RDB持久化,因為設置觸發的時間太短,則容易頻繁寫入rdb文件,影響服務器性能,時間設置太長則會造成數據丟失。

rdb文件

前面介紹了三種讓服務器生成rdb文件的方式,無論是由主進程生成還是子進程來生成,其過程如下:

  • 生成臨時rdb文件,并寫入數據。

  • 完成數據寫入,用臨時文代替代正式rdb文件。

  • 刪除原來的db文件。

RDB默認生成的文件名為dump.rdb,當然,我可以通過配置文件進行更加詳細配置,比如在單機下啟動多個redis服務器進程時,可以通過端口號配置不同的rdb名稱,如下所示:

#?是否壓縮rdb文件
rdbcompression?yes#?rdb文件的名稱
dbfilename?redis-6379.rdb#?rdb文件保存目錄
dir?~/redis/

RDB的幾個優點

  • 與AOF方式相比,通過rdb文件恢復數據比較快。

  • rdb文件非常緊湊,適合于數據備份。

  • 通過RDB進行數據備,由于使用子進程生成,所以對Redis服務器性能影響較小。

RDB的幾個缺點

  • 如果服務器宕機的話,采用RDB的方式會造成某個時段內數據的丟失,比如我們設置10分鐘同步一次或5分鐘達到1000次寫入就同步一次,那么如果還沒達到觸發條件服務器就死機了,那么這個時間段的數據會丟失。

  • 使用save命令會造成服務器阻塞,直接數據同步完成才能接收后續請求。

  • 使用bgsave命令在forks子進程時,如果數據量太大,forks的過程也會發生阻塞,另外,forks子進程會耗費內存。


AOF

聊完了RDB,來聊聊Redis的另外一個持久化方式:AOF(Append-only file)。

與RDB存儲某個時刻的快照不同,AOF持久化方式會記錄客戶端對服務器的每一次寫操作命令,并將這些寫操作以Redis協議追加保存到以后綴為aof文件末尾,在Redis服務器重啟時,會加載并運行aof文件的命令,以達到恢復數據的目的。

ac36339694d770d58bba8d77958151d4.png

開啟AOF持久化方式

Redis默認不開啟AOF持久化方式,我們可以在配置文件中開啟并進行更加詳細的配置,如下面的redis.conf文件:

#?開啟aof機制
appendonly?yes#?aof文件名
appendfilename?"appendonly.aof"#?寫入策略,always表示每個寫操作都保存到aof文件中,也可以是everysec或no
appendfsync?always#?默認不重寫aof文件no-appendfsync-on-rewrite?no#?保存目錄
dir?~/redis/

三種寫入策略

在上面的配置文件中,我們可以通過appendfsync選項指定寫入策略,有三個選項

appendfsync?always#?appendfsync?everysec#?appendfsync?no

1. always

客戶端的每一個寫操作都保存到aof文件當,這種策略很安全,但是每個寫請注都有IO操作,所以也很慢。

2. everysec

appendfsync的默認寫入策略,每秒寫入一次aof文件,因此,最多可能會丟失1s的數據。

3. no

Redis服務器不負責寫入aof,而是交由操作系統來處理什么時候寫入aof文件。更快,但也是最不安全的選擇,不推薦使用。

AOF文件重寫

AOF將客戶端的每一個寫操作都追加到aof文件末尾,比如對一個key多次執行incr命令,這時候,aof保存每一次命令到aof文件中,aof文件會變得非常大。

incr?num?1
incr?num?2
incr?num?3
incr?num?4
incr?num?5
incr?num?6
...
incr?num?100000

aof文件太大,加載aof文件恢復數據時,就會非常慢,為了解決這個問題,Redis支持aof文件重寫,通過重寫aof,可以生成一個恢復當前數據的最少命令集,比如上面的例子中那么多條命令,可以重寫為:

set?num?100000

aof文件是一個二進制文件,并不是像上面的例子一樣,直接保存每個命令,而使用Redis自己的格式,上面只是方便演示。

兩種重寫方式

通過在redis.conf配置文件中的選項no-appendfsync-on-rewrite可以設置是否開啟重寫,這種方式會在每次fsync時都重寫,影響服務器性以,因此默認值為no,不推薦使用。

#?默認不重寫aof文件no-appendfsync-on-rewrite?no

客戶端向服務器發送bgrewriteaof命令,也可以讓服務器進行AOF重寫。

#?讓服務器異步重寫追加aof文件命令
>?bgrewriteaof

AOF重寫方式也是異步操作,即如果要寫入aof文件,則Redis主進程會forks一個子進程來處理,如下所示:

7b02640fc1ec3a4eadbf7a974236b239.png

重寫aof文件的好處

  • 壓縮aof文件,減少磁盤占用量。

  • 將aof的命令壓縮為最小命令集,加快了數據恢復的速度。

AOF文件損壞

在寫入aof日志文件時,如果Redis服務器宕機,則aof日志文件文件會出格式錯誤,在重啟Redis服務器時,Redis服務器會拒絕載入這個aof文件,可以通過以下步驟修復aof并恢復數據。

1、備份現在aof文件,以防萬一。

2、使用redis-check-aof命令修復aof文件,該命令格式如下:

#?修復aof日志文件
$?redis-check-aof?-fix?file.aof

3、重啟Redis服務器,加載已經修復的aof文件,恢復數據。

AOF的優點

  • AOF只是追加日志文件,因此對服務器性能影響較小,速度比RDB要快,消耗的內存較少。

AOF的缺點

  • AOF方式生成的日志文件太大,即使通過AFO重寫,文件體積仍然很大。

  • 恢復數據的速度比RDB慢。


選擇RDB還是AOF呢?

通過上面的介紹,我們了解了RDB與AOF各自的優點與缺點,到底要如何選擇呢?

通過下面的表示,我們可以從幾個方面對比一下RDB與AOF,在應用時,要根本自己的實際需求選擇RDB或者AOF

如果想要數據足夠安全,可以兩種方式都開啟,但兩種持久化方式同時進行IO操作,會嚴重影響服務器性能,因此有時候不得不做出選擇。

0e3912229cc477099258ecaaa0ac07f1.png

當RDB與AOF兩種方式都開啟時,Redis會優先使用AOF日志來恢復數據,因為AOF保存的文件比RDB文件更完整。


小結

作者:張君鴻

來源:https://juejin.im/user/1697301685345773

上面講了一大堆Redis的持久化機制的知識,其實,如果你只是單純把Redis作為緩存服務器,那么可以完全不用考慮持久化

但是,在如今的大多數服務器架構中,Redis的單單只是扮演一個緩存服務器的角色,還可以作為數據庫,保存我們的業務數據,此時,我們則需要好好了解有關Redis持久化策略的區別與選擇。

閱讀原文:?最新?3625頁大廠面試題?

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

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

相關文章

python--批量下載豆瓣圖片

溜達豆瓣的時候,發現一些圖片,懶得一個一個扒,之前寫過c#和python版本的圖片下載,因此拿之前的Python代碼來改了改,折騰出一個豆瓣版本,方便各位使用 # -*- coding:utf8 -*- import urllib2, urllib, socke…

linux touch權限不夠,Linux下的Access、Modify、Change , touch的使用以及權限問題

每個文件在linux下面都會記錄許多的時間參數,其實是有三個主要的變動時間,那么,這三個時間的意義又是什么?下面我們來介紹:* Modify time(mtime)當該文件的“內容數據”更改時,就會更新這個時間。內容數據指…

scala 獲取數組中元素_從Scala中的元素列表中獲取隨機元素

scala 獲取數組中元素We can access a random element from a list in Scala using the random variable. To use the random variable, we need to import the Random class. 我們可以使用隨機變量從Scala中的列表訪問隨機元素。 要使用隨機變量,我們需要導入Rand…

ubuntu14.04下安裝cudnn5.1.3,opencv3.0,編譯caffe及配置matlab和python接口過程記錄

已有條件: ubuntu14.04cuda7.5anaconda2(即python2.7)matlabR2014a 上述已經裝好了,開始搭建caffe環境. 1. 裝cudnn5.1.3,參照:2015.08.17 Ubuntu 14.04cuda 7.5caffe安裝配置 詳情:先下載好cudnn-7.5-linux-x64-v5.1-rc.tgz安裝包(貌似需要官網申請) 解壓: tar -zxvf cudnn-7.…

python excel導入oracle數據庫_【Python代替Excel】12:Python操作oracle數據庫

日常工作中,如果有數據庫權限,那么在oracle中提取數據、在Python中處理是比較方便的。Python也提供了一個庫專門操縱數據庫。今天就專門來講講如何在Python中操作數據庫。準備工作需要工具:oracle、PL/SQL、Pythonimport cx_Oracle如果用anac…

Linux 金字塔 的shell命令,linux下保留文件系統下剩余指定數目文件的shell腳本

原文出處:http://www.jbxue.com/article/13808.html (原創文章,轉載請注明出處)本節內容:保留文件系統下剩余指定數目的文件例子:#!/bin/bash#-------------------------------#Description: Back up your files#site: www.jbxue.…

前端干貨之JS最佳實踐

持續更新地址 https://wdd.js.org/js-best-pr... 1. 風格 一千個讀者有一千個哈姆雷特,每個人都有自己的code style。我也曾為了要不要加分號給同事鬧個臉紅脖子粗,實際上有必要嗎? 其實JavaScript已經有了比較流行的幾個風格 JavaScript Sta…

python requests和urllib_Python——深入理解urllib、urllib2及requests(requests不建議使用?)...

深入理解urllib、urllib2及requestsPython 是一種面向對象、解釋型計算機程序設計語言,由Guido vanRossum于1989年底發明,第一個公開發行版發行于1991年,Python 源代碼同樣遵循 GPL(GNU General PublicLicense)協議[1] 。Python語法簡潔而清晰…

ssh查找linux端口,linux – 查找當前連接的端口號SSH

我正在使用SSH連接創建一個本地模擬器(未連接到Internet).我已經開始使用特定范圍的端口號進行sshd,并對一系列設備進行NAT處理.我必須找到當前連接的端口號.OS CentOS 5.5OpenSSH 6.1我做了以下事情.它適用于正常使用(手動用戶).但是當嘗試嚴格的測試(自動化)時,似乎有時找不到…

this.getstate_Java線程類Thread.State getState()方法(帶示例)

this.getstate線程類Thread.State getState() (Thread Class Thread.State getState()) This method is available in package java.lang.Thread.getState(). 軟件包java.lang.Thread.getState()中提供了此方法。 This method is used to return the state of this thread. 此方…

Java資源大全中文版(Awesome最新版)

來源:http://www.cnblogs.com/best/p/5876559.html 目錄 業務流程管理套件字節碼操作集群管理代碼分析編譯器生成工具構建工具外部配置工具約束滿足問題求解程序持續集成CSV解析數據庫數據結構時間日期工具庫依賴注入開發流程增強工具分布式應用分布式數據庫發布文檔…

運用多種設計模式的綜合案例_SpreadJS 純前端表格控件應用案例:表格數據管理平臺...

由某科技公司研發的表格數據管理平臺,是一款面向業務和企業管理系統定制開發的應用平臺,包括類 Excel 設計器、PC應用端和移動應用端等應用模塊。該平臺具備強大的業務配置和集成開發能力,對于企業客戶的信息系統在管理模式、業務流程、表單界…

linux定位哪個進程出發重啟,定位Linux下定位進程被誰KILL

hezhaoaqiang2012-11-09 11:10可以請教你一個問題嗎?關于arm的交叉編譯。我是按照:http://blog.chinaunix.net/uid-27003388-id-3276139.html 去做的,但是走到 四、建立初始編譯器(bootstrap gcc)下面的make install 它提示如下:m…

Java Integer類numberOfLeadingZeros()方法的示例

整數類numberOfLeadingZeros()方法 (Integer class numberOfLeadingZeros() method) numberOfLeadingZeros() method is available in java.lang package. 在java.lang包中提供了numberOfLeadingZeros()方法 。 numberOfLeadingZeros() method is used to returns the number o…

VS中C++ 項目重命名

應該都有過這樣的經歷,在Visual studio中創建解決方案,添加幾個項目進去,然后開始愉快的敲代碼...。寫代碼正歡的時候,卻總是感覺那里有些不舒服,一細看,這項目名稱取的真心挫,修改個吧。直接右…

Java GregorianCalendar getActualMinimum()方法與示例

GregorianCalendar類getActualMinimum()方法 (GregorianCalendar Class getActualMinimum() method) getActualMinimum() method is available in java.util package. getActualMinimum()方法在java.util包中可用。 getActualMinimum() method is used to get the actual minim…

axure9數據統計插件_WMDA:大數據技術棧的綜合實踐

一、概述WMDA是58自主開發的用戶行為分析產品,同時也是一款支持無埋點的數據采集產品,只需要在第一次使用的時候加載一段SDK代碼,即可采集全量、實時的PC、M、APP三端以及小程序的用戶行為數據。同時,為了滿足用戶個性化的數據采集…

Java Collections unmodifiableCollection()方法與示例

集合類unmodifiableCollection()方法 (Collections Class unmodifiableCollection() method) unmodifiableCollection() method is available in java.util package. unmodifiableCollection()方法在java.util包中可用。 unmodifiableCollection() method is used to get an un…

openfoam安裝中出現allmake error_如何更新OpenFOAM的版本?

這是協作翻譯的第四章,翻譯完感覺挺有意思的,分享給大家一起看看。4.更新OpenFOAM版本4.1 版本管理OpenFOAM以兩種不同的方式分發。一種方式是使用Git倉庫下載的倉庫版本。倉庫版本的版本號由附加的x標記,例如 OpenFOAM2.1.x。該版本會經常更…

java 根據類名示例化類_Java類類的requiredAssertionStatus()方法和示例

java 根據類名示例化類類的類requiredAssertionStatus()方法 (Class class desiredAssertionStatus() method) desiredAssertionStatus() method is available in java.lang package. requiredAssertionStatus()方法在java.lang包中可用。 desiredAssertionStatus() method is …