更新時(shí)間:2022-11-14 來(lái)源:黑馬程序員 瀏覽量:
為什么需要AOF 重寫(xiě)?
AOF 會(huì)記錄每個(gè)寫(xiě)命令到 AOF 文件,隨著時(shí)間越來(lái)越長(zhǎng),AOF 文件會(huì)變得越來(lái)越大。如果不加以控制,會(huì)對(duì) Redis 服務(wù)器,甚至對(duì)操作系統(tǒng)造成影響,而且 AOF 文件越大,數(shù)據(jù)恢復(fù)也越慢。為了解決 AOF 文件體積膨脹的問(wèn)題,Redis 提供 AOF 文件重寫(xiě)機(jī)制來(lái)對(duì) AOF 文件進(jìn)行 “瘦身”。
Redis 通過(guò)創(chuàng)建一個(gè)新的 AOF 文件來(lái)替換現(xiàn)有的 AOF,新舊兩個(gè) AOF 文件保存的數(shù)據(jù)相同,但新 AOF 文件沒(méi)有了冗余命令。
AOF 重寫(xiě)會(huì)阻塞嗎?
AOF 重寫(xiě)過(guò)程是由后臺(tái)進(jìn)程 bgrewriteaof 來(lái)完成的。主線(xiàn)程 fork 出后臺(tái)的 bgrewriteaof 子進(jìn)程,fork 會(huì)把主線(xiàn)程的內(nèi)存拷貝一份給 bgrewriteaof 子進(jìn)程,這里面就包含了數(shù)據(jù)庫(kù)的最新數(shù)據(jù)。然后,bgrewriteaof 子進(jìn)程就可以在不影響主線(xiàn)程的情況下,逐一把拷貝的數(shù)據(jù)寫(xiě)成操作,記入重寫(xiě)日志。
所以 AOF 在重寫(xiě)時(shí),在 fork 進(jìn)程時(shí)是會(huì)阻塞住主線(xiàn)程的。
AOF 日志何時(shí)會(huì)重寫(xiě)?
有兩個(gè)配置項(xiàng)控制 AOF 重寫(xiě)的觸發(fā):
auto-aof-rewrite-min-size: 表示運(yùn)行 AOF 重寫(xiě)時(shí)文件的最小大小,默認(rèn)為 64MB。
auto-aof-rewrite-percentage: 這個(gè)值的計(jì)算方式是,當(dāng)前 AOF文件大小和上一次重寫(xiě)后 AOF
文件大小的差值,再除以上一次重寫(xiě)后 AOF 文件大小。也就是當(dāng)前 AOF 文件比上一次重寫(xiě)后 AOF 文件的增量大小,和上一次重寫(xiě)后 AOF
文件大小的比值。
重寫(xiě)日志時(shí),有新數(shù)據(jù)寫(xiě)入,主進(jìn)程是怎么做的?
重寫(xiě)過(guò)程總結(jié)為:“一個(gè)拷貝,兩處日志”。在 fork 出子進(jìn)程時(shí)的拷貝,以及在重寫(xiě)時(shí),如果有新數(shù)據(jù)寫(xiě)入,主線(xiàn)程就會(huì)將命令記錄到兩個(gè) aof 日志內(nèi)存緩沖區(qū)中。如果 AOF 同步策略配置的是 always,則直接將命令寫(xiě)回 舊的日志文件 ,并且保存一份命令至 AOF重寫(xiě)緩沖區(qū) ,這些操作對(duì)新的日志文件是不存在影響的。(舊的日志文件:主線(xiàn)程使用的日志文件,新的日志文件:bgrewriteaof 進(jìn)程使用的日志文件)
而在 bgrewriteaof 子進(jìn)程完成會(huì)日志文件的重寫(xiě)操作后,會(huì)提示主線(xiàn)程已經(jīng)完成重寫(xiě)操作,主線(xiàn)程會(huì)將 AOF 重寫(xiě)緩沖中的命令追加到新的日志文件后面。這時(shí)候在高并發(fā)的情況下,AOF 重寫(xiě)緩沖區(qū)積累可能會(huì)很大,這樣就會(huì)造成阻塞,Redis 后來(lái)通過(guò) Linux 管道技術(shù)讓 aof 重寫(xiě)期間就能同時(shí)進(jìn)行回放,這樣 aof 重寫(xiě)結(jié)束后只需回放少量剩余的數(shù)據(jù)即可。
最后通過(guò)修改文件名的方式,保證文件切換的原子性。
在 AOF 重寫(xiě)日志期間發(fā)生宕機(jī)的話(huà),因?yàn)槿罩疚募€沒(méi)切換,所以恢復(fù)數(shù)據(jù)時(shí),用的還是舊的日志文件。
在重寫(xiě)日志整個(gè)過(guò)程時(shí),主線(xiàn)程有哪些地方會(huì)被阻塞?
1、fork 子進(jìn)程時(shí),需要拷貝虛擬頁(yè)表,會(huì)對(duì)主線(xiàn)程阻塞 。
2、主進(jìn)程有 bigkey 寫(xiě)入時(shí),操作系統(tǒng)會(huì)創(chuàng)建頁(yè)面的副本,并拷貝原有的數(shù)據(jù),會(huì)對(duì)主線(xiàn)程阻塞。
3、子進(jìn)程重寫(xiě)日志完成后,主進(jìn)程追加 aof 重寫(xiě)緩沖區(qū)時(shí)可能會(huì)對(duì)主線(xiàn)程阻塞