Redis系列(二):深入解讀Redis的兩種持久化方式
博客地址:blog.zysicyj.top
Redis為什么要引入持久化機制
Redis引入持久化機制是為了解決內(nèi)存數(shù)據(jù)庫的數(shù)據(jù)安全性和可靠性問題。雖然內(nèi)存數(shù)據(jù)庫具有高速讀寫的優(yōu)勢,但由于數(shù)據(jù)存儲在內(nèi)存中,一旦服務器停止或崩潰,所有數(shù)據(jù)將會丟失。持久化機制的引入旨在將內(nèi)存中的數(shù)據(jù)持久化到磁盤上,從而在服務器重啟后能夠恢復數(shù)據(jù),提供更好的數(shù)據(jù)保護和可靠性。
以下是持久化機制的幾個主要原因:
「1. 數(shù)據(jù)安全和可靠性:」通過將數(shù)據(jù)持久化到磁盤上,即使在服務器崩潰或異常停止的情況下,也可以保證數(shù)據(jù)不會丟失。持久化機制可以防止重要的數(shù)據(jù)在突發(fā)情況下遭受損失。
「2. 數(shù)據(jù)恢復:」持久化機制允許在服務器重啟后將數(shù)據(jù)重新加載到內(nèi)存中,從而實現(xiàn)數(shù)據(jù)的恢復。這對于業(yè)務的連續(xù)性和可用性非常重要。
「3. 數(shù)據(jù)災難恢復:」持久化機制對于災難恢復也很有幫助。在不幸發(fā)生硬件故障、電力中斷等情況下,持久化機制可以幫助恢復數(shù)據(jù)。
「4. 數(shù)據(jù)遷移:」持久化機制也有助于將數(shù)據(jù)從一個服務器遷移到另一個服務器。你可以通過備份持久化文件并在另一臺服務器上進行恢復來完成數(shù)據(jù)遷移。
雖然持久化機制帶來了磁盤IO和性能開銷,但它為Redis提供了更強大的數(shù)據(jù)保護能力。根據(jù)應用的需求,可以根據(jù)數(shù)據(jù)的重要性和數(shù)據(jù)丟失的容忍度來選擇適當?shù)某志没绞剑蛘呓Y合兩種方式以提供更高的數(shù)據(jù)保護級別。
Redis提供了哪些持久化機制
Redis提供了兩種主要的持久化機制,分別是RDB快照(Snapshotting)和AOF日志(Append-Only File)。這兩種機制可以根據(jù)不同的需求和場景來選擇使用。
「1. RDB快照(Snapshotting):」RDB快照是一種全量持久化方式,它會周期性地將內(nèi)存中的數(shù)據(jù)以二進制格式保存到磁盤上的RDB文件。RDB文件是一個經(jīng)過壓縮的二進制文件,包含了數(shù)據(jù)庫在某個時間點的數(shù)據(jù)快照。RDB快照有助于實現(xiàn)緊湊的數(shù)據(jù)存儲,適合用于備份和恢復。
「優(yōu)點:」
RDB快照在恢復大數(shù)據(jù)集時速度較快,因為它是全量的數(shù)據(jù)快照。
由于RDB文件是壓縮的二進制文件,它在磁盤上的存儲空間相對較小。
適用于數(shù)據(jù)備份和災難恢復。
「缺點:」
RDB快照是周期性的全量持久化,可能導致某個時間點之后的數(shù)據(jù)丟失。
在保存快照時,Redis服務器會阻塞,可能對系統(tǒng)性能造成影響。
「2. AOF日志(Append-Only File):」AOF日志是一種追加式持久化方式,它記錄了每個寫操作命令,以追加的方式將命令寫入AOF文件。通過重新執(zhí)行AOF文件中的命令,可以重建出數(shù)據(jù)在內(nèi)存中的狀態(tài)。AOF日志提供了更精確的持久化,適用于需要更高數(shù)據(jù)安全性和實時性的場景。
「優(yōu)點:」
AOF日志可以實現(xiàn)更精確的數(shù)據(jù)持久化,每個寫操作都會被記錄。
在AOF文件中,數(shù)據(jù)可以更好地恢復,因為它保存了所有的寫操作歷史。
AOF日志適用于需要實時恢復數(shù)據(jù)的場景,如秒級數(shù)據(jù)恢復要求。
「缺點:」
AOF日志相對于RDB快照來說,可能會占用更多的磁盤空間,因為它是記錄每個寫操作的文本文件。
AOF日志在恢復大數(shù)據(jù)集時可能會比RDB快照慢,因為需要逐條執(zhí)行寫操作。
根據(jù)不同的需求,可以選擇RDB快照、AOF日志或兩者結合使用。你可以根據(jù)數(shù)據(jù)的重要性、恢復速度要求以及磁盤空間限制來選擇合適的持久化方式。有時候,也可以通過同時使用兩種方式來提供更高的數(shù)據(jù)保護級別。
AOF日志是如何實現(xiàn)的
首先,大家要知道,AOF是寫后日志,“寫后”的意思是Redis先執(zhí)行命令,把數(shù)據(jù)寫入內(nèi)存,然后才記錄日志,如下圖所示:
AOF 為什么要先執(zhí)行命令再記日志呢
AOF(Append-Only File)持久化機制中,為什么要先執(zhí)行命令再記錄日志,而不是相反,這涉及到數(shù)據(jù)的一致性和持久性。
AOF的設計目標之一是保證數(shù)據(jù)的持久性,即在服務器重啟后能夠恢復出與重啟前一致的數(shù)據(jù)狀態(tài)。為了實現(xiàn)這個目標,AOF的操作順序非常重要。
「先執(zhí)行命令再記錄日志的原因:」
「數(shù)據(jù)一致性:」 如果先記錄日志再執(zhí)行命令,假設記錄日志成功而執(zhí)行命令失?。ɡ绶掌鞅罎ⅲ?,那么日志中記錄的操作實際上沒有被應用,會導致數(shù)據(jù)在重啟后與預期不一致。
「可恢復性:」 先執(zhí)行命令再記錄日志可以保證在服務器重啟后,即使在崩潰前未能將操作記錄到日志中,也可以通過重新執(zhí)行AOF日志中的命令,將數(shù)據(jù)恢復到正確的狀態(tài)。
「避免日志丟失:」 如果先記錄日志再執(zhí)行命令,如果在記錄日志之前發(fā)生了服務器崩潰,會導致操作丟失,而這些操作可能已經(jīng)影響了數(shù)據(jù)的一致性。
當然,這里面還有一個非常重要的原因,「它是在命令執(zhí)行后才記錄日志,所以不會阻塞當前的寫操作」。
因此,為了確保數(shù)據(jù)的持久性和一致性,Redis選擇了先執(zhí)行命令再記錄日志的方式。這樣可以保證只有在操作真正成功執(zhí)行后,才會將操作記錄到AOF日志中,從而在服務器重啟后能夠準確地重放這些操作,保持數(shù)據(jù)的正確性。
AOF日志里面記錄了什么內(nèi)容呢
AOF(Append-Only File)日志記錄了每個寫操作命令,以追加的方式將命令寫入AOF文件。這些寫操作命令被以一種協(xié)議格式(通常是RESP協(xié)議)寫入AOF文件,以文本形式保存。下面是AOF日志中記錄的內(nèi)容示例:
假設執(zhí)行了以下操作:
SET?key1?value1
INCR?key2
LPUSH?list1?item1
對應的AOF日志內(nèi)容可能是:
*3\r\n$3\r\nSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n
*2\r\n$4\r\nINCR\r\n$4\r\nkey2\r\n
*3\r\n$5\r\nLPUSH\r\n$5\r\nlist1\r\n$5\r\nitem1\r\n
在這個示例中,每個寫操作都以RESP協(xié)議格式記錄在AOF文件中,以一系列字節(jié)數(shù)組來表示命令和參數(shù)。每個寫操作的記錄由多行組成,以\r\n分隔。
*3
:表示命令參數(shù)的個數(shù)為3。$3\r\nSET\r\n
:表示第一個參數(shù)為長度為3的字符串 "SET"。$4\r\nkey1\r\n
:表示第二個參數(shù)為長度為4的字符串 "key1"。$6\r\nvalue1\r\n
:表示第三個參數(shù)為長度為6的字符串 "value1"。
這樣的記錄方式允許在AOF文件中按照操作的順序逐條重放寫操作命令,從而實現(xiàn)數(shù)據(jù)在服務器重啟后的恢復。由于AOF記錄的是寫操作命令本身,所以在執(zhí)行AOF文件中的命令時,可以完全還原數(shù)據(jù)的狀態(tài)。
AOF日志潛在的問題
AOF(Append-Only File)寫日志是Redis的持久化機制之一,它記錄了每個寫操作命令,以追加的方式將命令寫入AOF文件。盡管AOF具有許多優(yōu)點,但也存在一些風險和潛在的問題,需要注意和管理:
「1. 磁盤IO開銷:」AOF日志以追加寫入方式工作,每次寫入操作都會直接追加到AOF文件末尾。這意味著頻繁的寫入操作可能會導致磁盤IO開銷增加,可能會影響系統(tǒng)的性能和響應時間。
「2. 磁盤空間占用:」AOF日志記錄的是每個寫操作命令本身,相比于RDB快照,AOF文件可能會更大。如果寫入操作頻繁,AOF文件可能會不斷增大,占用過多的磁盤空間。
「3. 數(shù)據(jù)一致性:」盡管AOF的先執(zhí)行命令再記錄日志的機制保證了數(shù)據(jù)一致性,但如果在記錄日志前發(fā)生服務器崩潰,尚未記錄的操作可能會丟失,可能導致數(shù)據(jù)一致性問題。
「4. AOF文件損壞:」由于AOF文件是以文本格式記錄的命令,如果AOF文件在寫入或存儲過程中受到損壞,可能導致數(shù)據(jù)恢復時出現(xiàn)問題,甚至無法正確恢復數(shù)據(jù)。
「5. AOF重寫耗時:」AOF重寫是為了減小AOF文件的大小,但它是一個耗時的操作,可能會對系統(tǒng)性能產(chǎn)生影響,尤其是在大數(shù)據(jù)集的情況下。
「6. AOF重寫可能引發(fā)的問題:」AOF重寫過程中可能會因為各種原因導致數(shù)據(jù)丟失,例如中斷的重寫過程、文件系統(tǒng)問題等。在執(zhí)行AOF重寫時,需要謹慎對待,確保數(shù)據(jù)的完整性。
「7. AOF文件合并:」在一些場景下,可能需要將多個AOF文件合并成一個,這樣的操作需要小心處理,以避免數(shù)據(jù)丟失或錯誤。
「8. 硬件故障:」雖然AOF可以提供持久性保證,但硬件故障(例如磁盤故障)可能會導致AOF文件丟失或損壞,需要適當?shù)膫浞莺突謴筒呗浴?/p>
為了減輕AOF寫日志帶來的風險,可以采取一些措施,如選擇適當?shù)腁OF同步策略、定期備份AOF文件、監(jiān)控AOF文件的大小和狀態(tài)、定期執(zhí)行AOF重寫、備份數(shù)據(jù)等。這些策略可以幫助減少潛在的問題,并提高系統(tǒng)的可靠性。
AOF日志三種寫回策略
AOF(Append-Only File)持久化機制在Redis中有三種不同的寫回(sync)策略,用于控制何時將AOF緩沖區(qū)中的寫入操作刷新到磁盤上的AOF文件。這些策略決定了AOF日志的同步頻率,影響了數(shù)據(jù)的持久性和性能。以下是這三種寫回策略:
「1. always(始終同步):」在這個策略下,每次執(zhí)行寫入操作之后,Redis都會立即將寫入操作刷新到磁盤,確保寫入操作已經(jīng)持久化。雖然這種方式能夠提供最高的數(shù)據(jù)保證,但也是性能開銷最大的一種方式,因為每次寫入操作都會引起磁盤IO。
「優(yōu)點:」
最高的數(shù)據(jù)保證,即使系統(tǒng)崩潰,也只會丟失上一個寫入操作。
「缺點:」
性能開銷較大,頻繁的磁盤IO可能影響系統(tǒng)的性能和響應時間。
「2. everysec(每秒同步):」在這個策略下,Redis會每秒一次將AOF緩沖區(qū)中的寫入操作批量刷新到磁盤上的AOF文件。這樣可以在一定程度上平衡數(shù)據(jù)保證和性能。
「優(yōu)點:」
較高的數(shù)據(jù)保證,每秒一次的同步保證了不會丟失過多的寫入操作。
性能開銷相對較低,因為是每秒一次的批量刷新。
「缺點:」
在一秒內(nèi)的操作可能會丟失。
「3. no(不同步):」這個策略下,Redis不會主動將AOF緩沖區(qū)中的寫入操作刷新到磁盤,而是由操作系統(tǒng)來決定何時將數(shù)據(jù)寫入磁盤。這是性能開銷最小的方式,但數(shù)據(jù)持久性相對較低。
「優(yōu)點:」
最小的性能開銷,幾乎不會影響系統(tǒng)的響應時間。
最高的性能表現(xiàn),寫入操作不會導致頻繁的磁盤IO。
「缺點:」
數(shù)據(jù)持久性較低,如果系統(tǒng)崩潰,可能會丟失多個寫入操作。
選擇合適的AOF寫回策略取決于數(shù)據(jù)的重要性和性能需求。如果數(shù)據(jù)安全性最為重要,可以選擇always
策略。如果在數(shù)據(jù)一致性和性能之間需要平衡,可以選擇everysec
策略。如果對性能要求較高,而可以接受一定程度的數(shù)據(jù)丟失,可以選擇no
策略。根據(jù)實際情況,可以根據(jù)需求來配置AOF的寫回策略。
這里呢給大家總結一下各種配置的優(yōu)缺點
日志文件太大了怎么辦
AOF(Append-Only File)重寫是為了減小AOF文件的大小,避免AOF文件不斷增大導致的磁盤空間占用問題。AOF重寫是一種以全量的方式生成新的AOF文件,其中記錄的是一個數(shù)據(jù)集的寫入操作,這個數(shù)據(jù)集的大小通常比原始AOF文件小很多。
AOF重寫的工作原理如下:
「觸發(fā)重寫:」AOF重寫可以手動觸發(fā),也可以根據(jù)配置自動觸發(fā)。當滿足一定條件(例如AOF文件大小超過指定百分比或最小大?。r,Redis會啟動AOF重寫過程。
「后臺進程啟動:」當AOF重寫觸發(fā)時,Redis會啟動一個子進程,這個子進程會負責執(zhí)行AOF重寫操作。
「創(chuàng)建數(shù)據(jù)集快照:」在子進程中,Redis會創(chuàng)建一個數(shù)據(jù)集的內(nèi)存快照,即內(nèi)存中數(shù)據(jù)在某個時間點的快照。
「遍歷數(shù)據(jù)集:」子進程開始遍歷數(shù)據(jù)集中的鍵,并將寫操作轉換成命令序列。
「生成新AOF文件:」子進程會將遍歷期間生成的命令序列追加到新的AOF文件中,這個新文件是緊湊的,只包含了數(shù)據(jù)集在某個時間點的寫入操作。
「替換原AOF文件:」當新的AOF文件生成完成后,子進程會將原始的AOF文件替換為新的AOF文件。這一步通常很快,因為新的AOF文件相對較小。
「主線程繼續(xù)服務:」在AOF重寫過程中,主線程仍然可以繼續(xù)處理客戶端請求,響應讀取操作等,不會被阻塞。
AOF重寫的優(yōu)勢在于它可以生成一個更小、更緊湊的AOF文件,避免了不斷增大的AOF文件所帶來的磁盤空間和讀寫開銷。此外,新的AOF文件只包含了寫入操作,沒有之前的讀操作,因此它在恢復數(shù)據(jù)時不需要考慮之前的讀操作。
AOF重寫可以通過多種方式觸發(fā):
手動觸發(fā):可以使用
BGREWRITEAOF
命令手動觸發(fā)AOF重寫。自動觸發(fā):可以通過設置
auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
來自動觸發(fā)AOF重寫。當AOF文件大小達到指定的百分比或最小大小時,Redis會自動啟動AOF重寫。
需要注意的是,AOF重寫是一個資源密集型操作,可能會影響系統(tǒng)的性能,特別是在大數(shù)據(jù)集的情況下。因此,在進行AOF重寫時,應該考慮其對系統(tǒng)性能的影響,并確保系統(tǒng)具備足夠的資源來執(zhí)行重寫操作。 下面舉例說明一下:
這里大家能看到,經(jīng)過優(yōu)化后,AOF日志文件會縮小很多,但是,要把整個數(shù)據(jù)庫的最新數(shù)據(jù)的操作日志都寫回磁盤,仍然是一個非常耗時的過程。這時,我們就要繼續(xù)關注另一個問題了。
重寫會不會阻塞主線程?
AOF重寫不會阻塞Redis的主線程。Redis的AOF重寫是作為一個后臺進程(子進程)來執(zhí)行的,不會影響主要的服務線程。
AOF重寫過程中,Redis會創(chuàng)建一個子進程來遍歷數(shù)據(jù)集,將寫操作轉換為命令序列,并生成新的AOF文件。主線程仍然可以繼續(xù)處理客戶端請求,響應讀取操作等。
這種設計使得Redis能夠在不中斷服務的情況下執(zhí)行AOF重寫,從而減少對系統(tǒng)的影響。但需要注意的是,雖然AOF重寫不會阻塞主線程,但它仍然是一個資源密集型操作,可能會占用較多的CPU和內(nèi)存資源,因此在進行AOF重寫時,需要考慮系統(tǒng)的資源情況,避免影響其他業(yè)務操作。
RDB快照是如何實現(xiàn)的?
RDB(Redis DataBase)是Redis的一種持久化機制,用于將數(shù)據(jù)從內(nèi)存中保存到磁盤上,以便在服務器重啟時恢復數(shù)據(jù)。RDB通過創(chuàng)建一個快照(Snapshot)來保存數(shù)據(jù)庫在某個時間點的數(shù)據(jù)狀態(tài),然后將這個快照保存到磁盤上的一個二進制文件中。
「RDB的實現(xiàn)過程:」
「創(chuàng)建快照:」當RDB持久化被觸發(fā)時(可以手動觸發(fā)或根據(jù)配置自動觸發(fā)),Redis會生成一個數(shù)據(jù)集的內(nèi)存快照。這個快照包含了數(shù)據(jù)庫在某個時間點的所有鍵值對以及相關的數(shù)據(jù)結構信息。
「快照數(shù)據(jù)序列化:」在創(chuàng)建快照后,Redis會將快照中的數(shù)據(jù)進行序列化,將鍵、值、過期時間等信息按照一定的格式編碼成二進制數(shù)據(jù)。
「保存到文件:」將序列化后的數(shù)據(jù)保存到磁盤上的RDB文件中。RDB文件的擴展名通常為
.rdb
。「持久化完成:」一旦RDB文件保存完成,持久化過程結束。這個RDB文件包含了數(shù)據(jù)庫在快照時間點的完整數(shù)據(jù)狀態(tài)。
「RDB的優(yōu)缺點:」
「優(yōu)點:」
「緊湊的數(shù)據(jù)格式:」 RDB文件是一個二進制文件,采用了緊湊的編碼格式,因此在磁盤上占用的空間相對較小。
「快速恢復:」 在恢復數(shù)據(jù)時,通過加載RDB文件,可以快速地將數(shù)據(jù)恢復到指定時間點的狀態(tài)。
「適用于備份和恢復:」 RDB文件適用于進行數(shù)據(jù)備份、遷移和災難恢復,可以方便地復制到其他服務器上。
「缺點:」
「數(shù)據(jù)丟失:」 由于RDB是周期性的全量持久化,可能會導致某個時間點之后的數(shù)據(jù)丟失。
「IO開銷:」 RDB持久化時,需要將整個數(shù)據(jù)集寫入磁盤,可能在大數(shù)據(jù)集上引起IO開銷,影響性能。
「耗時:」 在生成RDB快照的過程中,如果數(shù)據(jù)集很大,可能會占用較多的CPU資源,導致短時間內(nèi)的性能下降。
總的來說,RDB持久化適用于需要緊湊的備份和數(shù)據(jù)遷移,以及在服務器重啟時需要快速恢復數(shù)據(jù)的場景。但需要注意的是,RDB的全量持久化可能會導致某些數(shù)據(jù)的丟失,因此在選擇持久化方式時需要權衡數(shù)據(jù)的重要性和性能需求。
給哪些內(nèi)存數(shù)據(jù)做快照?
在RDB持久化中,Redis會對內(nèi)存中的各種數(shù)據(jù)進行快照,將數(shù)據(jù)保存到RDB文件中。這些內(nèi)存數(shù)據(jù)包括:
「字符串類型數(shù)據(jù):」 包括使用
SET
命令設置的字符串鍵值對。「哈希表(Hash):」 包括使用
HSET
、HMSET
等命令設置的哈希鍵值對。「列表(List):」 包括使用
LPUSH
、RPUSH
等命令添加的列表元素。「集合(Set):」 包括使用
SADD
等命令添加的集合元素。「有序集合(Sorted Set):」 包括使用
ZADD
等命令添加的有序集合元素。「Bitmaps、HyperLogLogs、Streams:」 包括這些特殊數(shù)據(jù)類型的內(nèi)容。
「過期時間:」 快照會記錄每個鍵的過期時間,以便在恢復數(shù)據(jù)時進行過期判斷。
「數(shù)據(jù)庫配置:」 包括數(shù)據(jù)庫的配置信息,如數(shù)據(jù)庫編號、鍵空間的選項等。
「服務器信息:」 包括服務器的信息,如版本號、運行模式等。
「客戶端連接信息:」 包括客戶端連接的信息。
需要注意的是,RDB持久化是一種全量持久化機制,它會在某個時間點生成一個數(shù)據(jù)庫的快照,將所有內(nèi)存中的數(shù)據(jù)保存到RDB文件中。這種方式有一些優(yōu)點,如緊湊的數(shù)據(jù)格式和快速恢復,但也有缺點,如可能造成數(shù)據(jù)丟失和IO開銷。在選擇使用RDB持久化時,需要權衡這些優(yōu)缺點,根據(jù)業(yè)務需求來確定是否適合使用。
哪些命令能生成RDB文件?
RDB文件是通過執(zhí)行持久化操作來生成的,而不是通過特定的命令來生成。在Redis中,可以手動觸發(fā)RDB持久化操作,也可以根據(jù)配置自動觸發(fā)。以下是生成RDB文件的方式:
「手動觸發(fā):」使用
SAVE
命令可以手動觸發(fā)RDB持久化操作,該命令會「阻塞服務器」的主線程,直到RDB文件生成完成為止。這個命令適合用于測試或緊急情況下的數(shù)據(jù)備份。示例:
SAVE
「后臺觸發(fā):」使用
BGSAVE
命令可以在后臺觸發(fā)RDB持久化操作,這個命令會派生一個子進程來執(zhí)行RDB持久化,「不會阻塞服務器」的主線程。這是比較常用的生成RDB文件的方式。示例:
BGSAVE
「自動觸發(fā):」可以通過配置文件中的參數(shù)來自動觸發(fā)RDB持久化操作。在配置文件(redis.conf)中可以設置
save
參數(shù),用于指定在何時執(zhí)行RDB持久化操作,例如:save?900?1
save?300?10
save?60?10000這表示當900秒內(nèi)至少發(fā)生1次寫操作、300秒內(nèi)至少發(fā)生10次寫操作、60秒內(nèi)至少發(fā)生10000次寫操作時,自動觸發(fā)BGSAVE命令。
無論是手動觸發(fā)還是后臺觸發(fā),RDB持久化操作都會生成一個RDB文件,其中包含了內(nèi)存中的數(shù)據(jù)快照。需要注意的是,RDB持久化是一個資源密集型操作,可能會影響服務器的性能,特別是在數(shù)據(jù)集較大的情況下。因此,在選擇何時執(zhí)行RDB持久化時,需要根據(jù)業(yè)務需求和性能要求做出權衡。
快照時數(shù)據(jù)能修改嗎?
這里大家可能會想到bgsave
命令避免阻塞。這里大家可能會有誤區(qū),「避免阻塞和正常處理讀寫請求并不是一回事」。此時,主線程確實沒有阻塞,可以正常接收請求,但是,為了保證快照完整性,它只能處理讀操作,因為不能修改正在執(zhí)行快照的數(shù)據(jù)。
那么Redis是如何解決這個問題的呢?
實際上,Redis 6.0 版本引入了「寫時復制(Copy-On-Write,COW)技術」來保證在執(zhí)行快照(RDB)時數(shù)據(jù)是可修改的。這個特性被稱為 "RDB快照時復制"(RDB Snapshotting)。
在 Redis 6.0 中,當進行 RDB 快照持久化時,Redis 會執(zhí)行以下步驟來確保數(shù)據(jù)可修改:
Redis 創(chuàng)建一個子進程。
在子進程中,將內(nèi)存中的數(shù)據(jù)進行寫時復制,創(chuàng)建出一個副本,而不會影響主進程的數(shù)據(jù)。
子進程將副本數(shù)據(jù)寫入 RDB 文件,這個過程是在子進程的上下文中執(zhí)行的,不會影響主進程。
這個操作在實際執(zhí)行過程中,是子進程復制了主線程的頁表,所以通過頁表映射,能讀到主線程的原始數(shù)據(jù),而當有新數(shù)據(jù)寫入或數(shù)據(jù)修改時,主線程會把新數(shù)據(jù)或修改后的數(shù)據(jù)寫到一個新的物理內(nèi)存地址上,并修改主線程自己的頁表映射。所以,子進程讀到的類似于原始數(shù)據(jù)的一個副本,而主線程也可以正常進行修改。
因此,RDB 快照時,主進程仍然可以繼續(xù)處理寫操作,而子進程則負責將數(shù)據(jù)寫入 RDB 文件。這樣,寫時復制技術確保了在生成 RDB 快照期間,數(shù)據(jù)是可修改的,同時保持了數(shù)據(jù)的一致性。
需要注意的是,這種特性僅適用于 Redis 6.0 及以上版本,并且在 RDB 快照時起作用。在生成 AOF 文件時,Redis 仍然會阻塞主線程以確保數(shù)據(jù)一致性。
可以每秒做一次快照嗎
雖然理論上可以每秒鐘做一次快照(RDB持久化),但實際上這樣做可能會對Redis服務器的性能產(chǎn)生顯著的影響,特別是在負載較重的情況下。
每秒鐘生成快照會引起以下一些問題:
「性能開銷:」 快照操作需要遍歷內(nèi)存中的所有數(shù)據(jù),并將數(shù)據(jù)序列化到磁盤中。頻繁的快照操作會占用大量的CPU和內(nèi)存資源,影響服務器的性能,導致響應時間變長。
「IO壓力:」 每秒鐘生成的快照會導致頻繁的磁盤寫入,增加了磁盤IO的負擔,可能影響其他應用程序和操作系統(tǒng)的正常運行。
「數(shù)據(jù)丟失:」 每秒鐘生成的快照可能會導致數(shù)據(jù)丟失,因為生成快照的操作需要一定的時間,如果在兩次快照之間發(fā)生了寫操作,那么這段時間內(nèi)的數(shù)據(jù)會丟失。
通常情況下,每秒鐘生成快照并「不是一個推薦的做法」。更合理的做法是根據(jù)業(yè)務需求和系統(tǒng)資源來選擇合適的持久化頻率。如果數(shù)據(jù)的一致性要求很高,可以考慮使用AOF持久化機制,它可以在不同程度上提供數(shù)據(jù)的保護和持久性,而且可以通過設置不同的寫回策略來平衡性能和數(shù)據(jù)保護。如果數(shù)據(jù)的一致性要求相對較低,可以選擇適當?shù)腞DB持久化頻率,避免頻繁的IO和性能開銷。
為什么推薦AOF和RDB混合使用
推薦在Redis中同時使用AOF(Append-Only File)持久化和RDB(Redis DataBase)持久化的原因是,這兩種持久化機制可以相互補充,提供更好的數(shù)據(jù)保護、恢復能力和性能優(yōu)化。
以下是推薦同時使用AOF和快照的主要原因:
「數(shù)據(jù)恢復能力:」 AOF持久化記錄了所有寫操作的日志,這使得在發(fā)生意外情況時(如服務器崩潰)可以精確地恢復數(shù)據(jù)到崩潰前的狀態(tài)。而RDB持久化通過全量快照提供了快速的數(shù)據(jù)恢復能力。結合使用兩者,可以在AOF日志的基礎上,通過加載最近的RDB快照來加速恢復。
「數(shù)據(jù)安全性:」 AOF持久化記錄了每個寫操作,可以確保每個寫操作都被持久化到日志中。RDB持久化則提供了一個點對點的數(shù)據(jù)備份。同時使用這兩種持久化機制可以提供更高的數(shù)據(jù)安全性。
「性能優(yōu)化:」 AOF持久化對于讀操作的性能影響較小,因為讀操作不涉及AOF文件的寫入。而RDB持久化對于快速的全量數(shù)據(jù)恢復很有幫助。通過結合使用AOF和RDB,可以在一定程度上平衡數(shù)據(jù)保護和性能要求。
「多層次的備份:」 使用AOF和RDB,您可以獲得多層次的數(shù)據(jù)備份。AOF日志可以提供精確的操作日志,RDB快照可以提供全量備份。這樣,即使其中一個持久化機制出現(xiàn)問題,另一個仍然可以提供數(shù)據(jù)保護。
綜上所述,使用AOF和RDB兩種持久化機制的組合,能夠提供更全面的數(shù)據(jù)保護、災難恢復和性能優(yōu)化。在配置Redis持久化時,根據(jù)業(yè)務需求和性能要求,結合使用這兩種機制,可以實現(xiàn)更好的數(shù)據(jù)管理和保護。
如何配置呢
在 Redis 中,同時使用 AOF 持久化和 RDB 持久化的配置是很常見的,這樣可以兼顧數(shù)據(jù)的持久性和恢復性能。以下是一個將 AOF 持久化和 RDB 持久化混合使用的示例配置:
打開 Redis 配置文件,通常是
redis.conf
。啟用 AOF 持久化: 找到以下行并確保其被設置為以下值,以啟用 AOF 持久化:
appendonly?yes
設置 AOF 重寫策略(可選): 可以設置 AOF 重寫的觸發(fā)條件,以便控制 AOF 文件的大小和寫入頻率。例如:
auto-aof-rewrite-percentage?100
auto-aof-rewrite-min-size?64mb啟用 RDB 持久化: 默認情況下,Redis 會使用 RDB 持久化,但要確保以下行沒有被注釋掉:
save?900?1
save?300?10
save?60?10000設置 RDB 快照文件名(可選): 如果希望為 RDB 快照指定特定的文件名,可以添加以下行:
dbfilename?dump.rdb
這會將 RDB 快照文件命名為
dump.rdb
。設置 RDB 快照保存路徑(可選): 如果希望將 RDB 快照保存到特定的路徑,可以添加以下行:
dir?/path/to/rdb/directory
這會將 RDB 快照保存到指定的目錄。
重啟 Redis 服務器: 在對配置文件進行更改后,需要重新啟動 Redis 服務器,以使配置生效。
使用以上配置,Redis 將同時使用 AOF 持久化和 RDB 持久化,提供了多層次的數(shù)據(jù)保護和恢復機制。AOF 持久化記錄寫操作,提供操作日志用于數(shù)據(jù)恢復。RDB 持久化提供了全量備份,用于快速恢復整個數(shù)據(jù)集。混合使用這兩種機制可以充分利用它們各自的優(yōu)點,提供更全面的數(shù)據(jù)持久性和保護。
關于AOF和RDB的選擇,三點建議
數(shù)據(jù)不能丟失時,內(nèi)存快照和 AOF 的混合使用是一個很好的選擇;
如果允許分鐘級別的數(shù)據(jù)丟失,可以只使用 RDB;
如果只用 AOF,優(yōu)先使用 everysec 的配置選項,因為它在可靠性和性能之間取了一個平衡。