淺談:Redis持久化機制(一)RDB篇


淺談:Redis持久化機制(一)RDB篇

​ 眾所周知,redis是一款性能極高,基於內存的鍵值對NoSql數據庫,官方顯示,它的讀效率可達到11萬次每秒,寫效率能達到8萬次每秒,因為它基於內存以及存讀效率高的特性,在市場上的應用中一般都把它作為緩存來使用,同時這也意味着它不能大量的無限制的填充數據,否則容易內存填滿,導致redis會向硬盤申請虛擬內存,造成內存和外存的不斷I/O,致使效率低下,甚至引起宕機,那么問題來了,既然只是當做緩存而不是為了永久存儲數據,redis為什么要做持久化呢?這樣做有什么意義呢?

1.為什么要做持久化

  • 第一點要明確,redis作為內存數據庫,宕機后就會發生數據消失,之所以要去做持久化只是為了能在重啟之后快速的恢復數據,而不是存儲數據;redis的持久化並不能夠保證數據的完整性.
  • 當然,如果要把redis當做DB用,DB數據要完整,所以需要一個完整的數據源(比如mysql),當啟動時將數據源的數據全部加載到redis里面,這只適用於數據量小的不易改變的,比如:字典庫。像mysql那樣大量的存儲數據是行不通的。

2.RDB(redis database)

​ 說完redis持久化的原因,我們再詳聊一下redis做持久化的第一種方式RDB,這種方式也是redis默認的一種持久化方式,默認是開啟的。

​ 從字面上來看,RDB也就是redis database,翻譯成中文就是redis 數據庫,也就是說這種持久化方式就是像數據庫一樣存儲了數據,當然事實上也是這樣的,RDB方式是通過存儲快照數據來完成的,既然是快照數據,那就是說明這種方式只關注了某一刻緩存的數據狀態,關注的是那一刻數據是什么,它並沒有去記錄這個數據變更的一系列過程。也就是說,RDB持久化方式關注的是數據存儲的結果,而非是數據存儲的過程。

​ 另外,既然是快照數據,redis又要保證性能,因此要明白RDB持久化時肯定不會是實時的,肯定是隔一段時間觸發一次,否則的話redis作為一個單線程處理的服務,光顧着去持久化數據了,怎么還有時間處理來自客戶端的請求訪問,這也就說明了由於有時間間隔,redis的RDB方式的持久化會丟失最后一次持久化后的數據,這也就表明了redis的持久化沒有辦法保證數據的完整性。

2.1 觸發快照的方式

  • 配置參數定期執行(在redis.conf中配置:save 多少秒內 數據變了多少)
save ""  # 不使用RDB存儲  不能主從
save 900 1  # 表示15分鍾(900秒鍾)內至少1個鍵被更改則進行快照。
save 300 10 # 表示5分鍾(300秒)內至少10個鍵被更改則進行快照。
save 60 10000 # 表示1分鍾內至少10000個鍵被更改則進行快照。
  • 命令顯式觸發(save或者bgsave命令)

    127.0.0.1:6379> bgsave
    Background saving started
    

2.2 RDB執行流程

1.redis父進程首先判斷,當前是否正在執行save,如果正在執行,則先返回。

2.父進程fork()復制出子進程,在這個過程中父進程是阻塞的,不再處理redis接收到的其他命令。當父進程fork結束,又可以重新處理工作。

3.子進程創建RDB文件,根據父進程的內存快照生成臨時快照文件,完成后對原有的文件進行替換。始終保持RDB文件的完整性。

4.子進程生成RDB文件完成后,就響應信息給父進程,父進程更新統計信息。

2.3 RDB文件結構

1、頭部5字節固定為“REDIS”字符串
2、4字節“RDB”版本號(不是Redis版本號),當前為9,填充后為0009
3、輔助字段,以key-value的形式

字段名 字段值 字段名 字段值
redis-ver 5.0.5 aof-preamble 是否開啟aof
redis-bits 64/32 repl-stream-db 主從復制
ctime 當前時間戳 repl-id 主從復制
used-mem 使用內存 repl-offset 主從復制

4、存儲數據庫號碼
5、字典大小6、過期key
7、主要數據,以key-value的形式存儲
8、結束標志
9、校驗和,就是看文件是否損壞,或者是否被修改。

2.4 RDB的優缺點

優點:

  • RDB是二進制壓縮文件,占用空間小,便於傳輸。(做主從復制時傳遞給slaver效率也很高)
  • 通過主進程fork復制子進程,由子進程完成持久化的方式,這樣可以最大化的保證redis的性能。但是前提條件是redis的數據量不能太大,否則fork的過程太長,容易造成阻塞。

缺點:

  • 不能保證數據的完整性,會丟失最后一次fork之后的數據。例如,redis進行持久化的操作是1分鍾一次,當上次持久化完成后的30秒內,新添加了5000個數據,那么redis發生宕機然后重新恢復時,那30秒的數據會丟失。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM