Linux Kernel Shared Memory 剖析

來源:互聯網
上載者:User

看到這篇文章的時候,感覺只有兩個字:鬱悶。還在Linux-2.6.29的時候,就看是看Linux kernel virtual machine,那時候就感覺多個VM肯定有很多的記憶體是共用的,完全可以合并,沒想到Linux的發展是這麼的快,linux-2.6.32就正式的支援了ksm機制,實現了共用記憶體的合并,而且還是專門針對虛擬機器的,真是讓我抓狂,都是可惡的項目,全是在浪費時間。下面轉載ksm相關的一篇文章,學習之餘做個記錄,已備畢業設計只需。

 

簡介: 作為一個系統管理程式(hypervisor),Linux 有幾個創新,2.6.32 核心中一個有趣的變化是 Kernel Shared Memory (KSM)。KSM 允許這個系統管理程式通過合并記憶體頁面來增加並發虛擬機器的數量。本文探索 KSM 背後的理念(比如儲存去耦合)、KSM 的實現、以及如何管理 KSM。

伺服器虛擬化

虛擬化技術從上世紀 60 年代開始出現,經由 IBM System/360 大型主機得以流行。50 年過後,虛擬化技術取得了跨越式發展,使得多個作業系統和應用程式共用一個伺服器成為可能。這一特殊用途(稱為伺服器虛擬化)正在演變為資料中心,因為單個物理機能夠用於託管 10 個(一般情況)或更多虛擬機器(VM), 1 所示。這種虛擬化使基礎設施更動態、更省電、(因而也)更經濟。

 

頁面都是相同的。假如作業系統和應用程式代碼以及常量資料在 VMs 之間相同,那麼這個特點就很有用。當頁面惟一時,它們可以被合并,從而釋放記憶體,供其他應用程式使用。圖 2 示範了記憶體共用,並展示了在內容相同的 VMs 之間共用頁面時更多可用閑置記憶體的好處。
圖 2. 跨 VMs 的記憶體共用
 

特性命名

本文描述的特性非常新;因此,其名稱經曆了一些變化。您將發現這個 Linux 核心特性稱為 Kernel Shared MemoryKernel Samepage Merging

您很快就會發現,儘管 Linux 中的記憶體共用在虛擬環境中有優勢(KSM 最初設計用於基於核心的虛擬機器),但它在非虛擬環境中仍然有用。事實上,KSM 甚至在嵌入式 Linux 系統中也有用處,表明了這種方法的靈活性。下面,我們將探索這種 Linux 記憶體共用方法,以及如何使用該方法提高伺服器的記憶體密度,從而增加其託管其他應用程式或 VMs 的能力。

其他支援人員

儲存技術中的一個稱為去耦合(de-duplication)的最新進展是 Linux 和其他系統管理程式中的記憶體共用的先驅。去耦合這種技術通過刪除冗餘資料(基於資料區塊,或者基於更大的資料片段,比如檔案)來減少已儲存的資料。公用資料片段被合并(以一種 copy-on-write [CoW] 方式),釋放空間供其他用途。使用這種方法,儲存成本更低,最終需要的儲存空間也更少。鑒於當前的資料增長速度,這個功能顯得非常重要。

KSM 操作

KSM 作為核心中的守護進程(稱為 ksmd)存在,它定期執行頁面掃描,識別副本頁面併合並副本,釋放這些頁面以供它用。KSM 執行上述操作的過程對使用者透明。例如,副本頁面被合并(然後被標記為唯讀),但是,如果這個頁面的其中一個使用者由於某種原因更改該頁面,該使用者將(以 CoW 方式)收到自己的副本。可以在核心原始碼 ./mm/ksm.c 中找到 KSM 核心模組的完整實現。

KSM 依賴進階應用程式程式來提供指導,根據該指導確定合并的候選記憶體地區。儘管 KSM 可以只掃描系統中的匿名頁面,但這將浪費 CPU 和記憶體資源(考慮到管理頁面合并進程所需的空間)。因此,應用程式可以註冊可能包含副本頁面的虛擬地區。

KSM API(API)通過 madvise 系統調用(見清單 1)和一個新的建議參數(advice parameter)MADV_MERGEABLE(表明已定義的地區可以合并)來實現。可以通過 MADV_UNMERGEABLE 參數(立即從一個地區取消合并任何已合并頁面)從可合并狀態刪除一個地區。注意,通過 madvise 來刪除一個頁面地區可能會導致一個 EAGAIN 錯誤,因為該操作可能會在取消合并過程中耗盡記憶體,從而可能會導致更大的麻煩(記憶體不足情況)。

清單 1. madvise 系統調用

#include <sys/mman.h>int madvise( void *start, size_t length, int advice );

一旦某個地區被定義為 “可合并”,KSM 將把該地區添加到它的工作記憶體列表。啟用 KSM 時,它將搜尋相同的頁面,以防寫保護的 CoW 方式保留一個頁面,釋放另一個頁面以供它用。

KSM 使用的方法與記憶體去耦合中使用的方法不同。在傳統的去耦合中,對象被散列化,然後使用散列值進行初始相似性檢查。當散列值一致時,下一步是進行一個實際對象比較(本例中是一個記憶體比較),以便正式確定這些對象是否一致。KSM 在它的第一個實現中採用這種方法,但後來開發了一種更直觀的方法來簡化它。

在當前的 KSM 中,頁面通過兩個 “紅-黑” 樹管理,其中一個 “紅-黑” 樹是臨時的。第一個樹稱為不穩定樹,用於儲存還不能理解為穩定的新頁面。換句話說,作為合并候選對象的頁面(在一段時間內沒有變化)儲存在這個不穩定樹中。不穩定樹中的頁面不是防寫保護的。第二個樹稱為穩定樹,儲存那些已經發現是穩定的且通過 KSM 合并的頁面。為確定一個頁面是否是穩定頁面,KSM 使用了一個簡單的 32 位校正和(checksum)。當一個頁面被掃描時,它的校正和被計算且與該頁面儲存在一起。在一次後續掃描中,如果新計算的校正和不等於此前計算的校正和,則該頁面正在更改,因此不是一個合格的合并候選對象。

使用 KSM 進程處理一個單一的頁面時,第一步是檢查是否能夠在穩定樹中發現該頁面。搜尋穩定樹的過程很有趣,因為每個頁面都被視為一個非常大的數字(頁面的內容)。一個 memcmp(記憶體比較)操作將在該頁面和相關節點的頁面上執行。如果 memcmp 返回 0,則頁面相同,發現一個匹配值。反之,如果 memcmp 返回 -1,則表示候選頁面小於當前節點的頁面;如果返回 1,則表示候選頁面大於當前節點的頁面。儘管比較 4KB 的頁面似乎是相當重量級的比較,但是在多數情況下,一旦發現一個差異,memcmp 將提前結束。請參見圖 3 查看這個過程的視覺呈現。

圖 3. 搜尋樹中的頁面的搜尋過程


 

如果候選頁面位於穩定樹中,則該頁面被合并,候選頁面被釋放。有關代碼位於 ksm.c/stable_tree_search()(稱為 ksm.c/cmp_and_merge_page())中。反之,如果沒有發現候選頁面,則應轉到不穩定樹(參見 ksm.c/unstable_tree_search())。

在不穩定樹中搜尋時,第一步是重新計算頁面上的校正和。如果該值與原始校正和不同,則本次掃描的後續搜尋將拋棄這個頁面(因為它更改了,不值得跟蹤)。如果校正和沒有更改,則會搜尋不穩定樹以尋找候選頁面。不穩定樹的處理與穩定樹的處理有一些不同。第一,如果搜尋代碼沒有在不穩定樹中發現頁面,則在不穩定樹中為該頁面添加一個新節點。但是如果在不穩定樹中發現了頁面,則合并該頁面,然後將該節點遷移到穩定樹中。

當掃描完成(通過 ksm.c/ksm_do_scan() 執行)時,穩定樹被儲存下來,但不穩定樹則被刪除並在下一次掃描時重新構建。這個過程大大簡化了工作,因為不穩定樹的組織方式可以根據頁面的變化而變化(還記得不穩定樹中的頁面不是防寫保護的嗎?)。由於穩定樹中的所有頁面都是防寫保護的,因此當一個頁面試圖被寫入時將產生一個頁面故障,從而允許 CoW 進程為寫入程式取消頁面合并(請參見 ksm.c/break_cow())。穩定樹中的孤立頁面將在稍後被刪除(除非該頁面的兩個或更多使用者存在,表明該頁面還在被共用)。

如前所述,KSM 使用 “紅-黑” 樹來管理頁面,以支援快速查詢。實際上,Linux 包含了一些 “紅-黑” 樹作為一個可重用的資料結構,可以廣泛使用它們。“紅-黑” 樹還可以被 Completely Fair Scheduler (CFS) 使用,以便按時間順序儲存任務。您可以在 ./lib/rbtree.c 中找到 “紅-黑” 樹的這個實現。

KSM 配置和監控

KSM 的管理和監控通過 sysfs(位於根 /sys/kernel/mm/ksm)執行。在這個 sysfs 子目錄中,您將發現一些檔案,有些用於控制,其他的用於監控。

第一個檔案 run 用於啟用和禁用 KSM 的頁面合并。預設情況下,KSM 被禁用(0),但可以通過將一個 1 寫入這個檔案來啟用 KSM 守護進程(例如,echo 1 > sys/kernel/mm/ksm/run)。通過寫入一個 0,可以從運行狀態禁用這個守護進程(但是保留合并頁面的當前集合)。另外,通過寫入一個 2,可以從運行狀態(1)停止 KSM 並請求取消合并所有合并頁面。

KSM 運行時,可以通過 3 個參數(sysfs 中的檔案)來控制它。sleep_millisecs 檔案定義執行另一次頁面掃描前 ksmd 休眠的毫秒數。max_kernel_pages 檔案定義 ksmd 可以使用的最大頁面數(預設值是可用記憶體的 25%,但可以寫入一個 0 來指定為無限)。最後,pages_to_scan 檔案定義一次給定掃描中可以掃描的頁面數。任何使用者都可以查看這些檔案,但是使用者必須擁有根許可權才能修改它們。

還有 5 個通過 sysfs 匯出的可監控檔案(均為唯讀),它們表明 ksmd 的運行情況和效果。full_scans 檔案表明已經執行的全地區掃描的次數。剩下的 4 個檔案表明 KSM 的頁面級統計資料:

  • pages_shared:KSM 正在使用的不可交換的核心頁面的數量。
  • pages_sharing:一個記憶體儲存指示。
  • pages_unshared:為合并而重複檢查的惟一頁面的數量。
  • pages_volatile:頻繁改變的頁面的數量。

KSM 作者定義:較高的 pages_sharing/pages_shared 比率表明高效的頁面共用(反之則表明資源浪費)。

結束語

Linux 並不是使用頁面共用來改進記憶體效率的惟一系統管理程式,但是它的獨特之處在於將其實現為一個作業系統特性。VMware 的 ESX 伺服器系統管理程式將這個特性命名為 Transparent Page Sharing (TPS),而 XEN 將其稱為 Memory CoW。不管採用哪種名稱和實現,這個特性都提供了更好的記憶體利用率,從而允許作業系統(KVM 的系統管理程式)過量使用記憶體,支援更多的應用程式或 VM。 您可以在最新的 2.6.32 Linux 核心中發現 KSM — 以及其他很多有趣的特性。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.