共計 1229 個字符,預計需要花費 4 分鐘才能閱讀完成。
這篇文章給大家分享的是有關 Redis 中 AOF 有哪些潛在的阻塞點的內容。丸趣 TV 小編覺得挺實用的,因此分享給大家做個參考,一起跟隨丸趣 TV 小編過來看看吧。
AOF 有哪些潛在的阻塞點
1. Redis 采用 fork 子進程重寫 AOF 文件時,有潛在的阻塞風險
1)、fork 子進程
fork 子進程,fork 這個瞬間一定是會阻塞主線程的(注意,fork 時并不會一次性拷貝所有內存數據給子進程),fork 采用操作系統提供的寫實復制 (Copy On Write) 機制,就是為了避免一次性拷貝大量內存數據給子進程造成的長時間阻塞問題。【相關推薦:Redis 視頻教程】
但 fork 子進程需要拷貝進程必要的數據結構,其中有一項就是拷貝內存頁表(虛擬內存和物理內存的映射索引表),這個拷貝過程會消耗大量 CPU 資源,拷貝完成之前整個進程是會阻塞的,阻塞時間取決于整個實例的內存大小,實例越大,內存頁表越大,fork 阻塞時間越久。
拷貝內存頁表完成后,子進程與父進程指向相同的內存地址空間,也就是說此時雖然產生了子進程,但是并沒有申請與父進程相同的內存大小。
那什么時候父子進程才會真正內存分離呢?
“寫實復制”顧名思義,就是在寫發生時,才真正拷貝內存真正的數據,這個過程中,父進程也可能會產生阻塞的風險,就是下面介紹的場景。
2)、AOF 重寫中父進程有寫入的場景
fork 出的子進程指向與父進程相同的內存地址空間,此時子進程就可以執行 AOF 重寫,把內存中的所有數據寫入到 AOF 文件中。
但是此時父進程依舊是會有流量寫入的,如果父進程操作的是一個已經存在的 key,那么這個時候父進程就會真正拷貝這個 key 對應的內存數據,申請新的內存空間,這樣逐漸地,父子進程內存數據開始分離,父子進程逐漸擁有各自獨立的內存空間。因為內存分配是以頁為單位進行分配的,默認 4k,如果父進程此時操作的是一個 bigkey,重新申請大塊內存耗時會變長,可能會產生阻塞風險。
另外,如果操作系統開啟了內存大頁機制(Huge Page,頁面大小 2M),那么父進程申請內存時阻塞的概率將會大大提高,所以在 Redis 機器上需要關閉 Huge Page 機制。Redis 每次 fork 生成 RDB 或 AOF 重寫完成后,都可以在 Redis log 中看到父進程重新申請了多大的內存空間。
3)、AOF 重寫為什么不復用 AOF 本身日志呢
AOF 重寫不復用 AOF 本身的日志:
一個原因是父子進程寫同一個文件必然會產生競爭問題,控制競爭就意味著會影響父進程的性能。
二是如果 AOF 重寫過程中失敗了,那么原本的 AOF 文件相當于被污染了,無法做恢復使用。所以 Redis AOF 重寫一個新文件,重寫失敗的話,直接刪除這個文件就好了,不會對原先的 AOF 文件產生影響。等重寫完成之后,直接替換舊文件即可。
感謝各位的閱讀!關于“Redis 中 AOF 有哪些潛在的阻塞點”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!