概述
最近在搞一個小東西,要使用Linux的sar -B命令裳瘪。而后我發(fā)現(xiàn)一個小問題,就是那些輸出項(xiàng)的含義罪针,明面上一眼就能看懂彭羹,但是仔細(xì)思考,卻有點(diǎn)拿捏不定它對系統(tǒng)的影響泪酱。
所以查找了一些資料派殷,記錄一下我對這些輸出的理解。這篇文章會從Linux內(nèi)核的角度去看待那些輸出墓阀。
在Ubuntu 18.04上執(zhí)行man sar能夠看到-B選項(xiàng)的含義:Report paging statistics.
執(zhí)行之后的樣子形如:
同樣在man sar里面也有解釋每一個條目的意思毡惜,熟悉的讀者可以直接跳過這個部分:
- pgpgin/s: Total number of kilobytes the system paged in from disk per second.
- pgpgout/s: Total number of kilobytes the system paged out to disk per second.
- fault/s: fault/s: Number of page faults (major + minor) made by the system per second. This is not a count of page faults that generate I/O, because some page faults can be resolved without I/O.
- majflt/s: Number of major faults the system has made per second, those which have required loading a memory page from disk.
pgfree/s: Number of pages placed on the free list by the system per second.
pgscank/s: Number of pages scanned by the kswapd daemon per second.
pgscand/s: Number of pages scanned directly per second.
pgsteal/s: Number of pages the system has reclaimed from cache (pagecache and swapcache) per second to satisfy its memory demands.
%vmeff: Calculated as pgsteal / pgscan, this is a metric of the efficiency of page reclaim. If it is near 100% then almost every page coming off the tail of the inactive list is being reaped. If it gets too low (e.g. less than 30%) then the virtual memory is having some difficulty. This field is displayed as zero if no pages have been scanned during the interval of time.
選項(xiàng)含義
如果學(xué)過操作系統(tǒng)原理,那么對上面的很多條目都有一些熟悉感∷勾椋現(xiàn)代計(jì)算機(jī)的內(nèi)存管理基本上都是一個套路经伙,這個套路就是分頁(Paging)。一般而言勿锅,操作系統(tǒng)將虛擬地址空間劃分成固定大小的“頁(Page)”帕膜,比如說,現(xiàn)在的Linux默認(rèn)使用的頁大小是4KB溢十,該參數(shù)可以通過命令getconf PAGESIZE
查看垮刹。操作系統(tǒng)使用頁表來管理頁。而且张弛,最重要的是荒典,頁是操作系統(tǒng)內(nèi)存管理的最小單元。
但是吞鸭,系統(tǒng)運(yùn)行的進(jìn)程所要求的內(nèi)存寺董,往往大于實(shí)際的物理內(nèi)存的大小,在狼多肉少的情況下刻剥,就要考慮怎么合理分配資源螃征。于是就誕生了一種稱為swap的技術(shù)。swap其實(shí)很簡單透敌,就是在物理內(nèi)存不足的時候盯滚,操作系統(tǒng)考慮將一部分內(nèi)存數(shù)據(jù)“刷”到文件系統(tǒng)中(簡單來說踢械,就是磁盤上)。而Linux為了提高讀寫效率魄藕,會將一部分文件緩存在內(nèi)存中内列,那么也會逐漸消耗完所有的物理內(nèi)存。這個時候背率,一般會將一些很長時間沒有運(yùn)行的程序交換到磁盤上话瞧,以釋放出內(nèi)存供新的程序使用。
pgpgin/s和pgpgout/s
到這里寝姿,也就是了解了pgpgin/s和pgpgout/s兩個指標(biāo)的意義交排。它們展示的就是Linux系統(tǒng)在每秒內(nèi),換進(jìn)換出的內(nèi)存大小饵筑。注意的是埃篓,這兩個指標(biāo)的單位是KB,而不是頁數(shù)根资〖茏ǎ可以想到的是,這兩個指標(biāo)玄帕,越大表明物理內(nèi)存越不夠部脚。直接訪問內(nèi)存和從swap中加載比起來,要快至少一個數(shù)量級裤纹。因此委刘,這兩個數(shù)字越高,性能懲罰也就越嚴(yán)重鹰椒。
我看過一個典型的案例钱雷,就是在JVM內(nèi)存回收的時候,因?yàn)橐獟呙璐婊顚ο蟠盗悖|發(fā)了大量的pagein和pageout罩抗,導(dǎo)致垃圾回收時間顯著拉長。
這里要額外討論的一個是灿椅,Linux系統(tǒng)下有一個參數(shù)可以控制操作系統(tǒng)在什么情況下開始將內(nèi)存交換到磁盤上:swappiness
套蒂。這個參數(shù)假如設(shè)置到10,那么表明物理內(nèi)存使用到90%的時候就會開始交換茫蛹。很多應(yīng)用的性能都會受到該設(shè)置的影響操刀,典型的如kafka。kafka就是利用page cache將隨機(jī)寫轉(zhuǎn)化為順序?qū)懸垣@得良好的性能婴洼。該參數(shù)可以通過命令cat /proc/sys/vm/swappiness
來查看骨坑。比如在我買的貧下中農(nóng)版阿里云上,該值是60。
fault/s和majflt/s
這兩個選項(xiàng)欢唾,只是說了一件事且警,就是頁錯誤(Page Fault,也叫頁缺失)礁遣,與之相關(guān)的一個耳熟能詳?shù)臇|西就是缺頁中斷斑芜。它是指程序試圖訪問一個存在于虛擬地址空間,但是并未被映射到實(shí)際物理內(nèi)存的情況祟霍。
頁缺失一般來說有兩種(那種訪問的地址都不在虛擬地址空間的錯誤杏头,我覺得怎么都不算頁缺失……):Major Page Fault和Minor Page Fault:
Major Page Fault: 這個就是通俗意義上的頁缺失,也就是該頁在此時并沒有被加載到物理內(nèi)存中沸呐。操作系統(tǒng)這個時候就要找到一個空閑的頁醇王,或者一個使用中的頁,寫到磁盤上崭添,然后從MMU中注銷寓娩;而后讀入選定的頁,并向MMU注冊滥朱。這一大串的操作下來,基本上可以判定力试,性能降低了極多徙邻;
Minor Page Fault: 一般人都不知道這個鬼東西,尤其是那些使用高級編程語言的(越高級越不知道)畸裳。出現(xiàn)這種情況的最常見的原因就是進(jìn)程共享內(nèi)存缰犁,操作系統(tǒng)為其中的一些程序注冊了該頁,但是并沒有為另外的程序注冊怖糊。另外一種可能是帅容,在MMU上注銷了,但是還沒來得及刷新到磁盤伍伤。不論是哪種情況并徘,可以肯定的是該頁一定已經(jīng)在物理內(nèi)存中了,操作系統(tǒng)只需要付出少量的代價(jià)就能恢復(fù)過來扰魂;
很顯然麦乞,這兩個選項(xiàng)和前面提到的pgpgin/s、pgpgout/s有很強(qiáng)的關(guān)聯(lián)性劝评〗阒保基本上,它們的變化趨勢是一致的蒋畜。數(shù)值越大声畏,也意味著性能越糟糕。尤其是majflt/s的數(shù)值姻成。而fault/s和majflt/s的差則能計(jì)算出Minor Page Fault——該值如果很大插龄,也是一個很奇怪的地方愿棋,要小心優(yōu)化了。
pgfree/s
這個選項(xiàng)很簡單辫狼,就是每秒放回空閑鏈表的頁的數(shù)量初斑。
Linux是使用空閑鏈表的方法來管理內(nèi)存的。當(dāng)一個頁不再被使用的時候膨处,它就會被放回去空閑鏈表见秤。
理論上來說,這個值高點(diǎn)可能會比較好真椿。但是我對此持有一種懷疑的態(tài)度鹃答。因?yàn)閜gfree/s每秒越高,意味著每秒有很多進(jìn)程釋放了內(nèi)存突硝,但是测摔,如果一直持續(xù)一段時間,是否也意味著進(jìn)程在頻繁的申請內(nèi)存解恰,而后又釋放锋八?
畢竟,池子的水就那么多护盈,頻繁的往里面倒水挟纱,也意味著有人頻繁的從里面舀水,畢竟也沒別的池子可以搞到水了腐宋。
pgscank/s和pgscand/s
pgscank我猜測是page scanned by kswapd的簡寫紊服,而s和pgscand則是page scanned directly的簡寫。
kswapd是Kernel Swap Daemon的簡寫胸竞。它代表的是一個內(nèi)核線程欺嗤。該線程的任務(wù)是“keep the memory management system operating efficiently”。大體上來說卫枝,它就是一個定時任務(wù)煎饼,定時查看系統(tǒng)的空閑頁,如果數(shù)量比較少校赤,它叫要開始將頁置換出去磁盤腺占,以騰出物理內(nèi)存。一般來說痒谴,它會清理page cache(kafka再次中槍)衰伯、共享頁面和discarding pages。有意思的是积蔚,這個線程并不是一次清理完這些東西意鲸,而是清理個四個頁面就收手了。感覺就是為了避免一次清理太多影響正在運(yùn)行的進(jìn)程。
而pgscand則可以理解為kswapd的同步版本怎顾。我覺得读慎,pgscand的數(shù)值大應(yīng)該比pgscank數(shù)值大更加可怕。
pgsteal/s
這個選項(xiàng)槐雾,就是代表每秒從page cache和swap cache中回收的頁數(shù)量夭委。它和pgscank/s、pgscand/s有很強(qiáng)的相關(guān)性募强。要知道的是株灸,操作系統(tǒng)會盡量避免頻繁的IO操作,畢竟IO操作太消耗資源了擎值。所以才會page cache和swap cache兩個東西慌烧,它們分別表示的是映射到磁盤的內(nèi)存緩存和映射到交換區(qū)的內(nèi)存緩存。所以這個參數(shù)代表的是刷新到磁盤的頻率鸠儿。
影響到磁盤刷新page cache的參數(shù)主要有兩個vm.dirty_ratio和vm.dirty_background_ratio屹蚊。
%vmeff
理解了前面的參數(shù),理解這個就不難了进每,它是pgsteal/pgscan的值汹粤,實(shí)際上也就是pgsteal/(pgscank+pgscand)。它后面還有一大段的話田晚≈黾妫總結(jié)下來就是這個東西越低就越糟糕。
我現(xiàn)在嘗試解釋一下這個東西肉瓦。前面提到過遭京,page scan其實(shí)就是要找到可以回收的頁胃惜,而后將對應(yīng)的物理內(nèi)存釋放出來泞莉;而前面還提到,操作系統(tǒng)會盡量避免IO操作船殉,所以鲫趁,也就是意味著,page scan得到的頁利虫,并不會直接被寫到磁盤里面挨厚。
于是就出現(xiàn)了這樣的情況,page scan得到的也還繼續(xù)駐留在物理內(nèi)存里面糠惫,期望得到釋放的內(nèi)存并沒有被釋放疫剃。所以才會有越低越糟糕的說法。
但是一個很奇特的是硼讽,如果page scan得到的結(jié)果是0(也就是分母是0)巢价,那么結(jié)果也是0.所以0通常會有兩種可能,一種就是page scan為0個頁面,這當(dāng)然算是好事(壤躲?)城菊。因?yàn)橹拔覀兲岬秸f,如果要是內(nèi)存不足的話碉克,kswapd就會清理一些頁面凌唬。
另外一種可能就是,page steal為0漏麦。這就很可怕了客税,它表示在采集數(shù)據(jù)的這個時間間隔內(nèi),沒有任何的page cache和swap cache被刷新到磁盤唁奢。
所以霎挟,保險(xiǎn)起見,要是這個數(shù)值低了麻掸,或者為0酥夭,都要引起重視了。
歡迎關(guān)注公眾號: