1、為什么redis要持久化?
- 將redis作為資料庫來使用;
- 將redis作為寫緩沖(讀緩沖不需要持久化);
- 當redis崩潰(crash)時,可以很快從磁盤恢復資料,否則會引起快取雪崩;
2、持久化概述
redis支持RDB和AOF兩種持久化方式,
redis.conf中可配置RDB持久化檔案和AOF持久化檔案的位置和檔案名,
# 持久化檔案位置
dir ./
# 快照檔案名
dbfilename dump.rdb
# AOF檔案名
appendfilename appendonly.aof
RDB通過快照完成持久化,發生快照的條件如下:
- 根據配置規則自動快照;
- 用戶執行save或bgsave命令;
- 執行flushall;
- 主從復制;
redis啟動后會讀取RDB檔案,
redis允許同時開啟RDB和AOF,redis重啟后會使用AOF檔案恢復資料,因為AOF方式可能丟失的資料更少,
3、RDB方式
3.1、自動快照
默認的redis.conf中有如下配置
# 每900秒有一個或一個以上的鍵被更改則進行快照,多個save之間是或的關系
save 900 1
save 300 10
save 60 10000
自動快照是異步的,并不會阻塞客戶端請求,
3.2、save或bgsave
save命令是同步操作,阻塞所有客戶端請求,生產上避免使用,
bgsave后臺異步執行,回應客戶端請求,執行bgsave會立即回傳OK,想知道快照是否完成可以通過lastsave命令查看最后一次快照時間,
3.3、flushall
執行flushall時,只要自動快照條件不為空,無論是夠滿足自動快照條件,都會進行一次快照,
3.4、快照原理
- redis使用fork函式復制一份當前行程(父行程)的副本(子行程)
- 父行程繼續接收并處理客戶端請求,而子行程將記憶體資料寫入磁盤中的臨時檔案
- 當子行程寫完所有資料后用臨時檔案替換舊的RDB檔案
在執行fork函式時作業系統(類Unix系統)會使用寫時復制(copy-on-write)策略,即fork函式發生的一刻父子行程共享同一記憶體資料,當父行程要更改其中某片資料時(如執行一個命令),作業系統會將該片資料復制一份以保證子行程的資料不受影響,因此新的RDB檔案存盤的是執行fork函式一刻的記憶體資料,
4、AOF方式
AOF會將redis執行的每一條寫命令追加到磁盤檔案中,
默認情況下redis沒有開啟AOF,可通過如下配置開啟,
appendonly yes
AOF檔案中保存的就是redis通信協議的內容,
比如我執行一條set age 10命令,則AOF檔案內容如下,
*3
$3
set
$3
age
$2
10
4.1、優化AOF檔案
比如執行了兩條命令set age 10和set age 12,其實AOF只用保存第二條命令就行了,因為第二條命令會覆寫第一條命令,
如果冗余命令過多,會導致AOF檔案過大而記憶體資料并沒有多少,針對這種情況每達到一定條件(見如下配置)時redis會對AOF檔案進行重寫,
# 當前AOF檔案大小超過上一次重寫的AOF檔案大小的百分之多少時就重寫
auto-aof-rewrite-percentage 100
# 允許重寫的最小AOF檔案大小
auto-aof-rewrite-min-size 64mb
也可以執行bgrewriteaof命令手動重寫,
即使BGREWRITEAOF執行失敗,也不會有任何資料丟失,因為舊的AOF檔案在BGREWRITEAOF 成功之前不會被修改,
AOF重寫程序:
- 從主行程中fork出子行程,并拿到fork時的AOF檔案資料寫到一個臨時AOF檔案中;
- 在重寫程序中,redis收到的命令會同時寫到AOF緩沖區和重寫緩沖區中,這樣保證重寫不丟失重寫程序中的命令;
- 重寫完成后通知主行程,主行程會將AOF緩沖區中的資料追加到子行程生成的檔案中;
- redis會原子的將舊檔案替換為新檔案,并開始將資料寫入到新的aof檔案上;
4.2、同步磁盤資料
AOF持久化會將命令記錄在AOF檔案中,但由于作業系統的快取限制,資料并沒有真正寫入磁盤,而是進行了系統的磁盤快取,默認情況下系統每30秒進行一次同步,如果這30秒期間系統例外退出則會導致資料丟失,
可通過如下配置設定同步時機,
# 總是同步
appendfsync always
# 每秒同步一次(默認)
appendfsync everysec
# 由作業系統決定(30秒)
appendfsync no
5、設定了過期時間的key會持久化嗎?
現有如下操作
set age 10
expire age 60
save
ttl age --50
shutdown nosave
--過10秒
./redis-server
ttl age --顯示40 or 50?
正確答案是10,說明expire記錄的是一個時間戳,即使redis服務停止了,停止期間這10秒的時間仍然是有效的
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/272624.html
標籤:其他
