aof有哪些潛在的阻塞點?下面本篇文章給大家總結一些redis中aof的潛在阻塞點,希望對大家有所幫助!
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視頻教程!!