開源技術分享:Linux 核心參數 swappiness細解

來源:互聯網
上載者:User

標籤:into   wan   交換分區   ref   緩衝   並且   ever   res   cti   

本篇文章主要是就swappiness的一個源碼上的解析(基於kernel版本 v4.14-13151-g5a787756b809),僅為個人見解,有不足歡迎相互交流。

關於Swap和swappiness

Swap(交換分區)是作業系統就記憶體不足的一個緩解。當記憶體緊張時候,會適當的根據一些配置值和當前的統計值進行一次判斷,會把一些anon記憶體(分配出去的記憶體)交換到Swap分區中。

Swappiness是系統的一個參數,可以調節swap的使用優先順序。Linux文檔描述如下:

swappiness

This control is used to define how aggressive the kernel will swap
memory pages. Higher values will increase aggressiveness, lower values
decrease the amount of swap. A value of 0 instructs the kernel not to
initiate swap until the amount of free and file-backed pages is less
than the high water mark in a zone.

The default value is 60.

翻譯過來就是
這個參數是定義核心交換記憶體頁的×××性(aggressive)。更大的值將增加×××性,較低的值會減少swap的數量。0值會命令核心不要使用swap,只有當free和檔案使用的記憶體頁數量少於一個zone的高水位,才會使用swap。

預設值是60。

關於這裡的aggressive,看的是雲裡霧裡。只知道這個值大概意義。在一些環境,使用者一直抱怨為什麼Swap使用量這麼多,明明還有挺多的available記憶體。

Linux記憶體申請

Linux 記憶體申請一般來說會打上一些flag標誌,會對申請流程產生一些影響,這裡不細講。主要是講一般情況下(使用者態的申請和大部分核心態的社區都是可以等待記憶體釋放的)的記憶體申請。

__alloc_pages 一般第一次遍曆每一個記憶體地區(zone)尋找第一個可用的足夠的記憶體塊。如果一個地區滿了,那麼會尋找下一個地區。單數如果 CPUSETS被設定了,他就會觸發記憶體reclaim回收。

這裡Swappiness主要是在記憶體reclaim時候生效。

Reclaim的方式

基本上Reclaim的方式為一個是將file相關的記憶體進行回收,一個是將anon部分記憶體(即被分配出去的記憶體)交換到Swap分區。
Linux的記憶體使用量的一個宗旨是儘可能使用記憶體。在檔案被讀寫的時候,檔案的cache會一直保留在系統記憶體中,一直到記憶體不夠時候,沒有主動釋放這部分記憶體的邏輯。這樣在下次讀取被緩衝的檔案時候可以直接從記憶體讀取,不必從磁碟進行IO操作,這樣檔案讀取速度會更加快速。

造成的結果是其實available的記憶體還很多的情況下,仍然會有記憶體不夠,觸發Reclaim邏輯,將一部分記憶體交換到Swap分區。

Swappiness生效方式

Swappiness是在get_scan_count函數使用的。
如下代碼顯示:Swap滿時候,這個參數無影響。

2195 / If we have no swap space, do not bother scanning anon pages. /
2196 if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) {
2197 scan_balance = SCAN_FILE;
2198 goto out;
2199 }

在Cgroup的mem還沒達到limit時候,並且Swappiness為0,也僅僅掃描file cache部分。即不會考慮交換出去。

2201 /
2202
Global reclaim will swap to prevent OOM even with no
2203 swappiness, but memcg users want to use this knob to
2204
disable swapping for individual groups completely when
2205 using the memory controller‘s swap limit feature would be
2206
too expensive.
2207 */
2208 if (!global_reclaim(sc) && !swappiness) {
2209 scan_balance = SCAN_FILE;
2210 goto out;
2211 }

當系統接近OOM時候,並且swapiness非0,那麼會平等的掃描anon和file的記憶體。

2213 /
2214
Do not apply any pressure balancing cleverness when the
2215 system is close to OOM, scan both anon and file equally
2216
(unless the swappiness setting disagrees with swapping).
2217 */
2218 if (!sc->priority && swappiness) {
2219 scan_balance = SCAN_EQUAL;
2220 goto out;
2221 }
當記憶體達到limit時候,會只釋放申請的記憶體。這裡結合前面提到的分支,可以知道,當Swappiness為0時候,沒有達到limit只釋放file cache,當達到limit時候,才考慮切換記憶體到swap中。

    /*     * Prevent the reclaimer from falling into the cache trap: as     * cache pages start out inactive, every cache fault will tip     * the scan balance towards the file LRU.  And as the file LRU     * shrinks, so does the window for rotation from references.     * This means we have a runaway feedback loop where a tiny     * thrashing file LRU becomes infinitely more attractive than     * anon pages.  Try to detect this based on file LRU size.     */    if (global_reclaim(sc)) {            unsigned long pgdatfile;            unsigned long pgdatfree;            int z;            unsigned long total_high_wmark = 0;            pgdatfree = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES);            pgdatfile = node_page_state(pgdat, NR_ACTIVE_FILE) +                       node_page_state(pgdat, NR_INACTIVE_FILE);            for (z = 0; z < MAX_NR_ZONES; z++) {                    struct zone *zone = &pgdat->node_zones[z];                    if (!managed_zone(zone))                            continue;                    total_high_wmark += high_wmark_pages(zone);            }            if (unlikely(pgdatfile + pgdatfree <= total_high_wmark)) {                    /*                     * Force SCAN_ANON if there are enough inactive                     * anonymous pages on the LRU in eligible zones.                     * Otherwise, the small LRU gets thrashed.                     */                    if (!inactive_list_is_low(lruvec, false, memcg, sc, false) &&                        lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, sc->reclaim_idx)                                    >> sc->priority) {                            scan_balance = SCAN_ANON;                            goto out;                    }            }    }

當inactive的cache頁足夠的時候,只釋放file cache。

    /*     * If there is enough inactive page cache, i.e. if the size of the     * inactive list is greater than that of the active list *and* the     * inactive list actually has some pages to scan on this priority, we     * do not reclaim anything from the anonymous working set right now.     * Without the second condition we could end up never scanning an     * lruvec even if it has plenty of old anonymous pages unless the     * system is under heavy pressure.     */    if (!inactive_list_is_low(lruvec, true, memcg, sc, false) &&        lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, sc->reclaim_idx) >> sc->priority) {            scan_balance = SCAN_FILE;            goto out;    }

這裡強調一下,swappiness的一般作用這裡開始涉及。是把anon_prio設成相應的swappiness,file_prio 設成200-anon_prio。

    scan_balance = SCAN_FRACT;    /*     * With swappiness at 100, anonymous and file have the same priority.     * This scanning priority is essentially the inverse of IO cost.     */    anon_prio = swappiness;    file_prio = 200 - anon_prio;

這裡進一步使用anon_prio和file_prio來擷取ap和fp

    /*     * The amount of pressure on anon vs file pages is inversely     * proportional to the fraction of recently scanned pages on     * each list that were recently referenced and in active use.     */    ap = anon_prio * (reclaim_stat->recent_scanned[0] + 1);    ap /= reclaim_stat->recent_rotated[0] + 1;    fp = file_prio * (reclaim_stat->recent_scanned[1] + 1);    fp /= reclaim_stat->recent_rotated[1] + 1;

具體其他的細節或者後續的演算法,留待後續分析。

總結

Swappiness的控制方式主要是在記憶體緊張時候才會觸發(這裡是指free的記憶體低)。具體如下:

  1. 當swappiness為0,那麼在available記憶體充足情況,只釋放file cache,當available記憶體不足情況下,那麼會將一些記憶體交換到swap空間。
  2. Swappiness不為0,那麼他的值大小主要是控制每次記憶體緊張時候,切換到swap和檔案快取釋放的比例。

注意:大部分人誤以為是控制記憶體剩餘比例到swappiness值時,去切換記憶體到swap,這個是錯誤的。

開源技術分享:Linux 核心參數 swappiness細解

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.