Redis持久化

NO IMAGE

我們知道,redis是基於內存的,也就是說數據在內存中,這也是為什麼redis這麼快的原因之一。但是當redis重啟了,內存中的數據就會丟失。所以,redis就有持久化的機制。它提供兩種方式的持久化:

  1. RDB
  2. AOF

前者根據指定的規則‘定時’將內存中的數據存儲在硬盤中。後者在每次執行寫命令後將命令本身記錄下來。

RDB方式

當符合一定的條件的時候,redis會自動將內存中的所有數據生成一個副本並存儲在硬盤上。這個過程被稱為‘快照’。

根據配置規則進行自動快照

在配置文件redis.conf中, 配置save如下例:

save 900 1
save 300 10
save 60 10000

意思是:900s內,至少有一個key被更改則進行異步快照;300s內至少有10個key被更改;60s內至少有10000個key。

執行SAVE或者BGSAVE命令

SAVE命令,使redis同步進行快照,會阻塞來自客戶端的請求。不推薦

BGSAVE命令,在後臺異步進行快照,可以相應客戶端請求。執行BGSAVE會立刻返回ok,表示開始執行快照操作,如果想要知道快照是否完成,通過LASTSAVE命令,獲取最近一次成功執行快照的時間,返回unix時間戳。

快照過程

redis默認會將快照文件存儲在redis工作目錄的dump.rdb文件中。過程如下:

  1. redis使用fork函數複製一份當前進程的子進程;
  2. 父進程繼續處理客戶端發來的請求,子進程開始將內存中的數據寫入硬盤中的臨時文件
  3. 當子進程寫入完所有的數據後會用該臨時文件替換舊的rdb文件,本次快照完成。

注意:
當fork函數發生的一刻,父子進程共享同一內存數據,當父進程要更改其中某片數據時,操作系統會將該片數據複製一份,以保持子進程的數據不受影響,所以新的rdb文件存儲的是fork一刻的內存數據。

rdb文件是經過壓縮的二進制格式。

以上,可以看到這種方式的持久化明顯存在缺陷。當redis異常退出,就會丟失最後一次快照以後的更改。如果數據相對重要,就要使用AOF方式了。

AOF方式

這種方式將所有的寫命令追加到硬盤文件中,這個過程會降低redis的性能,但是大部分情況下這個影響是可以接受的,另外使用較快的硬盤可以提高AOF的性能。

默認情況redis是沒有開啟AOF的,可以通過appendonly參數啟用:

appendonly yes

aof文件和rdb文件的位置相同,默認文件名是appendonly.aof,可以通過appendfilename參數修改:

appendfilename XXX.aof

AOF文件的重寫

比如我們有兩條寫命令:

set foo 1
set foo 2
set foo 3

明顯,前面兩條都是沒用的。這時候我們希望優化aof文件。

可以在配置文件redis.conf裡面配置:

auto-aof-rewrite-percentage 100
aotu-aof-rewrite-min-size 64mb

auto-aof-rewrite-percentage意思是當目前的aof文件大小超過上次重寫時的aof文件大小的百分之多少時,會再次自動重寫,如果之前沒有重寫過,則以啟動時的aof文件大小為依據。

aotu-aof-rewrite-min-size限制了允許自動重寫的最小aof文件大小,通常在aof文件太小的時候我們並不關心。

此外還可以手動重寫:

BGREWRITEAOF

重寫的過程只和內存中的數據有關,和舊的aof文件無關。

相關文章

函數式編程在前端權限管理中的應用

React源碼Scheduler(三)React的調度算法實現

React源碼Scheduler(二)React的調度流程

React源碼Scheduler(一)瀏覽器的調度