日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis专题-持久化方式

發(fā)布時間:2025/3/20 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis专题-持久化方式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

很多時候我們?yōu)榱司徑鈹?shù)據(jù)庫的壓力,都會使用緩存來作為數(shù)據(jù)的存儲方式,最常用的就是使用redis。將熱點數(shù)據(jù)緩存在redis中可以有效緩解數(shù)據(jù)庫的壓力。但是如果redis掛了那些重要的數(shù)據(jù)怎么辦?redis為我們提供了持久化的機制,它可以保證數(shù)據(jù)不會丟失。接下來我們就來聊聊redis的這一特性。
redis為我們提供了兩種方式的持久化策略:RDB(Redis DataBase)和AOF(Append Only File)。

1.RDB(Redis DataBase)

RDB持久化是將當(dāng)前進程中的數(shù)據(jù)生成快照保存到磁盤(快照持久化),保存的文件后綴為rdb,當(dāng)redis重啟時,可以讀取快照文件恢復(fù)數(shù)據(jù)。

1.1啟用方式

通過在配置文件redis.conf中進行參數(shù)的配置可以開啟或者關(guān)閉是否啟用RDB持久化:

save 900 1 save 300 10 save 60 10000

如果將這些注釋掉則可以關(guān)閉RDB持久化。上面每一條的含義如下:

Redis 服務(wù)器在 900 秒之內(nèi),對數(shù)據(jù)庫進行了至少一次修改 Redis 服務(wù)器在 300 秒之內(nèi),對數(shù)據(jù)庫進行了至少 10 次修改 Redis 服務(wù)器在 60 秒之內(nèi),對數(shù)據(jù)庫進行了至少 10000 次修改

這種配置的方式為save m n,表示當(dāng)m秒內(nèi)發(fā)生n次變化時,會觸發(fā)bgsave,屬于自動觸發(fā)啟動RDB持久化,我們還可以使用命令save/bgsave來進行手動出發(fā)RDB持久化。save和bgsave雖然都可以觸發(fā)RDB持久化,但是具有不同的特性,這里簡單做一下對比:

指令savebgsave
IO類型同步異步
復(fù)雜度O(n)O(n)
內(nèi)存消耗不會消耗額外內(nèi)存消耗內(nèi)存,需要fork子進程
是否阻塞阻塞redis服務(wù)器的進程,直到RDB文件創(chuàng)建完,在該期間,redis不能處理任何的命令請求生成RDB文件時,會派生出一個子進程,只有fork子進程期間是阻塞的,子進程負責(zé)創(chuàng)建RDB文件,在此期間,主進程和子進程是同時存在的,不會阻塞redis服務(wù)器進程

1.2存儲路徑

打開配置文件redis.conf,則可以看到以下兩個參數(shù):

1.3RDB文件

1.3.1RDB文件格式

Redis的RDB文件是二進制格式的文件,可以用cat命令看一下RDB文件的內(nèi)容:

這里顯示的是一個包含亂碼的文件,因為文件是以二進制的格式保存,要想看到正常的信息,可以通過linux的od命令查看,od命令用于輸出文件的八進制、十六進制或其他格式編碼的字節(jié),通常用于輸出文件中不能直接顯示在終端的字符,注意輸出的是字節(jié),分隔符之間的字符都是保存在一個字節(jié)的。這里就不做演示了,大家想看可以自行進行操作。

1.3.2RDB文件結(jié)構(gòu)

如下圖所示,這里是RDB文件的一個大致結(jié)構(gòu)圖:

為了更好的理解,這里對各個參數(shù)做一下解釋:

REDIS:常量,保存著“REDIS”5個字符,判斷當(dāng)前的文件是否為“RDB文件“,這樣才方便用常量的時間來判別; db_version:RDB文件的版本號,注意不是Redis的版本號; database:表示一個完整的數(shù)據(jù)庫,比如 SELECTDB 3 pairs表示完整的3號數(shù)據(jù)庫; EOF:常量,標(biāo)志RDB文件正文內(nèi)容結(jié)束; check_sum:前面所有內(nèi)容的校驗和;Redis在載入RBD文件時,會計算前面的校驗和并與check_sum值比較,判斷文 件是否損壞。

注意:只有當(dāng)數(shù)據(jù)庫中有鍵值對時,RDB文件中才會有該數(shù)據(jù)庫的信息,如果Redis中所有的數(shù)據(jù)庫都沒有鍵值對,則這一部分直接省略。

1.3.3RDB文件存儲過程

RDB持久化觸發(fā)的方式包括手動和自動,因為save指令會阻塞服務(wù)進程,所以通常不會使用,自動觸發(fā)雖然指令是save m n,但是最后也是調(diào)用的bgsave,了解了bgsave的原理也就了解了RDB文件存儲的過程,以下是bgsave的執(zhí)行流程圖:

文字描述過程如下:

  • 父進程首先判斷當(dāng)前是否在執(zhí)行save,或bgsave/bgrewriteaof的子進程,如果在執(zhí)行則bgsave命令直接返回;
  • 如果沒有執(zhí)行的子進程,父進程執(zhí)行fork操作創(chuàng)建子進程,這個過程中父進程是阻塞的,Redis不能執(zhí)行來自客戶端的任何命令;
  • 父進程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父進程,并可以響應(yīng)其他命令;
  • 子進程創(chuàng)建RDB文件,根據(jù)父進程內(nèi)存快照生成臨時快照文件,完成后對原有文件進行原子替換;
  • 子進程發(fā)送信號給父進程表示完成,父進程更新統(tǒng)計信息。
  • 第二步中bgsave/bgrewriteaof 的子進程不能同時執(zhí)行,主要是基于性能方面的考慮:兩個并發(fā)的子進程同時執(zhí)行大量的磁盤寫操作,可能引起嚴重的性能問題。

    1.4 常用配置

    這里給大家介紹幾個RDB常用的配置,這些都可以再redis.conf配置文件中進行配置:

    //bgsave自動觸發(fā)的條件,沒有save m n配置,相當(dāng)于自動的RDB持久化關(guān)閉,仍可以通過其他方式觸發(fā) save m n //bgsave出現(xiàn)錯誤時,Redis是否停止執(zhí)行寫命令,設(shè)置為yes,則當(dāng)硬盤出現(xiàn)問題時,可以及時發(fā)現(xiàn),避免數(shù)據(jù)的大量丟失 stop-writes-on-bgsave-error yes //是否開啟RDB文件壓縮 rdbcompression yes //是否開啟RDB文件的校驗,在寫入文件和讀取文件時都起作用; rdbchecksum yes //RDB文件名 dbfilename dump.rdb //RDB文件和AOF文件所在目錄 dir ./

    2.AOF(Append Only File)

    RDB持久化是將進程數(shù)據(jù)寫入文件,而AOF持久化(即Append Only File持久化),則是將Redis執(zhí)行的每次寫命令記錄到單獨的日志文件中(有點像MySQL的binlog),與RDB相比,AOF的實時性更好,因此已成為主流的持久化方案。

    2.1啟用方式

    Redis服務(wù)器默認開啟RDB,關(guān)閉AOF;要開啟AOF,只需要在配置文件中配置:

    //開啟AOF appenonly yes

    2.2存儲路徑

    //存儲路徑 dir ./ //存儲文件名,自己定義 appendfilename "appendonly.aof"

    2.3AOF文件存儲

    2.3.1 執(zhí)行流程

    AOF的執(zhí)行流程圖大致如下:

    2.3.1.1 命令追加(append)

    AOF命令追加的內(nèi)容直接是文本協(xié)議格式,那么什么會采用文本協(xié)議格式呢?原因如下:

  • 文本協(xié)議具有很好的兼容性;
  • 開啟AOF后,所有寫入命令都包含追加操作,直接采用協(xié)議格式,避免了二次處理開銷;
  • 文本協(xié)議具有可讀性,方便直接修改和處理。
  • 從流程圖可以看到,追加的內(nèi)容會追加到aof緩沖區(qū)而不是直接寫入aof文件,這樣做的目的是什么呢?

  • 實時寫入磁盤會帶來非常高的磁盤IO,影響整體的性能;
  • Redis使用單線程響應(yīng)命令,如果每次寫AOF文件命令都直接追加到硬盤,那么性能完全取決于當(dāng)前硬盤負載;
  • Reids可以提供多種緩沖區(qū)同步硬盤的策略,在性能和安全性方面做出平衡。
  • 2.3.1.2 文件同步(sync)

    在命令追加中提到 Reids可以提供多種緩沖區(qū)同步硬盤的策略,其主要由appendfsync控制,redis提供了三種方式,不同的值具有的特點如下:

    枚舉值說明
    always命令寫入aof_buf后立即調(diào)用系統(tǒng)fsync操作同步到AOF文件,fsync完成后線程返回;每次有寫命令都要同步到AOF文件,硬盤IO成為性能瓶頸,Redis只能支持大約幾百TPS寫入,嚴重降低了Redis的性能;即便是使用固態(tài)硬盤(SSD),每秒大約也只能處理幾萬個命令,而且會大大降低SSD的壽命。
    everysec命令寫入aof_buf后調(diào)用系統(tǒng)write操作,write完成后線程返回。fsync同步文件操作由專門線程每秒調(diào)用一次
    no命令寫入aof_buf后調(diào)用系統(tǒng)write操作,不對AOF文件做fsync同步,同步硬盤操作由操作系統(tǒng)負責(zé),通常同步周期最長30秒。

    2.3.1.3 文件重寫(rewrite)

    隨著時間流逝,Redis服務(wù)器執(zhí)行的寫命令越來越多,AOF文件也會越來越大;過大的AOF文件不僅會影響服務(wù)器的正常運行,也會導(dǎo)致數(shù)據(jù)恢復(fù)需要的時間過長,所以需要對文件進行重寫。通過多aof文件重寫,減小AOF文件的體積,減少文件占用的空間,加快恢復(fù)速度。需要注意的是AOF重寫是把Redis進程內(nèi)的數(shù)據(jù)轉(zhuǎn)化為寫命令,同步到新的AOF文件,不會對舊的AOF文件進行任何讀取、寫入操作。文件重寫主要做了以下幾個優(yōu)化:

  • 進程內(nèi)已經(jīng)超時(過期)的數(shù)據(jù)不再寫入文件;
  • 無效的命令不再寫入文件,如有些數(shù)據(jù)被重復(fù)設(shè)值(set mykey v1, set mykey v2)、有些數(shù)據(jù)被刪除了(sadd myset v1, del myset)等等;
  • 多條寫命令可以合并為一個,如:lpush list a、lpush list b、lpush list c可以轉(zhuǎn)化為:lpush list a b c。不過為了防止單條命令過大造成客戶端緩沖區(qū)溢出,對于list、set、hash、zset類型的key,并不一定只使用一條命令,以64個元素為界拆分為多條。
  • AOF重寫過程依然可以分為手動觸發(fā)和自動觸發(fā)。手動觸發(fā)直接調(diào)用bgrewriteaof命令就可以,自動觸發(fā)根據(jù)auto-aof-rewrite-min-size和auto-aof-rewrite-percentage參數(shù)確定自動觸發(fā)時機:

    auto-aof-rewrite-min-size:表示運行AOF重寫時文件最小體積,默認為64MB; auto-aof-rewrite-percentage:代表當(dāng)前AOF文件空間(aof_current_size)和上一次重寫后AOF文件空間(aof_base_size)的比值。自動觸發(fā)時機 = aof_current_size > auto-aof-rewrite-min-size && (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewrite=percentage

    以下是文件重寫的流程圖:

    接下來描述一下執(zhí)行過程:

  • Redis父進程首先判斷當(dāng)前是否存在正在執(zhí)行 bgsave/bgrewriteaof的子進程,如果存在則bgrewriteaof命令直接返回;
  • 父進程執(zhí)行fork操作創(chuàng)建子進程,這個過程中父進程是阻塞的;
  • 父進程fork后,父進程不再阻塞,并可以響應(yīng)其他命令。Redis的所有寫命令依然寫入AOF緩沖區(qū),由于fork操作使用寫時復(fù)制技術(shù),子進程只能共享fork操作時的內(nèi)存數(shù)據(jù),因此Redis使用AOF重寫緩沖區(qū)(圖中的aof_rewrite_buf)保存這段時間的數(shù)據(jù),防止新AOF文件生成期間丟失這部分數(shù)據(jù)。也就是說,bgrewriteaof執(zhí)行期間,Redis的寫命令同時追加到aof_buf和aof_rewirte_buf兩個緩沖區(qū)。然后根據(jù)appendfsync策略同步到硬盤,保證原有AOF機制的正確;
  • 子進程根據(jù)內(nèi)存快照,按照命令合并規(guī)則寫入到新的AOF文件,寫完新的AOF文件后,向父進程發(fā)信號,父進程更新統(tǒng)計信息;
  • 父進程把AOF重寫緩沖區(qū)的數(shù)據(jù)寫入到新的AOF文件,通過rename完成文件的替換工作,即使用新的AOF文件替換老文件,完成AOF重寫。
  • 2.3.1.4 重啟加載(load)

    關(guān)于redis重啟加載的時候,在這里說明一下假如RDB和AOF都開啟的時候,優(yōu)先加載的是AOF,因為AOF保存的數(shù)據(jù)更加完整,最多只會損失1s的數(shù)據(jù)。我們來看一下redis的源碼:

    因為redis的源碼是用c語言寫的,為了提高可讀性,我加了部分中文注釋。通過源碼的解讀我大致畫出了對應(yīng)的流程圖如下:

    2.4 常用配置

    //是否開啟AOF appendonly no //AOF文件名 appendfilename "appendonly.aof" //RDB文件和AOF文件所在目錄 dir ./ //fsync持久化策略 appendfsync everysec //AOF重寫期間是否禁止fsync no-appendfsync-on-rewrite no //文件重寫觸發(fā)條件之一 auto-aof-rewrite-percentage 100 //文件重寫觸發(fā)條件之一 auto-aof-rewrite-min-size 64mb //如果AOF文件結(jié)尾損壞,Redis啟動時是否仍載入AOF文件 aof-load-truncated yes

    3.RDB與AOF比較

    優(yōu)點缺點
    AOF支持秒級持久化,兼容性好文件大,恢復(fù)速度慢,對性能影響大,官方文檔也指出,在某些情況下,AOF的確也存在一些bug,比如使用阻塞命令時
    RDBRDB文件緊湊,體積小,網(wǎng)絡(luò)傳輸快,適合全量復(fù)制;恢復(fù)速度比AOF快很多;對性能的影響相對較小做不到實時持久化;RDB文件需要滿足特定格式,兼容性差,如老版本的Redis不兼容新版本的RDB文件

    4.性能與實踐

    通過以上的分析可以知道不管是AOF還是RDB都是需要fork出子進程進行操作,這是一個重量級的操作,會對redis造成阻塞,所以為了不影響redis的性能,我們應(yīng)該盡可能的降低阻塞,主要有以下策略可以采用:

    • 降低fork頻率,比如關(guān)閉自動,改成手動來進行RDB的快照生成和AOF的重寫;
    • 控制redis最大使用內(nèi)存,防止fork耗時過長;
    • 采用更高級的硬件設(shè)備;
    • 合理配置Linux的內(nèi)存分配策略,避免因物理內(nèi)存不足導(dǎo)致fork失敗。

    以上描述的可能太抽象,在實際生產(chǎn)中我們應(yīng)該怎么呢?在這里提供一點自己的實踐經(jīng)驗:

    • 如果Redis中的數(shù)據(jù)完全丟棄也沒有關(guān)系(如Redis完全用作DB層數(shù)據(jù)的cache),那么無論是單機,還是主從架構(gòu),都可以不進行任何持久化;
    • 單機如果出現(xiàn)多個實例,要防止多個及其同時運行持久化和重寫操作,避免出現(xiàn)內(nèi)存,CPU,IO資源競爭,讓持久化變?yōu)榇?#xff1b;
    • 在單機環(huán)境下(對于個人開發(fā)者,這種情況可能比較常見),如果可以接受十幾分鐘或更多的數(shù)據(jù)丟失,選擇RDB對Redis的性能更加有利;如果只能接受秒級別的數(shù)據(jù)丟失,應(yīng)該選擇AOF;
    • 在多數(shù)情況下,我們都會配置主從環(huán)境,slave的存在既可以實現(xiàn)數(shù)據(jù)的熱備,也可以進行讀寫分離分擔(dān)Redis讀請求,以及在master宕掉后繼續(xù)提供服務(wù)。在這種情況下的可行做法是master完全關(guān)閉持久化(包括RDB和AOF),這樣可以讓master的性能達到最好。
    • RDB和AOF可以同時存在,配合使用提高效率。

    猜你感興趣
    Redis專題-集群模式
    Redis專題-持久化方式
    Redis專題-底層數(shù)據(jù)結(jié)構(gòu)與使用場景
    Redis專題-緩存穿透、緩存雪崩、緩存擊穿

    更多文章請點擊:更多…

    總結(jié)

    以上是生活随笔為你收集整理的Redis专题-持久化方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。