關於Redis兩種持久化方式的說明
在說Redis持久化之前,需要搞明白什麼是資料庫狀態這個概念,因為持久化的就是將記憶體中的資料庫狀態儲存到磁碟上。那麼什麼是資料庫狀態呢?Redis是一個key-value資料庫伺服器,一般預設是有16個資料庫,可以使用select <index>命令進行切換(0-15),這每個非空的資料庫又可以包含任意多個索引值對,為了方便起見,我們將資料庫伺服器中的非空資料庫以及它們的索引值對通常為【資料庫狀態】,所以這裡持久化,說的不是一個資料庫,而是伺服器上的所有非空資料庫。
接著,我們繼續來說redis的兩種持久化方式,一種是RDB持久化,一種是AOF持久化,這兩種持久化方式都可以將記憶體中的資料庫狀態儲存到磁碟上,但是原理非常不同,我們逐一來看看,首先說一下RDB持久化。
RDB持久化預設產生的檔案名稱為dump.rdb,這個可以通過設定檔配置,RDB檔案一個經過壓縮的二進位檔案,接下來介紹一些rdb檔案結構,RDB檔案包含五個部分,分別是【Redis | db_version | databases | EOF | check_sum】開頭的Redis表示這是一個RDB檔案,伺服器可以通過這個快速檢查載入的檔案是否是rdb檔案,db_version是一個整數,代表RDB檔案的版本,databases部分包含0個或者是任意多個資料庫,以及資料庫中的索引值對資料,如果資料庫狀態是空,那麼這部分也是空的,這部分的結構如下【SELECTDB | db_number | key_values_pairs】其中SELECTDB是一個常量,長度是一位元組,當伺服器遇到這個的時候,知道接下來要讀入的將是一個資料庫號碼,db_number中儲存的是一個資料庫號碼(0-15)這兩部分結合就可以切換到相應的資料庫,然後讀取索引值對了,索引值對的部分的結構有兩種,一種是帶到期值的,一種是不帶到期值的,如果是帶到期值,那麼結構是【EXPIRETIME_MS | ms | TYPE | key | value】第一個常量和SELECTDB一樣,第二部分是毫秒為單位的UNIX時間戳記,就是索引值對的到期時間,然後是TYPE記錄了value的類型,是String,list,set,zset,hash,等。不帶到期值的索引值對部分的結構沒有前兩部分,只是【TYPE | key | value】
RDB持久化可以通過命令進行手動執行,也可以配置好後讓伺服器自動執行,手動執行可以使用Redis命令【SAVE】或者【BGSAVE】,這兩個命令有一些差別,需要說明一下,save命令會阻塞伺服器處理序,也就說,但save命令執行的時候伺服器不能夠處理任何命令請求,知道save命令執行完畢,RDB檔案建立完畢,bgsave命令不會阻塞伺服器,而是通過派生出一個子進程,然後由子進程負責建立RDB檔案,伺服器處理序繼續處理命令請求,這裡需要說明一下,bgsave處理期間,伺服器處理序雖然能夠繼續處理命令請求,但是save,bgsave,bgrewriteaof這三個命令的處理方式會和平時有所不同,在bgsave期間,save命令會被伺服器拒絕,伺服器禁止save和bgsave同時執行,避免父進程和子進程同時執行兩個rdbSave(建立RDB檔案的實際工作實際上是由rdbSave函數完成,save和bgsave都會調用這個函數,只是調用的方式不同)調用,bgsave命令在bgsave期間也會被拒絕,理由和拒絕save的理由一樣,兩個bgsave也會產生競爭,bgrewriteaof命令會被延遲到bgsave執行完畢之後執行。
Redis沒有專門的RDB檔案載入命令,只要Redis伺服器開啟,就會檢測RDB檔案是否存在,就會自動載入RDB檔案,這裡需要說明一點,如果伺服器開啟了AOF持久化功能,伺服器會優先使用AOF檔案來還原資料庫狀態,只有在AOF持久化功能關閉的時候,才會使用RDB檔案來還原資料庫狀態。
接下來說一下,RDB自動儲存,前面已經說了,RDB可以通過手動執行,SAVE命令和BGSAVE命令,也可以通過配置讓伺服器自動執行,那麼如何配置呢?
Redis.conf中可以配置,預設配置如下:
save 900 1
save 300 10
save 60 10000
以上表示的意思是,
- 900秒之內對服務進行了至少一次修改
- 300秒之內伺服器進行了至少10次修改
- 60秒之內對伺服器進行了至少10000次修改。
這些條件滿足其中的任意一個bgsave命令就會自動執行。
那麼你可能會好奇,伺服器是怎麼知道我做了多少修改的?伺服器中有個dirty計數器和一個lastsave時間戳記
當伺服器執行一個資料庫修改命令之後,dirty計數器就會進行更新,命令修改了多少次資料庫,dirty就會增加多少,如:【set msg hello】修改了一個,那麼dirty就加一,如果【mset msg word name nihao age 20】那麼dirty就增加三
lastsave屬性記錄上次伺服器執行儲存操作的時間,是一個unix時間戳記,通過這兩個屬性,可以很簡單的距離上次儲存已經多少時間了,以及修改了多少次資料庫,一旦滿足以上三個條件,那麼就自動調用bgsave命令,同時更新lastsave屬性和dirty屬性歸零。
至於檢查儲存條件是否滿足這個工作,是由Redis伺服器周期性操作函數serverCron預設間隔100毫秒執行一次檢查,這個函數有很多地方用到,注意一下,這個函數是對正在啟動並執行伺服器進行維護的函數,在Redis事件中會有提到(Redis伺服器是一個事件驅動程式,什麼是事件驅動呢?就是發生事件的時候才會動一下,不然就跟死了一樣,事件驅動又分為檔案事件和時間事件,ServerCron就是一種時間驅動,至於檔案驅動,其實就是用戶端發過來一個命令,伺服器才會去執行,然後給用戶端返回結果)
最後說一點,Redis本身內建了一個RDB檔案檢查工具redis-check-dump,可以使用這個工具對rdb檔案是否完整進行檢查。
Ubuntu 14.04下Redis安裝及簡單測試
Redis叢集明細文檔
Ubuntu 12.10下安裝Redis(圖文詳解)+ Jedis串連Redis
Redis系列-安裝部署維護篇
CentOS 6.3安裝Redis
Redis安裝部署學習筆記
Redis設定檔redis.conf 詳解
Redis 的詳細介紹:請點這裡
Redis 的:請點這裡
本文永久更新連結地址: