您好,登錄后才能下訂單哦!
如何進行Redis持久化RDB和AOF的分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
Redis持久化方案
Redis是內存數據庫,數據都是存儲在內存中,為了避免進程退出導致數據的永久丟失,需要定期將Redis中的數據以某種形式(數據或命令)從內存保存到硬盤。當下次Redis重啟時,利用持久化文件實現數據恢復。除此之外,為了進行災難備份,可以將持久化文件拷貝到一個遠程位置。
Redis提供了多種不同級別的持久化方式:一種是RDB,另一種是AOF。
RDB持久化可以在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot),將數據庫的快照(snapshot)以二進制的方式保存到磁盤中。
AOF持久化記錄服務器執行的所有更改操作命令,AOF文件中的命令全部以Redis協議的格式來保存,新命令會被追加到文件的末尾。Redis還可以在后臺對AOF文件進行重寫(rewrite),使得AOF文件的體積不會超出保存數據集狀態所需的實際大小。
Redis可以同時使用AOF持久化和RDB持久化。在這種情況下,當Redis重啟時,它會優先使用AOF文件來還原數據集,因為AOF文件保存的數據集通常比RDB文件所保存的數據集更完整。你甚至可以關閉持久化功能,讓數據只在服務器運行時存在。
了解RDB持久化和AOF持久化之間的異同是非常重要的,以下幾個小節將詳細地介紹這這兩種持久化功能,并對它們的相同和不同之處進行說明。
RDB快照
下面我們說一下Redis的第一個持久化策略,RDB快照。Redis支持將當前內存數據的快照存成一個數據文件的持久化機制,而一個持續寫入的數據庫如何生成快照呢?Redis巧妙地借助了fork命令的寫時復制(copy on write)機制,將當前進程fork出一個子進程,子進程根據內存快照,循環將數據持久化為RDB文件。
在默認情況下, Redis將數據庫快照保存在根目錄下,名字為dump.rdb的二進制文件中。可通過參數dir配置指定保存目錄,dbfilename指定文件名。你可以對Redis進行設置,如“save N M”,表示N秒內數據項中有M個改動時這一條件被滿足時,自動保存一次數據集。比如你可以配置當10分鐘以內有100次寫入就生成快照,也可以配置當1分鐘內有1000次寫入就生成快照,支持可以多個規則一起生效,當匹配到哪個就哪個規則生效。這些規則的定義就在Redis的配置文件中,你也可以通過Redis的CONFIG SET命令在Redis運行時設置規則,不需要重啟Redis。
比如說,以下設置會讓Redis在滿足“60秒內有至少有1000個鍵被改動”這一條件時,自動保存一次數據集:
save 60 1000
你也可以通過調用SAVE或者BGSAVE,手動讓Redis進行數據集保存操作。SAVE命令執行一個同步操作,以RDB文件的方式保存所有數據的快照,很少在生產環境直接使用SAVE命令,因為它會阻塞所有的客戶端的請求,不要在生產環境使用,可以使用BGSAVE命令代替。BGSAVE命令執行過程中是通過fork一個子進程來完成的,所以不會阻塞客戶端請求,只有fork子進程時會阻塞服務器。另外,在自動觸發RDB持久化時,Redis也會選擇BGSAVE而不是SAVE來進行持久化。
Redis自動RDB持久化在其內部是通過serverCron周期性操作函數、dirty計數器、和lastsave時間戳來實現的。其中serverCron每100ms執行一次,檢查服務器狀態,其中就包括檢查“save N M”是否滿足條件,如果滿足就執行BGSAVE;當然也包括AOF重寫檢查。dirty計數器是Redis服務器維持的一個狀態,記錄了上一次執行BGSAVE/SAVE命令后,服務器狀態進行了多少次修改(包括增刪改),而當BGSAVE/SAVE執行完成后,會將dirty重新置為0。lastsave時間戳也是Redis服務器維持的一個狀態,記錄的是上一次成功執行BGSAVE/SAVE的時間,當前時間減去lastsave需滿足M。
除了手動和自動以外,還有一些其他情況會觸發BGSAVE:
在主從復制場景下,如果從節點執行全量復制操作,則主節點會執行BGSAVE命令,并將rdb文件發送給從節點。
執行shutdown命令時,自動執行rdb持久化。
另外需要了解的,因為其寫操作是在一個新進程中進行的,當生成一個新的RDB文件時,Redis生成的子進程會先將數據寫到一個臨時文件中,然后通過原子性rename系統調用將臨時文件重命名為RDB文件,這樣在任何時候出現故障,Redis的RDB文件都總是可用的。
這種持久化方式被稱為快照(snapshot)。但是,我們可以很明顯的看到,RDB有他的不足,就是一旦數據庫出現問題,那么我們的RDB文件中保存的數據并不是全新的,從上次RDB文件生成到Redis停機這段時間的數據全部丟掉了。在某些業務下,如果可以忍受間隔內數據丟失,我們也推薦這些業務使用RDB的方式進行持久化,因為開啟RDB的代價并不高。但是對于另外一些對數據安全性要求極高的應用,無法容忍數據丟失的應用,RDB就無能為力了,所以Redis引入了另一個重要的持久化機制,AOF日志方式持久化。
為了盡可能使RDB文件體積減小,Redis默認采用LZF算法對RDB文件進行壓縮。雖然壓縮耗時,但是可以大大減小RDB文件的體積,因此壓縮默認開啟,參數為rdbcompression。需要注意的是,RDB文件的壓縮并不是針對整個文件進行的,而是對數據庫中的字符串進行的,且只有在字符串達到一定長度(20字節)時才會進行。
除了壓縮,你也可以檢驗RDB文件,通過參數rdbchecksum設置,默認為yes。在寫入文件和讀取文件時都起作用,關閉checksum在寫入文件和啟動文件時大約能帶來10%的性能提升,但是數據損壞時無法發現。
另外,當bgsave出現錯誤時,Redis是否停止執行寫命令。Redis提供了一個參數stop-writes-on-bgsave-error,設置為yes,則當硬盤出現問題時,可以及時發現,避免數據的大量丟失;設置為no,則Redis無視bgsave的錯誤繼續執行寫命令,當對Redis服務器的系統(尤其是硬盤)使用了監控時,該選項考慮設置為no。
說說FORK的開銷?
父進程通過fork操作可以創建子進程,第一代Unix系統實現了一種傻瓜式的進程創建:當執行fork系統調用時,內核復制父進程的整個用戶空間并把復制得到的那一份分配給子進程。這種行為時非常耗時的,因為它需要完成以下幾項任務:為子進程的頁表分配頁面、為子進程的頁分配頁面、初始化子進程的頁表、把父進程的頁復制到子進程對應的頁中。
現在 Linux 的fork()使用寫時拷貝(copy-on-write)頁實現。寫時拷貝是一種可以推遲甚至免除拷貝數據的技術。內核此時并不復制整個進程地址空間,而是讓父進程和子進程共享同一個拷貝。只有在需要寫入的時候,數據才會被復制,從而使各個進程擁有各自的拷貝。也就是說,資源的復制只有在需要寫入的時候才進行,在此之前,只是以只讀方式共享。這種技術使地址空間上的頁的拷貝被推遲到實際發生寫入的時候。所以就算fork很大內存的進程,對內存的消耗和耗時都很小。
現在雖然fork時,子進程不會復制父進程的數據空間,但是會復制內存頁表(頁表相當于內存的索引、目錄);父進程的數據空間越大,內存頁表越大,fork時復制耗時也會越多。這個問題也是導致Redis內存不宜過大的原因之一,當然還有導致故障恢復時間延長也是Redis內存不宜過大的原因。
AOF日志
通過上面的分析,我們知道RDB快照有大概率丟失最近寫入、且仍未保存到快照中的那些數據。盡管對于某些程序來說,數據安全并不是最重要的考慮因素,但是對于那些追求數據安全的程序來說,快照功能就不太適用了。從1.1版本開始,Redis增加了一種實時性更好的持久化方式,即AOF持久化。AOF日志的全稱是append only file,從名字上我們就能看出來,它是一個追加寫入的日志文件。與RDB相比,AOF的實時性更好,因此已成為主流的持久化方案。
AOF文件與MySQL數據庫的binlog不同的是,AOF是一種純文本格式,具有兼容性好、可讀性強、容易處理、操作簡單避免二次開銷等優點,它記錄的內容就是一個個的Redis標準命令。開啟AOF持久化命令如下:
appendonly yes appendfilename "appendonly.aof"
從現在開始,每當Redis執行一個改變數據集的命令時(比如SET),這個命令就會被追加到AOF文件的末尾。這樣的話,當Redis重新啟時,程序就可以通過重新執行AOF文件中的命令來達到重建數據集的目的。
由于需要記錄Redis的每條寫命令,因此AOF不需要觸發,下面介紹AOF的執行流程:
命令追加(append)
Redis先將寫命令追加到緩沖區,而不是直接寫入文件,主要是為了避免每次有寫命令都直接寫入硬盤,導致硬盤IO成為Redis負載的瓶頸。
文件寫入(write)和文件同步(sync)
Redis提供了多種AOF緩存區的同步文件策略,策略涉及到操作系統的write函數和fsync函數,說明如下:
為了提高文件寫入效率,在現代操作系統中,當用戶調用write函數將數據寫入文件時,操作系統通常會將數據暫存到一個內存緩沖區里,當緩沖區被填滿或超過了指定時限后,才真正將緩沖區的數據寫入到硬盤里。這樣的操作雖然提高了效率,但也帶來了安全問題:如果計算機停機,內存緩沖區中的數據會丟失;因此系統同時提供了fsync、fdatasync等同步函數,可以強制操作系統立刻將緩沖區中的數據寫入到硬盤里,從而確保數據的安全性。
AOF緩存區的同步文件策略由參數appendfsync控制,各個值的含義如下:
always:命令寫入aof_buf后立即調用系統fsync操作同步到AOF文件,fsync完成后線程返回。這種情況下,每次有寫命令都要同步到AOF文件,硬盤IO成為性能瓶頸,Redis只能支持大約幾百TPS寫入,嚴重降低了Redis的性能;即便是使用固態硬盤(SSD),每秒大約也只能處理幾萬個命令,而且會大大降低SSD的壽命。
no:命令寫入aof_buf后調用系統write操作,不對AOF文件做fsync同步;同步由操作系統負責,通常同步周期為30秒。這種情況下,文件同步的時間不可控,且緩沖區中堆積的數據會很多,數據安全性無法保證。
everysec:命令寫入aof_buf后調用系統write操作,write完成后線程返回;fsync同步文件操作由專門的線程每秒調用一次。everysec是前述兩種策略的折中,是性能和數據安全性的平衡,因此是Redis的默認配置,也是我們推薦的配置。
文件重寫(rewrite)
因為AOF的運作方式是不斷地將命令追加到文件的末尾,所以隨著寫入命令的不斷增加,AOF文件的體積也會變得越來越大。舉個例子,如果你對一個計數器調用了100次INCR,那么僅僅是為了保存這個計數器的當前值,AOF文件就需要使用100條記錄(entry)。然而在實際上,只使用一條SET命令已經足以保存計數器的當前值了,其余99條記錄實際上都是多余的。另外還有一些過期的數據,無效的數據也都是可以去除。
過大的AOF文件不僅會影響服務器的正常運行,也會導致數據恢復需要的時間過長。為了處理這種情況,Redis支持一種有趣的特性,可以在不打斷服務客戶端的情況下,對AOF文件進行重建(rebuild)。執行BGREWRITEAOF命令, Redis將生成一個新的AOF文件, 這個文件包含重建當前數據集所需的最少命令。
AOF REWRITE(重寫)生成過程和RDB快照類似,都巧妙地利用了寫時復制機制。同樣也是fork一個子進程(此時主線程是阻塞的),子進程根據內存快照,按照命令合并規則寫入到新的AOF文件。當主進程fork完子線程后繼續接受請求,所有寫命令依然寫入AOF緩沖區(aof_buf),并根據appendfsync策略同步到硬盤,保證原有AOF機制的正確。但由于fork操作使用寫時復制技術,子進程只能共享fork操作時的內存數據。由于父進程依然在響應命令,因此Redis使用AOF重寫緩沖區(aof_rewrite_buf)保存這部分新日志,防止新AOF文件生成期間丟失這部分數據。也就是說,bgrewriteaof執行期間,Redis的寫命令同時追加到aof_buf和aof_rewirte_buf兩個緩沖區。
當子進程寫完新的AOF文件后,向父進程發信號,父進程更新統計信息,具體可以通過info persistence查看。然后父進程把AOF重寫緩沖區的數據寫入到新的AOF文件,這樣就保證了新AOF文件所保存的數據庫狀態和服務器當前狀態一致。然后調用原子性的rename命令用新的AOF文件取代老的AOF文件,完成AOF重寫。
這里需要注意,因為由主進程把aof_rewrite_buf緩存追加到新日志文件。主進程追加日志時,不會處理其他請求,如果aof_rewrite_buf特別大,例如幾百M,也可能造成Redis幾秒甚至幾十秒不響應。
從上面的流程我們能夠看到,RDB和AOF操作都是順序IO操作,性能都很高。而在通過RDB文件或者AOF日志進行數據庫恢復的時候,也是順序的讀取數據加載到內存中。所以也不會造成磁盤的隨機讀。
文件重寫的觸發,分為手動觸發和自動觸發:
手動觸發:直接調用bgrewriteaof命令,該命令的執行與bgsave有些類似:都是fork子進程進行具體的工作,且都只有在fork時阻塞。
自動觸發:根據auto-aof-rewrite-min-size和auto-aof-rewrite-percentage參數,以及aof_current_size和aof_base_size狀態確定觸發時機。
auto-aof-rewrite-min-size表示執行AOF重寫時,文件的最小體積,默認值為64MB。
auto-aof-rewrite-percentage表示執行AOF重寫時,當前AOF大小(即aof_current_size)和上一次重寫時AOF大小(aof_base_size)的比值,即增長比例達到設定值。
只有當auto-aof-rewrite-min-size和auto-aof-rewrite-percentage兩個參數同時滿足時,才會自動觸發AOF重寫,即bgrewriteaof操作。
其中,參數可以通過config get命令查看:
127.0.0.1:6391> CONFIG GET auto-aof-rewrite-min-size 1) "auto-aof-rewrite-min-size" 2) "64000000" 127.0.0.1:6391> CONFIG GET auto-aof-rewrite-percentage 1) "auto-aof-rewrite-percentage" 2) "100"
狀態可以通過info persistence查看:
127.0.0.1:6379> info persistence # Persistence aof_enabled:1 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:0 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_current_size:40876638 aof_base_size:2217565 aof_pending_rewrite:0 aof_buffer_length:0 aof_rewrite_buffer_length:0 aof_pending_bio_fsync:0 aof_delayed_fsync:0
另外在aof rewrite過程中,是否采取增量”文件同步”策略,由參數aof-rewrite-incremental-fsync控制,默認為”yes”,而且必須為yes。rewrite過程中,每32M數據進行一次文件同步,這樣可以減少”aof大文件”寫入對磁盤的操作次數。
bgrewriteaof機制,在一個子進程中進行aof的重寫,從而不阻塞主進程對其余命令的處理,同時解決了aof文件過大問題。現在問題出現了,同時在執行bgrewriteaof操作和主進程寫aof文件的操作,兩者都會操作磁盤,而bgrewriteaof往往會涉及大量磁盤操作,這樣就會造成主進程在寫aof文件的時候出現阻塞的情形,現在no-appendfsync-on-rewrite參數出場了。
如果該參數設置為no,是最安全的方式,不會丟失數據,但是要忍受阻塞的問題。如果設置為yes呢?這就相當于將appendfsync設置為no,這說明并沒有執行磁盤操作,只是寫入了緩沖區,因此這樣并不會造成阻塞(因為沒有競爭磁盤),但是如果這個時候Redis掛掉,就會丟失數據。丟失多少數據呢?在Linux的操作系統的默認設置下,最多會丟失30s的數據。因此,如果應用系統無法忍受延遲,而可以容忍少量的數據丟失,則設置為yes。如果應用系統無法忍受數據丟失,則設置為no。
AOF刷新策略?
前面提到過,在AOF中,如果AOF緩沖區的文件同步策略為everysec,則:在主線程中,命令寫入aof_buf后調用系統write操作,write完成后主線程返回;fsync同步文件操作由專門的文件同步線程每秒調用一次。這種做法的問題在于,如果硬盤負載過高,那么fsync操作可能會超過1s;如果Redis主線程持續高速向aof_buf寫入命令,硬盤的負載可能會越來越大,IO資源消耗更快;如果此時Redis進程異常退出,丟失的數據也會越來越多,可能遠超過1s。
為此,Redis的處理策略是這樣的:主線程每次進行AOF會對比上次fsync成功的時間;如果距上次不到2s(也就是延遲了1s),主線程直接返回;如果超過2s,則主線程阻塞直到上一次fsync同步完成。因此,如果系統硬盤負載過大導致fsync速度太慢,會導致Redis主線程的阻塞;此外,使用everysec配置,AOF最多可能丟失2s的數據,而不是1s。具體看Redis AOF刷新策略分析
AOF追加阻塞問題定位的方法,監控info Persistence中的aof_delayed_fsync,當AOF追加阻塞發生時(即主線程等待fsync而阻塞),該指標累加。另外,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.
如果AOF追加阻塞頻繁發生,說明系統的硬盤負載太大;可以考慮更換IO速度更快的硬盤,或者通過IO監控分析工具對系統的IO負載進行分析。
對于pipelining有什么不同?
對于pipelining的操作,其具體過程是客戶端一次性發送N個命令,然后等待這N個命令的返回結果被一起返回。通過采用pipilining就意味著放棄了對每一個命令的返回值確認。由于在這種情況下,N個命令是在同一個執行過程中執行的。所以當設置appendfsync為everysec時,可能會有一些偏差,因為這N個命令可能執行時間超過1秒甚至2秒。但是可以保證的是,最長時間不會超過這N個命令的執行時間和。
如果AOF文件出錯了,怎么辦?
服務器可能在程序正在對AOF文件進行寫入時停機,如果停機造成了 AOF 文件出錯(corrupt),那么Redis在重啟時會拒絕載入這個AOF文件, 從而確保數據的一致性不會被破壞。當發生這種情況時,可以用以下方法來修復出錯的 AOF 文件:為現有的AOF文件創建一個備份。然后使用Redis附帶的redis-check-aof --fix程序對原來的AOF文件進行修復。
然后可選使用 diff -u 對比修復后的 AOF 文件和原始 AOF 文件的備份,查看兩個文件之間的不同之處。再次重啟Redis服務器,等待服務器載入修復后的AOF文件,并進行數據恢復。
但如果是AOF文件結尾不完整(機器突然宕機等容易導致文件尾部不完整),且aof-load-truncated參數開啟,則日志中會輸出警告,Redis忽略掉AOF文件的尾部,啟動成功。aof-load-truncated參數默認是開啟的。
RDB和AOF優缺點
RDB的優點?
RDB是一個非常緊湊(compact)的文件,體積小,網絡傳輸快,它保存了Redis在某個時間點上的數據集。這種文件非常適合用于進行備份,恢復速度比AOF快很多。當然,與AOF相比,RDB最重要的優點之一是對性能的影響相對較小。父進程在保存RDB文件時唯一要做的就是fork出一個子進程,然后這個子進程就會處理接下來的所有保存工作,父進程無須執行任何磁盤 I/O 操作。
RDB的缺點?
RDB文件的致命缺點在于其數據快照的持久化方式決定了必然做不到實時持久化,而在數據越來越重要的今天,數據的大量丟失很多時候是無法接受的,因此AOF持久化成為主流。此外,RDB文件需要滿足特定格式,兼容性差(如老版本的Redis不兼容新版本的RDB文件)。
AOF的優點?
與RDB持久化相對應,AOF的優點在于支持秒級持久化、兼容性好。你可以設置不同的fsync策略,比如無fsync,每秒鐘一次fsync,或者每次執行寫入命令時fsync。AOF的默認策略為每秒鐘fsync一次,在這種配置下,Redis仍然可以保持良好的性能,并且就算發生故障停機,也最多只會丟失一秒鐘的數據。AOF文件是一個只進行追加操作的日志文件(append only log),因此對AOF文件的寫入不需要進行seek(查找),即使日志因為某些原因而包含了未寫入完整的命令(比如寫入時磁盤已滿,寫入中途停機,等等), redis-check-aof 工具也可以輕易地修復這種問題。
Redis可以在AOF文件體積變得過大時,自動地在后臺對AOF進行重寫: 重寫后的新AOF文件包含了恢復當前數據集所需的最小命令集合。 整個重寫操作是絕對安全的,因為 Redis 在創建新 AOF 文件的過程中,會繼續將命令追加到現有的AOF文件里面,即使重寫過程中發生停機,現有的AOF文件也不會丟失。 而一旦新AOF文件創建完畢,Redis就會從舊AOF文件切換到新AOF文件,并開始對新AOF文件進行追加操作。AOF文件有序地保存了對數據庫執行的所有寫入操作,這些寫入操作以Redis協議的格式保存,因此AOF文件的內容非常容易被人讀懂,對文件進行分析(parse)也很輕松。導出(export)AOF文件也非常簡單: 舉個例子, 如果你不小心執行了FLUSHALL命令,但只要AOF文件未被重寫,那么只要停止服務器,移除AOF文件末尾的FLUSHALL命令,并重啟 Redis, 就可以將數據集恢復到FLUSHALL執行之前的狀態。
AOF的缺點?
AOF文件的體積通常要大于RDB文件的體積、且恢復速度慢。對于相同的數據集來說,根據所使用的fsync策略,AOF的速度可能會慢于RDB。在一般情況下,每秒fsync的性能依然非常高,而關閉fsync可以讓AOF的速度和RDB一樣快。另外,AOF在過去曾經發生過這樣的bug,因為個別命令的原因,導致AOF文件在重新載入時,無法將數據集恢復成保存時的原樣。雖然這種bug在AOF文件中并不常見,但是對比來說,RDB幾乎是不可能出現這種bug的。
RDB和AOF,我應該用哪一個?
首先要明白無論是RDB還是AOF,持久化的開啟都是要付出性能方面代價的:對于RDB持久化,一方面是bgsave在進行fork操作時Redis主進程會阻塞,另一方面,子進程向硬盤寫數據也會帶來IO壓力。但如果業務能容忍幾分鐘到10幾分鐘的數據丟失(且不使用備庫),RDB是一個不錯的選擇;不然,就選擇AOF。
對于AOF持久化,向硬盤寫數據的頻率大大提高(everysec策略下為秒級),IO壓力更大,甚至可能造成AOF追加阻塞問題(后面會詳細介紹這種阻塞),此外,AOF文件的重寫與RDB的bgsave類似,會有fork時的阻塞和子進程的IO壓力問題。相對來說,由于AOF向硬盤中寫數據的頻率更高,因此對Redis主進程性能的影響會更大。
在實際生產環境中,根據數據量、應用對數據的安全要求、預算限制等不同情況,會有各種各樣的持久化策略;如完全不使用任何持久化、使用RDB或AOF的一種,或同時開啟RDB和AOF持久化等。此外,持久化的選擇必須與Redis的主從策略一起考慮,因為主從復制與持久化同樣具有數據備份的功能,而且主機master和從機slave可以獨立的選擇持久化方案。比如完全關閉master持久化(包括RDB和AOF),這樣可以讓master的性能達到最好;而slave可以只開啟AOF。但這種情況下,如果master服務因為故障宕掉了,如果系統中有自動拉起機制(即檢測到服務停止后重啟該服務)將master自動重啟,由于沒有持久化文件,那么master重啟后數據是空的,slave同步數據也變成了空的,意味著數據丟失。所以盡量避免這種情況出現。
RDB和AOF之間的相互作用?
在版本號大于等于2.4的Redis中,BGSAVE執行的過程中,不可以執行BGREWRITEAOF。反過來說,在BGREWRITEAOF執行的過程中,也不可以執行BGSAVE。這可以防止兩個Redis后臺進程同時對磁盤進行大量的I/O操作。
如果BGSAVE正在執行,并且用戶顯示地調用BGREWRITEAOF命令,那么服務器將向用戶回復一個OK狀態,并告知用戶,BGREWRITEAOF已經被預定執行: 一旦BGSAVE執行完畢,BGREWRITEAOF就會正式開始。當Redis啟動時,如果RDB持久化和AOF持久化都被打開了,那么程序會優先使用AOF文件來恢復數據集,因為AOF文件所保存的數據通常是最完整的。
RDB和AOF數據導入
這些持久化的數據有什么用,當然是用于重啟后的數據恢復。Redis是一個內存數據庫,無論是RDB還是AOF,都只是其保證數據恢復的措施。所以Redis在利用RDB或AOF進行恢復的時候,會讀取RDB或AOF文件,重新加載到內存中。相對于MySQL等數據庫的啟動時間來說,會長很多,因為MySQL本來是不需要將數據加載到內存中的。
但是相對來說,MySQL啟動后提供服務時,其被訪問的熱數據也會慢慢加載到內存中,通常我們稱之為預熱,而在預熱完成前,其性能都不會太高。而Redis的好處是一次性將數據加載到內存中,一次性預熱。這樣只要Redis啟動完成,那么其提供服務的速度都是非常快的。
而在利用RDB和利用AOF啟動上,其啟動時間有一些差別。RDB的啟動時間會更短,原因有兩個,一是RDB文件中每一條數據只有一條記錄,不會像AOF日志那樣可能有一條數據的多次操作記錄。所以每條數據只需要寫一次就行了。另一個原因是RDB文件的存儲格式和Redis數據在內存中的編碼格式是一致的,不需要再進行數據編碼工作。在CPU消耗上要遠小于AOF日志的加載。
注意:當redis啟動時,如果rdb持久化和aof持久化都打開了,那么程序會優先使用aof方式來恢復數據集,因為aof方式所保存的數據通常是最完整的。如果aof文件丟失了,則啟動之后數據庫內容為空。
注意:如果想把正在運行的redis數據庫,從RDB切換到AOF,建議先使用動態切換方式,再修改配置文件,重啟數據庫。(不能直接修改配置文件,重啟數據庫,否則數據庫中數據就為空了。)
在Redis 2.2或以上版本,可以在不重啟的情況下,從RDB切換到AOF :
為最新的dump.rdb文件創建一個備份,將備份放到一個安全的地方。執行以下兩條命令:
127.0.0.1:6379> CONFIG SET dir /apps/redis/data/redis-8836 127.0.0.1:6379> CONFIG SET appendonly yes 127.0.0.1:6379> CONFIG SET save ""
確保命令執行之后,數據庫的鍵的數量沒有改變。確保寫命令會被正確地追加到 AOF 文件的末尾。
步驟2是開啟了AOF功能,Redis會阻塞直到初始AOF文件創建完成為止,之后Redis會繼續處理命令請求,并開始將寫入命令追加到AOF文件末尾。
步驟3用于關閉RDB功能,這一步是可選的,如果你愿意的話,也可以同時使用RDB和AOF這兩種持久化功能。
看完上述內容,你們掌握如何進行Redis持久化RDB和AOF的分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。