AOF有哪些潛在的阻塞點?以下這篇文章為大家總結一些Redis中AOF的潛在阻塞點,希望對大家有幫助!
#1. Redis採用fork子程序重寫AOF檔時,有潛在的阻塞風險
fork子程序,fork這個瞬間一定是會阻塞主執行緒的(注意,fork時並不會一次性拷貝所有記憶體資料給子程序),fork採用作業系統提供的寫實複製(Copy On Write)機制,就是為了避免一次性拷貝大量記憶體資料給子程序造成的長時間阻塞問題。 【相關建議:Redis影片教學】
但fork子程序需要拷貝程序必要的資料結構,其中有一項就是拷貝記憶體頁表(虛擬記憶體和實體記憶體的映射索引表),這個拷貝過程會消耗大量CPU資源,拷貝完成之前整個進程是會阻塞的,阻塞時間取決於整個實例的記憶體大小,實例越大,記憶體頁表越大, fork阻塞時間越久。
拷貝記憶體頁表完成後,子進程與父進程指向相同的記憶體位址空間,也就是說此時雖然產生了子進程,但是並沒有申請與父進程相同的記憶體大小。
那什麼時候父子進程才會真正記憶體分離呢?
「寫實複製」顧名思義,就是在寫發生時,才真正拷貝記憶體真正的數據,這個過程中,父進程也可能會產生阻塞的風險,就是下面介紹的場景。
fork出的子程序指向與父進程相同的內存位址空間,此時子程序就可以執行AOF重寫,把記憶體中的所有資料寫入到AOF檔。
但是此時父進程依舊是會有流量寫入的,如果父進程操作的是一個已經存在的key,那麼這個時候父進程就會真正拷貝這個key對應的內存數據,申請新的記憶體空間,如此逐漸地,父子進程記憶體資料開始分離,父子進程逐漸擁有各自獨立的記憶體空間。因為記憶體分配是以頁為單位進行分配的,預設4k,如果父進程此時操作的是一個bigkey,重新申請大塊記憶體耗時會變長,可能會產生阻塞風險。
另外,如果作業系統開啟了記憶體大頁機制(Huge Page,頁面大小2M),那麼父行程申請記憶體時阻塞的機率將會大大提高,所以在Redis機器上需要關閉Huge Page機制。 Redis每次fork產生RDB或AOF重寫完成後,都可以在Redis log中看到父行程重新申請了多大的記憶體空間。
AOF重寫不復存在AOF本身的日誌:
一個原因是父子程序寫同一個檔案必然會產生競爭問題,控制競爭就意味著會影響父行程的效能。
二是如果AOF重寫過程中失敗了,那麼原本的AOF檔就相當於被污染了,無法做恢復使用。所以Redis AOF重寫一個新文件,重寫失敗的話,直接刪除這個文件就好了,不會對原先的AOF文件產生影響。等重寫完成之後,直接取代舊文件即可。
更多程式相關知識,請造訪:程式設計影片! !
以上是聊聊Redis中AOF的潛在阻塞點(總結)的詳細內容。更多資訊請關注PHP中文網其他相關文章!