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

歡迎訪問 生活随笔!

生活随笔

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

数据库

redis 硬件要求_Redis持久化机制

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

介紹

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

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

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


一、Redis的持久化機制

Redis將所有的數(shù)據(jù)都存儲在內(nèi)存中,那么如果服務器重啟了,Redis中的數(shù)據(jù)怎么恢復呢?

為了使Redis在重啟之后仍能保證數(shù)據(jù)不丟失,需要將數(shù)據(jù)從內(nèi)存中同步到硬盤中。Redis支持兩種方式的持久化,一種是RDB方式,一種是AOF方式。可以單獨使用其中一種或?qū)⒍呓Y合使用。

二、RDB方式

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

save 900 1 save 300 10 save 60 10000

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

dbfilename?dump-${port}.rdb

快照的過程如下:

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

  • 父進程繼續(xù)接收并處理客戶端發(fā)來的命令,而子進程開始將內(nèi)存中的數(shù)據(jù)寫入硬盤中的臨時文件

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

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

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

RDB文件是經(jīng)過壓縮的二進制格式:

可以配置rdbcompression參數(shù)以禁用壓縮節(jié)省CPU占用,所以占用的空間會小于內(nèi)存中的數(shù)據(jù)大小,更加利于傳輸。其他兩個配置參數(shù):

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

除了自動快照,還可以手動發(fā)送SAVE或BGSAVE命令讓Redis執(zhí)行快照,兩個命令的區(qū)別:

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

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

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

RDB文件觸發(fā)機制

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

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

  • debug reload

  • shutdown

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

RDB方式的優(yōu)點:

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

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

RDB方式的缺點:

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

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

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

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

三、AOF方式

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

appendonly yes

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

appendfilename appendonly.aof

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

SET foo 1 SET foo 2 SET foo 3 GET foo

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

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

可見AOF文件是純文本文件,其內(nèi)容正是Redis客戶端向Redis發(fā)送的原始通信協(xié)議的內(nèi)容。

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

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

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

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

AOF文件重寫后的內(nèi)容為:

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

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

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

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

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

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

AOF追加阻塞

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

所以可能產(chǎn)生的問題:

  • 主線程阻塞,主線程需要執(zhí)行我們?nèi)粘C畹奶幚?#xff0c;所以主線程不能阻塞

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

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配置參數(shù)最佳實踐

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

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

AOF方式的優(yōu)點:

  • 數(shù)據(jù)安全

AOF方式的缺點:

  • 數(shù)據(jù)集大的時候,比RDB啟動效率低

fork操作介紹

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

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

  • 控制Redis實例最大可用內(nèi)存:maxmemory

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

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

子進程開銷和優(yōu)化

1. CPU

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

  • 優(yōu)化:不做CPU綁定,不和CPU密集型部署

2.?內(nèi)存

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

  • 優(yōu)化:不允許單機多部署時大量產(chǎn)生重寫

3.?硬盤

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

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

四、RDB與AOF對比

命令RDBAOF
啟動優(yōu)先級
體積
恢復速度
數(shù)據(jù)安全性丟數(shù)據(jù)根據(jù)策略決定
操作量級

五、混合持久化

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

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

推薦閱讀

Redis值類型之sorted set

Redis數(shù)據(jù)結構與內(nèi)部編碼,你知道多少?

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

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

總結

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

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