首頁  >  文章  >  資料庫  >  Redis的RDB和AOF方法怎麼用

Redis的RDB和AOF方法怎麼用

WBOY
WBOY轉載
2023-06-05 12:31:031364瀏覽

Redis持久化方案

Redis是記憶體資料庫,資料都是儲存在記憶體中,為了避免進程退出導致資料的永久遺失,需要定期將Redis中的資料以某種形式(資料或指令)從記憶體儲存到硬碟。當下次Redis重啟時,利用持久化文件實現資料恢復。除此之外,為了進行災難備份,可以將持久化文件拷貝到一個遠端位置。

Redis的RDB和AOF方法怎麼用

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# Persistenceaof_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方法怎麼用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除