hadoop集群swap_性能瓶颈--MEM(swap)
內存的性能瓶頸主要集中在兩點,一個是內存不足,一個是沒有充分的利用buffer/cache 。
這里先介紹內存資源不足吧,畢竟應用程序不在 buffer/cache 里讀寫的可能性不大,除非程序員自己設置直接I/O。否則至少也用的是緩存I/O。當然一些動態鏈接庫也有自己的緩存。
內存回收
當有內存資源不足的時候,就會導致內存回收,也就是釋放掉回收的內存,比如buffer/cache 就屬于可回收內存,他們在內存管理中叫做文件頁(File-backend Page)。大部分的文件頁都可以直接回收,以后有需要的時候,再從磁盤重新讀取,而那些已經被應用程序改過的,暫時還沒有寫入磁盤的數據,在內存管理中就叫臟頁。需要先寫到磁盤中,內存才能得到釋放。
當然這些臟頁一般通過2種方式寫入磁盤,
應用程序中的fsync
內核線程pdflush
除了文件頁之外,另一種就是匿名頁(Anonymous Page),這些可以是應用程序動態分配的堆內存,這些可以被回收么?當然不能直接回收,要不程序再次訪問自己申請的內存時,內存資源突然不見,這可怎么整。但這些內存很少被訪問,所以會被放到磁盤中。當再次訪問時,會發生主缺頁異常(major page faults),再重新加載進內存中。這就是linux中的swap機制。
swap原理
swap說白了就是把一塊磁盤空間或者一個本地文件當成內存使用。他包含了換入和換出的兩個過程。
換出:就是把進程暫時不用的內存數據存儲到磁盤上,并釋放這些數據占用的內存。
換入:進程再次訪問內存時,從磁盤重新讀入內存中。
也就是linux在內存回收方面,做了兩件事。
直接內存回收:回收一部分緩存,進而滿足新內存的申請請求。
定期內存回收:內核通過kswapd0定期回收內存。
什么時候會定期內存回收
定期回收內存是由內核進程kswapd0來進行的。為了衡量內存的使用情況,kswapd0定義了三個閾值。
內存使用閾值
kswapd0是根據三個閾值進行內存的回收操作的。
當剩余內存小于頁最小閾值時,只有內核才可以分配新的內存。
當剩余內存大于頁最小閾值并小于頁底閾值時,說明此時內存壓力巨大,此時wswapd0會一直回收內存,直到內存大于高閾值。
當剩余內存大于頁底閾值并小于頁高閾值,說明內存存在一定的壓力,但還算滿足新的內存申請。
當剩余內存大于頁高閾值時,說明內存無壓力。
當剩余內存小于頁底閾值就會觸發內存回收,這個頁底閾值一般是通過內核選項 /proc/sys/vm/min_free_kbytes 設置。
$ cat /proc/sys/vm/min_free_kbytes
67584
而剩余的兩個閾值是由頁底閾值計算生成的。
pages_low = pages_min*5/4
pages_high = pages_min*3/2
在 /proc/zoneinfo中可以看到當前的三個閾值
$ cat /proc/zoneinfo
Node 0, zone DMA
pages free 3840
min 69
low 86
high 103
scanned 0
spanned 4095
present 3997
managed 3976
nr_free_pages 3840
nr_alloc_batch 17
nr_inactive_anon 21
nr_active_anon 8
nr_inactive_file 13
nr_active_file 0
這里的 min、low、high是內存頁數的閾值。free是剩余內存頁數。
nr_zone_active_anon 和 nr_zone_inactive_anon ,分別是活躍和非活躍的匿名頁數。
nr_zone_active_file 和 nr_zone_inactive_file ,分別是活躍和非活躍的文件頁數。
swap的回收偏向
上面只是說了什么時候會回收內存,但剛才也說到了,內存不夠了,一種方式是釋放文件頁。另一種方式就是將匿名頁寫入到磁盤(swap)。
兩種方式,linux更傾向于哪一種呢?
內核參數 /proc/sys/vm/swappiness 。是用來調整swap的積極性的,也就是說這個參數越高,內存的回收更傾向于swap機制,反則傾向于釋放buffer/cache 。但這個參數設置為0 并不代表就不會使用swap了。
swap好嗎?
實則根據業務場景,大部分應用都不需要開啟swap的。在hadoop,es等java應用其實都是應該關閉swap的,因為java代碼在gc時,會遍歷所有用到的堆內存,如果這部分內存是在swap上,遍歷操作可能就變成磁盤io了。
swap是針對小內存的一種優化,現在的線上服務器動輒128G內存,所以沒必要開啟swap。如果要開啟的話,也是建議將 /proc/swappiness 設置一個較小的值,如10。
另一種場景下,kubernets集群一般會關閉swap。因為開啟swap后,通過cgroups設置的內存上限會失效。
響應延遲敏感性的應用如果在開啟swap的服務器上運行的話,可以使用庫函數 mlock() 或者 mlockall() 鎖定內存,阻止內存的換出和換進。
另一個就是numa架構,非一致性內存訪問。這個最好也關掉,跨node訪問也會造成嚴重的性能問題。
我的應用開始使用swap了?
既然swap會造成應用程序的性能問題,那么怎么知道我的某個具體的程序開始使用swap了?
$ pidstat -r 1
Linux 3.10.0-957.el7.x86_64 (vm1.centos7.com) 2019年04月05日 _x86_64_ (2 CPU)
09時21分41秒 UID PID minflt/s majflt/s VSZ RSS %MEM Command
09時21分42秒 0 10445 353.85 0.00 108380 1168 0.03 pidstat
pidstat -r 表示的就是單個應用程序的內存使用情況。
minflt/s : 每秒次缺頁錯誤次數(minor page faults),次缺頁錯誤次數意即虛擬內存地址映射成物理內存地址產生的page fault次數。
majflt/s : 每秒主缺頁錯誤次數(major page faults),當虛擬內存地址映射成物理內存地址時,相應的page在swap中,這樣的page fault為major page fault,一般在內存使用緊張時產生。
也就是說如果某個應用程序有majflt/s 了,表示其開始使用swap了。其性能當然也會下降。
總結
以上是生活随笔為你收集整理的hadoop集群swap_性能瓶颈--MEM(swap)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 牙根尖周炎要怎么治疗
- 下一篇: 尿流率是什么