這篇文章帶大家了解一下redis中的兩種持久化機制(RDB和AOP),希望對大家有幫助!
redis是一個記憶體資料庫,資料保存在記憶體中,但是我們都知道記憶體的資料變化是很快的,也容易發生遺失。幸好Redis也為我們提供了持久化的機制,分別是RDB(Redis DataBase)和AOF(Append Only File)。 【相關推薦:Redis影片教學】
在這裡假設你已經了解了redis的基礎文法,某字母網站都有很好的教學課程,可以去看。基本使用的文章就不寫了,都是一些常用的指令。
下面針對這兩種方式來介紹一下。由淺入深。
既然redis的資料可以儲存在磁碟上,那麼這個流程是什麼樣的呢?
要有下面五個過程:
(1)客戶端向服務端發送寫入操作(資料在客戶端的記憶體中)。
(2)資料庫服務端接收到寫入請求的資料(資料在服務端的記憶體中)。
(3)服務端調用write這個系統調用,將資料往磁碟上寫(資料在系統記憶體的緩衝區中)。
(4)作業系統將緩衝區中的資料轉移到磁碟控制器上(資料在磁碟快取中)。
(5)磁碟控制器將資料寫到磁碟的實體媒體中(資料真正落到磁碟上)。
這5個過程是在理想條件下一個正常的保存流程,但是在大多數情況下,我們的機器等等都會有各種各樣的故障,這裡劃分了兩種情況:
(1)Redis資料庫發生故障,只要在上面的第三步執行完畢,那麼就可以持久化保存,剩下的兩步由作業系統替我們完成。
(2)作業系統發生故障,必須上面5步驟都完成才可以。
在這裡只考慮了保存的過程可能發生的故障,其實保存的資料也有可能發生損壞,需要一定的恢復機制,不過在這裡就不再延伸了。現在主要考慮的是redis如何來實現上面5個保存磁碟的步驟。它提供了兩種策略機制,也就是RDB和AOF。
RDB其實就是把資料以快照的形式保存在磁碟上。什麼是快照呢,你可以理解成把當下時刻的資料拍成一張照片保存下來。
RDB持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟。也是預設的持久化方式,這種方式是就是將記憶體中資料以快照的方式寫入到二進位檔案中,預設的檔案名稱為dump.rdb。
在我們安裝了redis之後,所有的設定都是在redis.conf檔中,裡面保存了RDB和AOF兩種持久化機制的各種設定。
既然RDB機制是透過把某個時刻的所有資料產生一個快照來保存,那麼就應該有一個觸發機制,就是實現這個過程。對RDB來說,提供了三種機制:save、bgsave、自動化。我們分別來看
1、save觸發方式
#該指令會阻塞目前Redis伺服器,執行save指令期間,Redis無法處理其他指令,直到RDB過程完成為止。具體流程如下:
執行完成時候如果存在舊的RDB文件,就把新的替換掉舊的。我們的客戶端可能都是幾萬或幾十萬,這種方式顯然不可取。
2、bgsave觸發方式
執行該指令時,Redis會在背景非同步進行快照操作,快照同時也能回應客戶端請求。具體流程如下:
具體操作是Redis進程執行fork操作建立子進程,RDB持久化過程由子進程負責,完成後自動結束。阻塞只發生在fork階段,一般時間很短。基本上 Redis 內部所有的RDB操作都是採用 bgsave 指令。
3、自動觸發
自動觸發是由我們的設定檔來完成的。在redis.conf設定檔中,裡面有以下配置,我們可以去設定:
①save:這裡是用來設定觸發Redis的RDB 持久化條件,也就是何時將記憶體中的資料儲存到硬碟.如“save m n”。表示m秒內資料集存在n次修改時,自動觸發bgsave。
預設如下配置:
#表示900 秒內如果至少有1 個key 的值變化,則保存save 900 1#表示300 秒內如果至少有10 個key 的值變化,則保存save 300 10#表示60 秒內如果至少有10000 個key 的值變化,則儲存save 60 10000
不需要持久化,那麼你可以註解掉所有的save 行來停用儲存功能。
②stop-writes-on-bgsave-error :預設值為yes。當啟用了RDB且最後一次後台儲存資料失敗,Redis是否停止接收資料。這會讓使用者意識到資料沒有正確持久化到磁碟上,否則沒有人會注意到災難(disaster)發生了。如果Redis重啟了,那麼又可以重新開始接收資料了
③rdbcompression ;預設值是yes。對於儲存到磁碟中的快照,可以設定是否進行壓縮儲存。
④rdbchecksum :預設值是yes。在儲存快照後,我們也可以讓redis使用CRC64演算法來進行資料校驗,但是這樣做會增加大約10%的效能消耗,如果希望取得最大的效能提升,可以關閉此功能。
⑤dbfilename :設定快照的檔案名,預設是 dump.rdb
⑥dir:設定快照檔案的存放路徑,這個設定項一定是目錄,而不能是檔案名稱。
我們可以修改這些配置來實現我們想要的效果。因為第三種方式是配置的,所以我們對前兩種做一個比較:
4、RDB 的優點和缺點
①、優勢
(1)RDB檔案緊湊,全量備份,非常適合用於進行備份和災難復原。
(2)產生RDB檔案的時候,redis主程序會fork()一個子程序來處理所有保存工作,主程序不需要進行任何磁碟IO操作。
(3)RDB 在恢復大資料集時的速度比 AOF 的復原速度還要快。
②、劣勢
RDB快照是一次全量備份,儲存的是記憶體資料的二元序列化形式,儲存上非常緊湊。當進行快照持久化時,會開啟一個子進程專門負責快照持久化,子進程會擁有父進程的內存數據,父進程修改內存子進程不會反應出來,所以在快照持久化期間修改的數據不會被保存,可能丟失資料。
全量備份總是耗時的,有時候我們提供更有效率的方式AOF,工作機制很簡單,redis會將每一個收到的寫入指令都透過write函數追加到檔案中。通俗的理解就是日誌記錄。
1、持久化原理
他的原理看下面這張圖:
每當有一個寫指令過來時,就直接保存在我們的AOF檔中。
2、檔案重寫原則
AOF的方式也同時帶來了另一個問題。持久化文件會變的越來越大。為了壓縮aof的持久化檔。 redis提供了bgrewriteaof指令。將記憶體中的資料以指令的方式儲存到暫存檔案中,同時會fork出一條新進程來將檔案重寫。
重寫aof文件的操作,並沒有讀取舊的aof文件,而是將整個記憶體中的資料庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點類似。
3、AOF也有三種觸發機制
(1)每修改同步always:同步持久化每次發生資料變更會被立即記錄到磁碟效能較差但資料完整性比較好
(2)每秒同步everysec:非同步操作,每秒記錄如果一秒內宕機,有資料遺失
( 3)不同no:從不同步
4、優點
(1)AOF可以更好的保護資料不遺失,一般AOF會每隔1秒,透過一個後台執行緒執行一次fsync操作,最多遺失1秒鐘的資料。 (2)AOF日誌檔案沒有任何磁碟尋址的開銷,寫入效能非常高,檔案不容易破損。
(3)AOF日誌檔案即使過大的時候,出現後台重寫操作,也不會影響客戶端的讀寫。
(4)AOF日誌檔案的命令透過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急復原。例如某人不小心用flushall指令清空了所有數據,只要這個時候後台rewrite還沒發生,那麼就可以立即拷貝AOF文件,將最後一條flushall指令給刪了,然後再將該AOF文件放回去,就可以透過恢復機制,自動恢復所有資料
5、缺點
#(1)對於同一份資料來說,AOF日誌檔案通常比RDB資料快照檔案更大
(2)AOF開啟後,支援的寫入QPS會比RDB支援的寫入QPS低,因為AOF一般會配置成每秒fsync一次日誌文件,當然,每秒一次fsync,性能也還是很高的
(3)以前AOF發生過bug,就是透過AOF記錄的日誌,進行數據恢復的時候,沒有恢復一模一樣的資料出來。
選擇的話,兩者加一起才會更好。因為兩個持久化機制你明白了,剩下的就是看自己的需求了,需求不同選擇的也不一定,但是通常都是結合使用。有一張圖可供總結:
比較了這幾個特性,剩下的就是看自己了。
更多程式相關知識,請造訪:程式設計影片! !
以上是一文了解redis中RDB和AOP持久化的詳細內容。更多資訊請關注PHP中文網其他相關文章!