Copy-on-Write機制: 父子進程共享內存頁 當父進程修改數據時,內核會復制被修改的頁 這可能導致內存使用量暫時增加 通俗的話描述一下
可以用一個生活中的例子來通俗解釋?Copy-on-Write(寫時復制)?機制:
📖 比喻:父子共用一本作業本
假設有一對父子(父進程和子進程)要完成以下任務:
初始狀態:父親有一本寫滿數據的作業本(Redis內存數據),現在孩子需要做一份完全相同的作業(RDB持久化)。
傳統方式(非COW):
?? 父親直接復印整本作業給孩子 →?浪費紙張(內存),而且復印過程很耗時。Copy-on-Write方式(Redis實際采用):
??第一步:父親直接把作業本借給孩子看,兩人暫時共用同一本作業(父子進程共享內存頁)。
??第二步:如果父親要修改作業的某一頁(父進程修改數據):?? 內核會單獨復制這一頁給孩子(復制被修改的內存頁)
📝 父親在新復制的頁上修改,不影響孩子讀原內容
📚 其他未修改的頁繼續保持共享
💡 關鍵點:
省資源:一開始不復制全部數據,只有真正修改時才復制局部(節省內存)。
副作用:如果父親頻繁修改作業(Redis寫入量大),會導致復制的頁越來越多,內存占用暫時上升(這就是BGSAVE期間可能出現的"內存翻倍"現象)。
短暫阻塞:剛開始"借作業本"時(fork子進程),父親需要整理作業本目錄(內核準備進程數據結構),這時會短暫暫停(所有請求被阻塞)。
🌰 Redis中的實際表現:
執行
BGSAVE
時,如果Redis內存有10GB:理想情況:無寫入操作 →?內存幾乎不增加(共享所有頁)
最壞情況:寫入全部數據 →?內存臨時增加10GB(所有頁被復制)
通常情況:增加約1-2GB(只有部分頁被修改和復制)
?? 這就是為什么大內存Redis實例執行BGSAVE時,需要預留額外內存空間。