亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

Redis的AOF日志及其重寫機制(二)

2023-10-30 01:54:32
7
0

AOF 日志重寫的時候,是由 bgrewriteaof 子進程來完成的,不用主線程參與,在《Redis的AOF日志及其重寫機制(一)》中最后所說的非阻塞也是指子進程的執行不阻塞主線程。那么,AOF日志的整個重寫過程有沒有其他潛在的阻塞風險呢?答案是:有的。

Redis采用fork子進程重寫AOF文件時,潛在的阻塞風險包括:fork子進程 和 AOF重寫過程中父進程產生寫入的場景,下面依次介紹。

對于fork子進程,fork這個瞬間一定是會阻塞主線程的,fork采用操作系統提供的寫時復制(Copy On Write)機制,就是為了避免一次性拷貝大量內存數據給子進程造成的長時間阻塞問題,但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本身的日志,一個原因是父子進程寫同一個文件必然會產生競爭問題,控制競爭就意味著會影響父進程的性能。二是如果AOF重寫過程中失敗了,那么原本的AOF文件相當于被污染了,無法做恢復使用。所以Redis AOF重寫一個新文件,重寫失敗的話,直接刪除這個文件即可,不會對原先的AOF文件產生影響。等重寫完成之后,直接替換舊文件即可。

0條評論
作者已關閉評論
1****m
13文章數
0粉絲數
1****m
13 文章 | 0 粉絲
原創

Redis的AOF日志及其重寫機制(二)

2023-10-30 01:54:32
7
0

AOF 日志重寫的時候,是由 bgrewriteaof 子進程來完成的,不用主線程參與,在《Redis的AOF日志及其重寫機制(一)》中最后所說的非阻塞也是指子進程的執行不阻塞主線程。那么,AOF日志的整個重寫過程有沒有其他潛在的阻塞風險呢?答案是:有的。

Redis采用fork子進程重寫AOF文件時,潛在的阻塞風險包括:fork子進程 和 AOF重寫過程中父進程產生寫入的場景,下面依次介紹。

對于fork子進程,fork這個瞬間一定是會阻塞主線程的,fork采用操作系統提供的寫時復制(Copy On Write)機制,就是為了避免一次性拷貝大量內存數據給子進程造成的長時間阻塞問題,但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本身的日志,一個原因是父子進程寫同一個文件必然會產生競爭問題,控制競爭就意味著會影響父進程的性能。二是如果AOF重寫過程中失敗了,那么原本的AOF文件相當于被污染了,無法做恢復使用。所以Redis AOF重寫一個新文件,重寫失敗的話,直接刪除這個文件即可,不會對原先的AOF文件產生影響。等重寫完成之后,直接替換舊文件即可。

文章來自個人專欄
文章 | 訂閱
0條評論
作者已關閉評論
作者已關閉評論
0
0