您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)Redis中AOF有哪些潛在的阻塞點的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
1. Redis采用fork子進程重寫AOF文件時,有潛在的阻塞風險
fork子進程,fork這個瞬間一定是會阻塞主線程的(注意,fork時并不會一次性拷貝所有內(nèi)存數(shù)據(jù)給子進程),fork采用操作系統(tǒng)提供的寫實復(fù)制(Copy On Write)機制,就是為了避免一次性拷貝大量內(nèi)存數(shù)據(jù)給子進程造成的長時間阻塞問題?!鞠嚓P(guān)推薦:Redis視頻教程】
但fork子進程需要拷貝進程必要的數(shù)據(jù)結(jié)構(gòu),其中有一項就是拷貝內(nèi)存頁表(虛擬內(nèi)存和物理內(nèi)存的映射索引表),這個拷貝過程會消耗大量CPU資源,拷貝完成之前整個進程是會阻塞的,阻塞時間取決于整個實例的內(nèi)存大小,實例越大,內(nèi)存頁表越大,fork阻塞時間越久。
拷貝內(nèi)存頁表完成后,子進程與父進程指向相同的內(nèi)存地址空間,也就是說此時雖然產(chǎn)生了子進程,但是并沒有申請與父進程相同的內(nèi)存大小。
那什么時候父子進程才會真正內(nèi)存分離呢?
“寫實復(fù)制”顧名思義,就是在寫發(fā)生時,才真正拷貝內(nèi)存真正的數(shù)據(jù),這個過程中,父進程也可能會產(chǎn)生阻塞的風險,就是下面介紹的場景。
fork出的子進程指向與父進程相同的內(nèi)存地址空間,此時子進程就可以執(zhí)行AOF重寫,把內(nèi)存中的所有數(shù)據(jù)寫入到AOF文件中。
但是此時父進程依舊是會有流量寫入的,如果父進程操作的是一個已經(jīng)存在的key,那么這個時候父進程就會真正拷貝這個key對應(yīng)的內(nèi)存數(shù)據(jù),申請新的內(nèi)存空間,這樣逐漸地,父子進程內(nèi)存數(shù)據(jù)開始分離,父子進程逐漸擁有各自獨立的內(nèi)存空間。因為內(nèi)存分配是以頁為單位進行分配的,默認4k,如果父進程此時操作的是一個bigkey,重新申請大塊內(nèi)存耗時會變長,可能會產(chǎn)生阻塞風險。
另外,如果操作系統(tǒng)開啟了內(nèi)存大頁機制(Huge Page,頁面大小2M),那么父進程申請內(nèi)存時阻塞的概率將會大大提高,所以在Redis機器上需要關(guān)閉Huge Page機制。Redis每次fork生成RDB或AOF重寫完成后,都可以在Redis log中看到父進程重新申請了多大的內(nèi)存空間。
AOF重寫不復(fù)用AOF本身的日志:
一個原因是父子進程寫同一個文件必然會產(chǎn)生競爭問題,控制競爭就意味著會影響父進程的性能。
二是如果AOF重寫過程中失敗了,那么原本的AOF文件相當于被污染了,無法做恢復(fù)使用。所以Redis AOF重寫一個新文件,重寫失敗的話,直接刪除這個文件就好了,不會對原先的AOF文件產(chǎn)生影響。等重寫完成之后,直接替換舊文件即可。
感謝各位的閱讀!關(guān)于“Redis中AOF有哪些潛在的阻塞點”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。