Redis持久化,AOF、RDB,混合持久化
Redis 是跑在內存里面的,當程序重啟或者服務器崩潰的時候,數(shù)據就會丟失,如果業(yè)務場景希望重啟之后數(shù)據還在,就需要做持久化,把數(shù)據保存到可永久保存的存儲設備中。
Redis 提供了兩種方式來實現(xiàn)持久化。
第一個是記錄 Redis 執(zhí)行的命令 AOF,第二種是記錄某一個時刻的快照數(shù)據 RDB。 這兩種各有優(yōu)缺點,使用的時候可以結合起來。
RDB
1RDB(Redis Database BackUp),記錄 Redis 某一個時刻的全部數(shù)據,這個方式的本質是快照,直接保存二進制數(shù)據到磁盤中去,后序通過加載 RDB 文件恢復數(shù)據。
RDB 底層的原理:
當 Redis 停止服務的時候執(zhí)行的是 save 命令,阻塞執(zhí)行保存所有的數(shù)據。正常情況下面執(zhí)行的是 bgsave,是異步的操作。
bgsave 命令的原理 :
調用 bgsave 的時候,Redis 使用 unix 的 fork 命令系統(tǒng)調用創(chuàng)建一個子進程,子進程會復制主進程的內存空間,公用父進程的頁表結構,使用的是 copy-on-write 機制,就是父子進程最初都是共享一塊內存區(qū)域。只有數(shù)據在被修改的時候才會真正的復制,減少了內存的拷貝成本。
子進程將當前 內存中的數(shù)據寫入到磁盤上面,父進程繼續(xù)處理客戶端的請求,父進程修改數(shù)據的時候需要復制被修改頁的內存,不會影響子進程正在生成的快照。
子進程寫入完畢后退出,生成 RDB 是 Redis 數(shù)據當時的完整快照。
fork 底層使用 copy on write 技術。主進程寫的寫操作的時候 要先拷貝一份數(shù)據,執(zhí)行寫操作。
存在的問題
使用 bgsave 執(zhí)行快照的時候,如果主線程修改了數(shù)據,不管是否共享內存的數(shù)據,RBD 快照都無法寫入主進程剛剛修改的數(shù)據,因為新拷貝了一份內存數(shù)據出來。 子進程寫入到 RDB 文件中的數(shù)據只能是原本的內存數(shù)據。
在 RDB 執(zhí)行持久化期間,剛 fork 時,主進程和子進程共享同一個物理內存,但是途中主進程處理寫操作修改了共享內存,于是當前被修改的數(shù)據的物理內存先會被復制一份,在極端的情況下面,所有的內存都被修改,此時內存占用時原來的兩倍。 內存會被占滿。所以在寫操作多的情況下面,要留意內存的變化,防止內存滿了。 還有在主進程寫完之后,崩潰掉了,Redis 將丟失線程在快照期間修改的數(shù)據。存在數(shù)據安全的漏洞,可能存在短分鐘內的數(shù)據沒有寫入到數(shù)據文件中去。
AOF
2.AOF(append only File) 記錄執(zhí)行的每條寫操作的命令, 不會記錄讀操作,重啟之后通過重新執(zhí)行命令來恢復數(shù)據,AOF 本質是記錄**操作日志**,后序通過日志來恢復數(shù)據。
redis 默認是沒有開啟持久化功能的,需要手動修改 redis.conf 文件來配置參數(shù)
存儲的內容
*3 表示命令由三個單詞組成。 $3 表示命令的長度 set 表示命令
Redis 先執(zhí)行 命令 然后將命令回寫到磁盤中去,寫道磁盤也是在主線程中執(zhí)行的,如果操作不當不能讓線程阻塞。
Redis 寫入 AOF 日志的過程,首先命令追加到緩沖區(qū),然后寫入到內核中去,最后由內核將命令寫入到磁盤中去,內核寫入的時機由三種新三種形式。
有三種寫的策略:
- always 同步寫回去。 2. everysec 每秒寫回
- no 由操作系統(tǒng)控制寫回
寫入的時機是又內核決定的,不同的寫入時機對性能和數(shù)據的丟失都是不一樣的。
AOF 的重寫機制
當執(zhí)行的命令越來越多的時候,AOF 文件會越來越大,Redis 會重寫 AOF 文件。重寫 AOF 文件是讀取當前數(shù)據庫中的所有鍵值對,然后每一個鍵值對用一條命令記錄到新的 AOF 文件中,等全部記錄完成之后,將新的 AOF 文件替換現(xiàn)有的 AOF 文件。
重寫操作 比如 set name lisi 和 set name wangwu 只會保留第二條命令,第一條命令會刪除掉。
重寫的過程是非常耗時的,不可能放在主線程中去運行,由后臺子進程 bgrewiteaof 來完成。 創(chuàng)建子進程可以·共享父進程的內存數(shù)據。以只讀的方式
混合化持久
混合使用 AOF 日志和內存快照。
AOF 重寫的時候,fork 出現(xiàn)的重寫子進程會先與主進程共享的內存數(shù)據以 RDB 方式寫入 aof 文件中,然后主線程處理的命令被記錄在緩沖區(qū)內,緩存區(qū)內的增量命令以 AOF 形式寫入 aof 文件,寫完后通知主線程將含以后 aof 格式和 rdb 格式的 aof 文件替換舊的 aof 文件。
牛牛的面試專欄,希望自己在25年可以拿到一份大廠的SP Offer 你的點贊和收藏都是我持續(xù)更新的動力