日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

redis 硬件要求_Redis持久化机制

發布時間:2024/2/28 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis 硬件要求_Redis持久化机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

介紹

Redis所有的數據都保存在內存中,數據的更新將異步的保存到硬盤上,當需要恢復數據時,從硬盤上將數據再讀取到內存中,這就是Redis的持久化過程。主流的持久化方式有兩種:

  • 快照:MySQL的Dump以及Redis的RDB等

  • 寫日志:MySQL的Binlog,Hbase的HLong以及Redis的AOF等


一、Redis的持久化機制

Redis將所有的數據都存儲在內存中,那么如果服務器重啟了,Redis中的數據怎么恢復呢?

為了使Redis在重啟之后仍能保證數據不丟失,需要將數據從內存中同步到硬盤中。Redis支持兩種方式的持久化,一種是RDB方式,一種是AOF方式。可以單獨使用其中一種或將二者結合使用。

二、RDB方式

RDB方式的持久化是通過快照(snapshotting)完成的,當符合一定條件時Redis會自動將內 存中的所有數據進行快照并存儲在硬盤上。進行快照的條件可以由用戶在配置文件中自定 義,由兩個參數構成:時間和改動的鍵的個數。當在指定的時間內被更改的鍵的個數大于指定 的數值時就會進行快照。RDB是Redis默認采用的持久化方式,在配置文件中已經預置了3個條 件:

save 900 1 save 300 10 save 60 10000

Redis默認會將快照文件存儲在當前目錄的dump.rdb文件中,可以通過配置dir和 dbfilename兩個參數分別指定快照文件的存儲路徑和文件名。最佳配置實踐:

dbfilename?dump-${port}.rdb

快照的過程如下:

  • Redis使用fork函數復制一份當前進程(父進程)的副本(子進程)

  • 父進程繼續接收并處理客戶端發來的命令,而子進程開始將內存中的數據寫入硬盤中的臨時文件

  • 當子進程寫入完所有數據后會用該臨時文件替換舊的RDB文件,至此一次快照操作完 成。

寫時復制(copy-on-write)策略:在執行fork的時候操作系統會使用寫時復制策略,即fork函數發生的一刻父子進程共享同一內存數據,當父進程要更改其中某片數據時(如執行一個寫命令),操作系統會將該片數據復制一份以保證子進程的數據不受影響,所以新的RDB文件存儲的是執行fork一刻的內存數據。

Redis在進行快照的過程中不會修改RDB文件,只有快照結束后才會將舊的文件替換成新的,也就是說任何時候RDB文件都是完整的。這樣我們可以通過定時備份RDB文件來實現Redis數據庫備份。

RDB文件是經過壓縮的二進制格式:

可以配置rdbcompression參數以禁用壓縮節省CPU占用,所以占用的空間會小于內存中的數據大小,更加利于傳輸。其他兩個配置參數:

stop-writes-on-bgsave-error yes // bgsave發生錯誤,停止寫入rdbchecksum?yesrdbcompression yes

除了自動快照,還可以手動發送SAVE或BGSAVE命令讓Redis執行快照,兩個命令的區別:

  • SAVE是由主進程進行快照操作,會阻塞住客戶端其他請求,不會消耗額外的內存

  • BGSAVE會通過fork子進程進行快照操作,不會阻塞客戶端命令,fork會消耗內存

  • 兩者的時間復雜度都是o(n)

RDB文件觸發機制

除了前面介紹的三種:自動,save,bgsave外,還有下面幾種方式也會生成RDB文件:

  • 全量復制:主從復制中,主節點會自動生成RDB文件給從節點同步使用

  • debug reload

  • shutdown

Redis啟動后會讀取RDB快照文件,將數據從硬盤載入到內存。通常將一個記錄一千萬個字符串類型鍵、大小為1GB的快照文件載入到內存中需要花費20~30秒鐘。通過RDB方式實現持久化,一旦Redis異常退出,就會丟失最后一次快照以后更改的所有數據。如果數據很重要以至于無法承受任何損失,則可以考慮使用AOF方式進行持久化。

RDB方式的優點:

  • 性能最大化,fork子進程來完成寫操作,讓主進程繼續處理命令,使用單獨子進程來進行持久化,保證了redis的高性能

  • 當重啟恢復數據的時候,數據量比較大時,Redis直接解析RDB二進制文件,生成對應的數據存儲在內存中,比AOF的啟動效率更高

RDB方式的缺點:

  • 數據安全性低,RDB是間隔一段時間進行持久化,如果持久化之間redis發生故障,會發生數據丟失,所以這種方式更適合數據要求不嚴謹的時候

  • linux fork之后,kernel把父進程中所有的內存頁的權限都設為read-only,然后子進程的地址空間指向父進程。當父子進程都只讀內存時,相安無事。

  • 當其中某個進程寫內存時,CPU硬件檢測到內存頁是read-only的,于是觸發頁的異常中斷(page-fault),陷入kernel的一個中斷例程

  • 中斷例程中,kernel的copyonwrite機制就會把觸發的異常的頁復制一份,于是父子進程各自持有獨立的一份,如果這時有大量的寫入操作,會產生大量的分頁錯誤,這樣就得耗費不少性能在復制上

三、AOF方式

默認情況下Redis沒有開啟AOF(append only file)方式的持久化,可以通過appendonly參數開啟:

appendonly yes

開啟AOF持久化后每執行一條會更改Redis中的數據的命令,Redis就會將該命令寫入硬盤中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通過dir參數設置的,默認的文件名是appendonly.aof,可以通過appendfilename參數修改:

appendfilename appendonly.aof

下面介紹AOF持久化的具體實現,假設在開啟AOF持久化的情況下執行了如下4個命令:

SET foo 1 SET foo 2 SET foo 3 GET foo

Redis會將前3條命令寫入AOF文件中,此時AOF文件中的內容如下:

*2$6SELECT$10*3$3set$3foo$11*3$3set$3foo$12*3$3set$3foo$13

可見AOF文件是純文本文件,其內容正是Redis客戶端向Redis發送的原始通信協議的內容。

這里有一個問題是前2條命令其實都是冗余的, 因為這兩條的執行結果會被第三條命令覆蓋。隨著執行的命令越來越多,AOF文件的大小也會越來越大。實際上每當達到一定條件時Redis就會自動重寫AOF文件,這個條件可以在配置文件中設置:

auto-aof-rewrite-percentage?100?//代表當前AOF文件空間和上一次重寫后AOF文件空間的比值auto-aof-rewrite-min-size?64mb?//表示運行AOF重寫時文件最小體積,默認64MB
  • auto-aof-rewrite-percentage參數的意思是當目前的AOF文件大小超過上一次重寫時的AOF 文件大小的百分之多少時會再次進行重寫,如果之前沒有重寫過,則以啟動時的AOF文件大小為依據

  • auto-aof-rewrite-min-size參數限制了允許重寫的最小AOF文件大小,通常在AOF文 件很小的情況下即使其中有很多冗余的命令我們也并不太關心

除了讓Redis自動執行重寫外,還可以主動使用BGREWRITEAOF命令手動執行AOF重寫。

AOF文件重寫后的內容為:

*2$6SELECT$10*3$3set$3foo$13

在啟動時Redis會逐個執行AOF文件中的命令來將硬盤中的數據載入到內存中,載入的速度相較RDB會慢一些。下面是AOF重寫的流程:

注意:雖然每次執行更改數據庫內容的操作時,AOF都會將命令記錄在AOF文件中,但是由于操作系統的緩存機制,數據并沒有真正地寫入硬盤,而是進入了系統的硬盤緩存。在默認情況下系統每30秒會執行一次同步操作,以便將硬盤緩存中的內容真正地寫入硬盤,在這30秒的過程中如果系統異常退出則會導致硬盤緩存中的數據丟失。一般來講啟用AOF持久化的應用都無法容忍這樣的損失,這就需要Redis在寫入AOF文件后主動要求系統將緩存內容同步到硬盤中。在Redis中我們可以通過appendfsync參數設置同步的時機:

# appendfsync always appendfsync everysec # appendfsync no
  • 默認情況下Redis采用everysec 規則,即每秒執行一次同步操作

  • always表示每次執行寫入都會執行同步,這是最安全也是最慢的方式

  • no表示不主動進行同步操作,而是完全交由操作系統來做(即每30秒一次),這是最快但最不安全的方式

AOF追加阻塞

主線程為了達到每秒刷盤的策略,它會執行AOF追加阻塞,流程如下:

所以可能產生的問題:

  • 主線程阻塞,主線程需要執行我們日常命令的處理,所以主線程不能阻塞

  • 每秒刷盤的策略不是只丟失1秒的數據,實際上可能丟失2秒的數據

AOF阻塞定位可以通過Redis日志:

Asynchronous AOF fsync is taking too long (disk is busy?).Writing?the?AOF?buffer?without?waiting?for?fsync?to?complete,this?may?slow?down Redis

也可以通過Redis命令:

127.0.0.1:6379>?info?persistence......aof_delayed_fsync:100......

也可以通過top命令觀察硬盤IO資源比較緊張的情況:

AOF配置參數最佳實踐

appendonly yesappendfilename?appendonly-${port}.aofappendfsync everysec no-appendfsync-on-rewrite?yes?//?aof重寫時是否做aof的append操作(否)

Redis允許同時開啟AOF和RDB,既保證了數據安全又使得進行備份等操作十分容易。此時重新啟動Redis后Redis會使用AOF文件來恢復數據,因為AOF方式的持久化可能丟失的數據更少。

AOF方式的優點:

  • 數據安全

AOF方式的缺點:

  • 數據集大的時候,比RDB啟動效率低

fork操作介紹

fork操作只是做一個內存頁(4K)的拷貝而不是拷貝整個內存,所以在大部分情況下是非常快的。info:latest_fork_usec可以查看Redis持久化的時間。改善fork可以通過:

  • 使用物理機或者高效支持fork操作的虛擬化技術

  • 控制Redis實例最大可用內存:maxmemory

  • 合理配置Linux內存分配策略:vm.overcommit_memory=1,當沒有足夠內存去做內存分配的時候就不去分配內存,默認值是0

  • 降低fork頻率,例如放寬AOF重寫機制的觸發時機,減少不必要的全量復制

子進程開銷和優化

1. CPU

  • 開銷:RDB和AOF文件生成,屬于CPU密集型,大量寫操作集中在這個時候

  • 優化:不做CPU綁定,不和CPU密集型部署

2.?內存

  • 開銷:copy-on-write,父子進程共享一個物理內存頁,寫時會fork一個副本

  • 優化:不允許單機多部署時大量產生重寫

3.?硬盤

  • 開銷:RDB和AOF文件寫入,可以結合iostat,iotop分析

  • 優化:不要和高硬盤負載服務部署一起:存儲服務,消息隊列等;no-appendfsync-on-rewrite=yes;大寫入量可以選用ssd;單機多實例持久化文件目錄可以考慮分盤

四、RDB與AOF對比

命令RDBAOF
啟動優先級
體積
恢復速度
數據安全性丟數據根據策略決定
操作量級

五、混合持久化

可以通過參數設置:aof-use-rdb-preamble yes開啟。

加載時,首先會識別AOF文件是否以REDIS字符串開頭,如果是,就按RDB格式加載,加載完RDB之后繼續按照AOF格式加載剩余部分。混合式持久化方案兼顧了RDB的速度和AOF的安全性。

推薦閱讀

Redis值類型之sorted set

Redis數據結構與內部編碼,你知道多少?

看完本文有收獲?請轉發分享給更多人

關注「并發編程之美」,一起交流Java學習心得

總結

以上是生活随笔為你收集整理的redis 硬件要求_Redis持久化机制的全部內容,希望文章能夠幫你解決所遇到的問題。

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