mongodb內存映射原理

 

內存映射

mongodb非常吃內存,爲啥這麼吃內存呢,mongodb使用的是內存映射存儲引擎,即Memory Mapped Storage Engine,簡稱MMAP,MMAP可以把磁盤文件的一部分或全部內容直接映射到內存,這樣文件中的信息位置就會在內存中有對應的地址空間,把磁盤IO操作轉換成內存操作。 avatarmapped:映射到內存的數據大小, vsize:虛擬內存,是mapped的2倍 這裏虛擬內存是mapped的兩倍,是因爲我們開啓了Journal日誌,需要在內存中多映射一次,大概就是它的兩倍了。如果關閉Journal日誌,虛擬內存大小將和mapped大小相當。

原理

內存映射,是把文件中數據全部映射到內存中的嗎?還是隻是映射一部分內容,那麼這部門內容又是如何確定呢?看這張圖 avatar

映射了就不需要讀磁盤嗎,沒有磁盤IO嗎? 沒有內存映射會怎麼樣 進程調用read,write的系統調用函數,內核進程把磁盤的數據讀到內核空間,然後在copy到用戶進程空間。沒錯,就是兩次複製。

而有了內存映射之後,用戶進程就可以採用指針的方式讀寫操作這一段內存,而系統會自動回寫髒頁面到對應的文件磁盤上,即完成了對文件的操作而不必再調用read,write等系統調用函數。

總而言之,常規文件操作需要從磁盤到頁緩存再到用戶主存的兩次數據拷貝。而mmap操控文件,只需要從磁盤到用戶主存的一次數據拷貝過程。說白了,mmap的關鍵點是實現了用戶空間和內核空間的數據直接交互而省去了空間不同數據不通的繁瑣過程。因此mmap效率更高。

兩步走

  • 內存映射

在內存映射的過程中,並沒有實際的數據拷貝,文件沒有被載入內存,只是邏輯上被放入了內存,這個過程由系統調用mmap()實現,所以建立內存映射的效率很高。 avatar

  • 缺頁中斷

既然建立內存映射沒有進行實際的數據拷貝,那麼進程又怎麼能最終直接通過內存操作訪問到硬盤上的文件呢?那就要看內存映射之後的幾個相關的過程了。

mmap()會返回一個指針ptr,它指向進程邏輯地址空間中的一個地址,這樣以後,進程無需再調用read或write對文件進行讀寫,而只需要通過ptr就能夠操作文件。但是ptr所指向的是一個邏輯地址,要操作其中的數據,必須通過內存管理單元MMU將邏輯地址轉換成物理地址,如圖1中過程2所示。這個過程與內存映射無關。

前面講過,建立內存映射並沒有實際拷貝數據,這時,MMU在地址映射表中是無法找到與ptr相對應的物理地址的,也就是MMU失敗,將產生一個缺頁中斷,缺頁中斷的中斷響應函數會在swap中尋找相對應的頁面,如果找不到(也就是該文件從來沒有被讀入內存的情況),則會通過mmap()建立的映射關係,從硬盤上將文件讀取到物理內存中,如圖1中過程3所示。這個過程與內存映射無關。

如果在拷貝數據時,發現物理內存不夠用,則會通過虛擬內存機制(swap)將暫時不用的物理頁面交換到硬盤上,如圖1中過程4所示。這個過程也與內存映射無關。

所以當mongodb讀取數據庫文件的時候,首先做內存映射,讀取文件變成了讀取內存操作,所以mongodb的查詢效率相當高,當然,如果你的內存不夠大,經常發生缺頁中斷,那麼效率會大打折扣了

Mongodb學習整理之內存映射機制

認真分析mmap:是什麼 爲什麼 怎麼用

從內核文件系統看文件讀寫過程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章