1. 程式人生 > >redis知識盤點【叄】_持久化

redis知識盤點【叄】_持久化

因為redis是記憶體資料庫,其所有資料都是儲存在記憶體中,那麼當伺服器程序掛掉,資料將丟失。為了解決這個問題,redis支援了將資料持久化到本地硬碟中,具體實現有RDB和AOF兩種方案。

RDB(redis database)

是把當前程序資料生成記憶體快照儲存到硬碟的過程,分手動觸發和自動觸發兩種情況。RDB持久化生成的RDB檔案是一個經過壓縮的二進位制檔案,通過它可以還原生成RDB檔案時的資料庫狀態。

手動觸發:
save:阻塞當前redis伺服器,直到RDB過程完成為止,對於記憶體比較大的例項會造成長時間阻塞,線上環境一定不要使用。基本已廢棄。
bgsave:redis程序執行fork操作傳經子程序,父程序繼續處理命令請求,RDB持久化過程由子程序來完成,完成後自動結束。阻塞發生在fork階段,時間很短。

自動觸發4種情況:
1.執行save m n :當m秒內資料集存在n次修改時,自動觸發bgsave;
2.如果從節點執行全量複製操作,主節點自動執行bgsave生成RDB檔案併發送給從節點;
3.執行debug reload命令重新載入redis時,會觸發save操作;
4.預設情況下執行shutdown時,如果沒有開啟AOF持久化功能則自動執行bgsave。

需要注意的是,在bgsave執行期間,客戶端傳送的save和bgsave

命令都會被伺服器拒絕,目的是為了避免父程序和子程序同時執行rdbSave呼叫而產生競爭條件。此外,bgsave和bgrewriteaof(此命令後面介紹)也不能同時執行:如果bgsave正在執行,那麼bgrewriteaof會等待其執行完畢後再執行;如果bgrewriteaof在執行,那麼bgsave命令會被拒絕。

redis沒有專門用於載入RDB檔案的命令,只要redis在啟動時檢測到RDB檔案存在,就會自動進行載入,在載入期間redis會一直處於阻塞狀態,直到載入完成為止。

RDB預設是開啟的,在.conf配置檔案中還有如下相關引數:

#根據給定的時間間隔和寫入次數將資料儲存到磁碟
# 900秒(15分鐘)之後,且至少1次變更
save 900 1
# 300秒(5分鐘)之後,且至少10次變更
save 300 10
# 60秒之後,且至少10000次變更
save 60 10000

# 當匯出到 .rdb 資料庫時是否用LZF壓縮字串物件,預設都設為 yes
rdbcompression yes
 
# 是否校驗rdb檔案,版本5的RDB有一個CRC64演算法的校驗和放在了檔案的最後。這將使檔案格式更加可靠。
rdbchecksum yes
 
# 持久化資料庫的檔名
dbfilename dump.rdb
 
# 工作目錄
# 例如上面的 dbfilename 只指定了檔名,但是它會寫入到這個目錄下。這個配置項一定是個目錄,而不能是檔名
dir ./


RDB的優點
RDB是一個緊湊壓縮的二進位制檔案,代表Redis在某個時間點上的資料快照。非常適用於備份,全量複製等場景。比如每6小時執行bgsave備份,並把RDB檔案拷貝到遠端機器或者檔案系統中(如hdfs), 用於災難恢復。

Redis載入RDB恢復資料遠遠快於AOF的方式。

RDB的缺點
RDB方式資料沒辦法做到實時持久化/秒級持久化。因為bgsave每次執行都要執行fork操作建立子程序,屬於重量級操作,頻繁執行成本過高。

RDB檔案使用特定二進位制格式儲存,Redis版本演進過程中有多個格式的RDB版本,存在老版本Redis服務無法相容新版RDB格式的問題。

針對RDB不適合實時持久化的問題,Redis提供了AOF持久化方式來解決。

AOF(append only file)

以獨立日誌的方式記錄每次寫命令,重啟時再重新執行AOF檔案中的命令達到恢復資料的目的。AOF的主要作用是解決了資料持久化的實時性, 目前已經是Redis持久化的主流方式。理解掌握好AOF持久化機制對我們兼顧資料安全性和效能非常有幫助。AOF也支援手動觸發和自動觸發。

手動觸發:
bgrewriteaof

自動觸發:
在Redis配置檔案redis.conf中,使用者設定了auto-aof-rewrite-percentage(當前aof檔案空間和上一次重寫後aof檔案空間的比值)和auto-aof-rewrite-min-size(aof重寫時檔案最小體積,預設64MB)引數,並且當前AOF檔案大小server.aof_current_size大於auto-aof-rewrite-min-size(server.aof_rewrite_min_size),同時AOF檔案大小的增長率大於auto-aof-rewrite-percentage(server.aof_rewrite_perc)時,會自動觸發AOF rewrite。

AOF的主要流程分為命令追加、檔案寫入和檔案同步三個步驟。

首先redis所有的寫入命令都追加到aof_buf緩衝區的末尾;然後緩衝區根據對應的策略向硬碟做寫入和檔案同步的工作,策略包括:

always(命令寫入aof_buf後呼叫系統fsync同步到aof檔案,fsync完成後執行緒返回);【不建議】
everysec(命令寫入aof_buf後呼叫系統write操作,write完成後執行緒返回。fsync同步檔案操作一秒一次);
no(命令寫入aof_buf後呼叫系統write操作,不對檔案進行sync同步。同步由作業系統完成,一般不超過30s)。

關於系統提供的write和fsync兩個同步函式的特點:

write:會觸發延遲寫機制。如果同步前系統宕機,緩衝區資料將丟失;
fsync:針對單個檔案做強制硬碟同步,fsync將阻塞直到硬碟完成後返回,保證資料持久化。

隨著aof檔案越來越大,需要定期對aof檔案重寫,達到壓縮的目的,檔案重寫的優點有:
1.只保留最終資料的寫入命令;
2.多個同樣命令合併為1個;

AOF預設是關閉的,如需開啟需要在.conf配置檔案中進行修改,但注意,如果開啟後那麼系統將自動關閉RDB持久化。相關引數如下:

appendonly yes設定開啟,預設不開啟
appendfilename fileName執行檔名,預設appendonly.aof

appendfsync always/everysec/no同步策略,預設everysec

no-appendfsync-on-rewrite yes/no:是否在日誌重寫時不進行命令追加操作,預設no

auto-aof-rewrite-percentage 100:當前aof檔案空間和上一次重寫後aof檔案空間的比值,預設100
auto-aof-rewrite-min-size 64mb:aof重寫時檔案最小體積,預設64M

下一篇講一講redis的sentinel(哨兵)功能。