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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis持久化-深入理解AOF,RDB

發布時間:2023/12/4 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis持久化-深入理解AOF,RDB 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

持久化

  • Redis數據全部在內存中,如果宕機,數據必然丟失,因此必須有一種機制保證Redis數據不會因為故障丟失,這就是Redis的持久化機制
  • 持久化方式兩種:AOF,RDB,如下圖
    • RDB快照模式是一次全量備份,是內存數據的二進制序列化形式,存儲緊湊
    • AOF日志方式是連續增量的備份。是內存數據修改指令的記錄文本。AOF日志長期運行下來會異常龐大,Redis重啟后加載AOF日志會很慢需要定期重寫AOF日志。
RDB快照原理
  • Redis單線程,需要同時負責N個客戶端套接字讀寫,內存數據結構邏輯讀寫,定時任務處理(上一節中說明),現在還需要內存快照,而且RDB是必須進行IO操作,此處IO操作是不能用底層select的多路復用。
  • 以上如果都是單線程完成那么肯會有兩個問題:
    • 第一RDB的IO操作的時候回嚴重拖慢服務器性能。因為需要一邊IO操作,一邊響應客戶端socket
    • 第二IO持久化同時,內存還在修改,比如大型hash結構,持久化一半修改了怎么處理?
  • Redis使用操作系統的多進程COW(Copy on write) 機制來實現快照持久化。
fork多進程
  • Redis在持久化時候會調用glibc函數,fork產生一個子進程,持久化是由子進程完成,父進程處理客戶端請求。
  • 子進程產生和父進程共享內存中代碼段與數據段,這是linux操作系統機制,為節約內存,可以盡可能讓他們共享,分離瞬間內存增長幾乎不變。
  • 用如下偽代碼來說明fork過程,fork時候在父進程中返回子進程pid,子進程返回0,資源不足返回error。
pid = os.fock() if pid > 0:handle_client_requests(); //父進程處理客戶端 if pid == 0:handle_snapshot_write(); //子進程處理快照 if pid < 0:error;
子進程持久化流程
  • fork的模式解決了上文中第一個問題IO高效性問題,那么第二個問題如何解決

  • 子進程在做數據RDB時候,不會修改現有內存結構,只對據結構進行遍歷讀取。父進程必須響應客戶端,修改內存數據。

  • 這個時候才是使用操作系統的copy on write 機制的時候,在fork之后,子進程就認為當前的內存中所有數據都算做此次需要RDB到磁盤的快照,而一旦父進程在此期間需要修改某個數據段,會將共享的當前數據段分離出來,單做現在最新的內存數據,而老的數據當老版本的數據。這時候子進程的相應的數據段頁面是不會變化的,還是fork瞬間的那個版本。如下示意圖。

  • 如上圖示意,隨著父進程的修改操作越多,只會COW出更多數據頁而已,占用部分內存,但是也不可能超過原內存2倍(不可能所有頁都在修改)。另外Redis冷數據占比更大,所以Redis實例中被COW的數據頁只有一小部分而已。每個頁大小4KB,一個Redis實例一般有成千上萬個頁面。

  • 子進程沒有因為數據變化影響,他們看到內存中數據就是fork產生的瞬間的那個內存中的所有數據,我們將這瞬間的數據看成是一個SNASHOP,所以RDB也叫快照的原因。

AOF原理

  • AOF日志存儲的是Redis服務器的順序指令執行序列,AOF日志只記錄內存進行修改的指令記錄
  • 例如有一份AOF日志記錄了Redis實例從創建以來的所有修改性指令,那么就可以通過對一個空Redis實例順序執行所有指令的方式來復刻當前Redis的狀態。
  • Redis收到客戶端指令,先進行校驗,邏輯處理,沒有問題,在存儲AOF日志。先執行在存盤。
  • 缺點,AOF日志隨著Redis不斷運行逐漸變大,加入宕機,加載AOF文件可能需要非常久時間,期間無法對外提供服務。
AOF重寫
  • Redis提供了bgrewriteaof指令對AOF日志瘦身。原理如下:
    • fork一個子進程對內存進行遍歷,轉換成一些列Redis的操作指令例如set, hset等,重寫序列化到新的AOF文件中
    • 完成存量的AOF之后,在操作期間的增量AOF日志追加到新的AOF日志文件中,然后替代原有AOF文件。
fsync
  • 還回歸到IO操作的問題上,在AOF日志寫入時候,實際上是將內容寫到內核為文件描述符分配的的一個內存緩沖區中。然后內核在異步將數據刷回磁盤,這時候宕機,AOF日志可能丟失
  • Linux的glibc提供了fsync(int fd)函數可以指定文件的內容強制從內核緩沖區刷新到磁盤。Redis調用fsync就可以保證不丟失,但是IO一次很慢,每次一條命令都一次IO操作性能會很受影響。
  • Redis提供兩種策略:
    • 一個永不主動調用fsync,讓系統決定何時同步磁盤,非安全性的操作
    • 另一個每個指令都調用fsync一次,會導致Redis延遲變得異常大,影響效率,不推薦
生產做法
  • 快照是通過開啟子進程方式進行,他比較消耗資源的操作
    • 遍歷整個內存,大塊寫磁盤家中系統負載
    • AOF的fsync是耗時的IO操作,會降低Redis性能,同時頻繁IO增加系統負擔。
  • 利用從節點進行持久化,在備份節點沒有來自客戶端壓力,操作系統資源充沛,問題在于需要保證從節點的數據完整性,例如異地多活導致的網絡分區,造成數據延遲,會導致一部分數據延遲此時持久化就丟了這部分數據量。應該增加數據監控,保證完了暢通或者能快速恢復
Redis4.0 混合持久化
  • 重啟Redis時候,很少使用RDB恢復,因為會丟失大量數據。我們通常用AOF回放,但是AOF回放啟動時候加載太慢,導致啟動時間變長。
  • Redis4.0 解決了這個問題,兼具AOF,RDB的長處-----混合持久化
    • 將RDB文件的內容與RDB之后的增量修改AOF文件保存在一起
    • 此處AOF日志不是全量日志,而是RDB結束后的AOF日志信息,這樣日志量就少太多
    • Redis重啟后,先加載Rdb內容,在回放AOF日志,可以完全替代之前的AOF全量,重啟效率增加
  • 如下圖。

上一篇:Redis高效性探索–管道
下一篇:Redis–事務

總結

以上是生活随笔為你收集整理的Redis持久化-深入理解AOF,RDB的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。