大家都知道,redis相比其他cache而言,它是支援持久化的,這樣就多了一份保障,在down機之後,可以從持久化檔案中進行恢復,防止從後端資料庫重新載入,而給資料庫造成壓力。redis 支援兩
2021-06-26 10:44:20
大家都知道,redis相比其他cache而言,它是支援持久化的,這樣就多了一份保障,在down機之後,可以從持久化檔案中進行恢復,防止從後端資料庫重新載入,而給資料庫造成壓力。redis 支援兩種持久化的方式:一種是 AOF ,一種是RDB。今天主要來聊聊AOF持久化的方式。
寫入日誌時機
redis 在寫AOF日誌的時候,是先執行redis命令,執行redis 命令之後,才會寫入AOF日誌。這樣做的好處,是防止錯誤的命令寫入AOF日誌,同時還會省去redis 命令語法檢查的開銷,同時這樣不會阻塞redis執行緒進行寫操作。
流程如下:
日誌內容
大家看了上圖,其實就知道AOF日誌檔案存的是什麼,其實就是儲存的文字格式的命令,以set hi redis 為例,*3 表示由三部分( set hi redis )組成,$3表示 這個部分由三個位元組組成,也就是set ,其他 hi redis 都是一個道理這裡就不多做解析,如果有疑問歡迎大家留言提問。
日誌的寫到磁碟的策略
我們知道reids 的aof 日誌,最後肯定是要落盤的,寫入磁碟肯定就會受到磁碟io的影響,如果磁碟io很忙,那麼勢必會影響我們寫入磁碟的速度,而且寫入磁碟和寫入記憶體的速度肯定不是一級別的,會不會影響redis 執行緒進行返回結果呢,因為我上篇文章介紹了 redis單執行緒模型 ,也就是阻塞了redis 的主執行緒呢,這樣就增加了延遲,後續的操作就會排隊或者超時。
其實redis 為我們提供三種寫磁碟的策略,分別為Always、EverySecond、No,下面分別介紹這三種策略原理和優缺點。
Aways
所謂的always 就是執行redis 寫命令之後,立即執行寫回磁碟,寫入磁碟之後,才會返回結果,這兩部是同步進行,勢必會增加redis 的響應延遲,如果此時磁碟io很繁忙,那麼寫入磁碟就會慢,那麼redis 就會增加延遲時間。
看下圖:
1-3 步驟是順序執行,且同步執行的。
現在可以思考下,這種模式會不會丟失資料呢? 看下圖:
圖中黑色圓表示斷電了,拔出電線。
在執行第二步之前,斷電了。
答案 是會的,如果寫入記憶體成功後,然後同步執行寫回磁碟操作,這兩個步驟中,在執行寫磁碟的之前,斷電了,那麼此時這條命令的資料是沒有寫入磁碟,也就是沒有持久化成功,redis再啟動恢復的時候,aof日誌中是沒有這條記錄的。
EverySecond
所謂EverySecond 這個詞很好理解,就是每秒寫入磁碟一次。
說下具體的流程吧,其實就是redis 寫入記憶體成功後,並不是同步寫入磁碟了,而是會寫入aof日誌的緩衝區,也就是一塊記憶體,那麼寫入的速度會很快。然後redis 後臺會有一個執行緒專門讀取aof日誌緩衝區的命令,再寫入磁碟。
看圖說話:
現在思考下,這種模式,會不會丟失資料呢?
看圖說話:
圖中黑色圓表示斷電了,拔出電線。
答案是肯定的啊,因為reids 寫入記憶體之後,會把命令寫入緩衝區,緩衝區說白了 ,也是記憶體,後臺執行緒每秒讀取一次,寫入磁碟,那麼如果發生斷電呢,那麼緩衝區內的資料,也就是上一秒的資料,還沒來得及寫入磁碟就丟失了。
No
和EverySecond 類似,redis 寫入記憶體成功之後,redis 的寫命令也是會寫入到aof 緩衝區,只是此時不會由redis 後臺執行緒去執行寫入磁碟的操作了,而是有作業系統來決定,何時重新整理到磁碟。
看圖說話:
丟不丟資料,就很好看出來了,丟多少,也是由作業系統來決定了,這裡不多做說明了
三種策略的對比
至於怎麼選擇這三種策略,看自己的實際需求,資料要求的敏感度,允不允許丟失,來做一個性能和需求的取捨。
AOF日誌檔案的重寫
隨著redis 命令的增多,那麼aof日誌檔案,肯定是越來越大的,那麼大檔案在進行檔案寫入的時候,速度就會變慢,而且作業系統會對大檔案的儲存會做限制,無法儲存檔案。redis 再進行重啟資料恢復的時候,是逐一執行aof日誌的命令,如果檔案很大,那麼資料恢復的過程就會很慢,造成的影響可想而知。
那麼此時就會進行aof日誌檔案的重寫操作,那麼重寫過程中都幹了什麼呢?是在原有的aof日誌檔案內的命令進行重寫嗎?aof 重寫過程中哪些操作會阻塞redis 執行緒的讀寫操作的延遲呢?
怎麼就變大了?
變大的原因,其實也是很簡答了,命令越來越多,當然就變大了,其次對一個key 的多次操作,就會造成一個aof檔案日誌儲存了一個key 的多次操作,如果操作很頻繁的話,那麼日誌檔案增大的速度可想而知了。其實redis 在重寫的過程中,就是把一個key 的多次操作命令進行壓縮,壓縮為一條寫入命令,這樣aof 檔案就變小了,小的aof檔案無論再寫入和恢復資料的時候都會很快的。
看圖說話:
一開始對set 集合 login_user 進行了多次操作,但是在重寫之後就壓縮為了一條命令。
重寫過程
aof 的重寫,並不會是redis 主執行緒來完成的,redis會fork出一個子程序進行 aof 日誌的重寫,這個子程序交bgrewriteaof。
redis 在進行aof 重寫的過程中,並不是對原有的aof檔案進行分析重寫,而是會copy一份redis當前的記憶體頁表給子程序,這也是fork子程序的過程,如果redis的記憶體很大,那麼記憶體頁表就會很大,那麼copy的過程就會變慢,記住這個copy的過程是會阻塞redis 的主執行緒的。
copy完成之後,此時redis 主執行緒和 fork子程序就會指向相同的記憶體地址,那麼子程序就可以開始讀取記憶體地址的資料,來生成新的aof日誌了。
那麼此時可能還會有的新的請求過來,新的請求redis 必須要處理的,不能收到aof重寫的影響,此時會用到linux 的copyonwrite技術,也叫寫時複製,也就是說當修改一個已經存在的key的時候,此時會複製這個key所在的記憶體頁到新的地址,複製完成後,再進行修改key的操作,如果頁很大,這個過程就會阻塞redis 主執行緒,延遲就會增加,這是需要注意的地方。對於新進來的請求,redis 會把新命令儲存aof日誌重新緩衝區,當子程序重寫完成之後,就會讀取aof日誌重新緩衝區的內容追加到新的aof日誌中,此時aof重寫完成,舊的aof日誌就會被替換。
注意在aof重寫的過程中,新的寫請求過來,還是會往原來的aof日誌中寫入的,主要是為了防止aof重寫失敗,而不會影響舊aof日誌資料的丟失。
繼續看圖說話:
總結
今天聊了aof日誌持久化的方式,檔案內容是什麼,以及寫入磁碟的三種策略,每種策略的對redis的效能和資料可靠性都有影響,Aways、EverySecond、No 效能逐次提高,可靠性逐漸降低,具體使用要看自己對資料的實際需求。
還有就是aof 重寫,fork子程序是會阻塞redis 操作執行緒的,copyonwrite 如果遇到大頁也會增加阻塞redis 操作執行緒的時間。
aof 重寫觸發時機:
手動傳送「bgrewriteaof」指令,通過子程序生成更小體積的aof,然後替換掉舊的、大體量的aof檔案。
配置檔案配置自動觸發: auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb
在aof檔案體量超過64mb,且比上次重寫後的體量增加了100%時自動觸發重寫。
根據自己的需求來修改配置即可。
如果文章對你有幫助的話,就點贊支援一波吧,非常感謝!
如何獲取Java學習資料?
轉發分享此文,後臺私信小編:「 資料 」即可獲取。注意是私信,因為檔案比較大,所以要加好友,免費,不花錢(注:轉發分享,感謝大家)
相關文章
大家都知道,redis相比其他cache而言,它是支援持久化的,這樣就多了一份保障,在down機之後,可以從持久化檔案中進行恢復,防止從後端資料庫重新載入,而給資料庫造成壓力。redis 支援兩
2021-06-26 10:44:20
【6月26日訊】相信大家都知道,自從全球晶片工藝進入到了5nm工藝時候,業內很多人士都一直認為:「摩爾定律要失靈了」,但我們可以看到更加先進的4nm工藝、3nm工藝、2nm工藝晶片研
2021-06-26 10:43:25
在工作中,我們可能會遇到需要對錶格中的局部資料進行排序的情況,這篇文章跟大家分享一下表格局部資料的排序辦法。應用案例對下圖表格中「2組」的七個葫蘆娃資料資訊按「成績
2021-06-26 10:42:13
最新的訊息顯示,小米將會在八月份釋出一大堆東西,不僅有作業系統,還有很多期待已經的硬體裝置;那麼都有哪些產品呢?小宅給小夥伴們總結一下。第一,MIUI 13作業系統,今年的MIUI 12.5
2021-06-26 10:24:19
感謝您的閱讀!【良心拷問:選擇手機你是選擇華為還是選擇iPhone?】我們在選擇手機的時候是考慮華為手機還是考慮iPhone手機?實際上,不管是華為手機還是iPhone手機,它們現在已經成為
2021-06-26 10:24:01
阿里頒發「達摩獎」,張勇:達摩院不以盈利為目的,堅定長期研究量子計算、晶片等 阿里巴巴達摩院成立於2017年10月,致力於開展基礎科學和顛覆式技術創新研究,並且開設「達摩
2021-06-26 10:23:42