Linux系統排查1——內存篇

  常見工做中,計算機系統的資源主要包括CPU,內存,硬盤以及網絡,過分使用這些資源將使系統陷入困境。本系列一共四篇博文,結合我在實習期間的學習,介紹一些常見的Linux系統排障工具及方法。html

  第1篇——內存篇node

  第2篇——CPU篇mysql

  第3篇——磁盤I/O篇sql

  第4篇——網絡篇vim

 

  事實上,當上述服務器系統資源中的任何一個遭遇瓶頸,都會帶來服務器性能的降低,典型的症狀就是系統運行遲緩。api

  本文從如下幾個角度介紹Linux系統內存相關的排查。緩存

  1. 內存的使用率如何查看,使用率真的很高嗎bash

  2. 內存用在哪裏了服務器

  3. 內存優化能夠有哪些手段網絡

 

1. 內存硬件查看

# dmidecode -t memory

# dmideocde -t memory
//如下爲命令輸出節選
# dmidecode 2.12
# SMBIOS entry point at 0x7f6be000
SMBIOS 2.5 present.

Handle 0x0005, DMI type 16, 15 bytes
Physical Memory Array
    Location: System Board Or Motherboard
    Use: System Memory
    Error Correction Type: Single-bit ECC
    Maximum Capacity: 192 GB
    Error Information Handle: Not Provided
    Number Of Devices: 18

Handle 0x0010, DMI type 6, 12 bytes
Memory Module Information
    Socket Designation: DIMM06
    Bank Connections: 0 0
    Current Speed: 1 ns
    Type: DIMM
    Installed Size: 8192 MB (Single-bank Connection)
    Enabled Size: 8192 MB (Single-bank Connection)
    Error Status: OK

Handle 0x0011, DMI type 17, 27 bytes
Memory Device
    Array Handle: 0x0005
    Error Information Handle: Not Provided
    Total Width: 72 bits
    Data Width: 64 bits
    Size: 8192 MB
    Form Factor: DIMM
    Set: None
    Locator: DIMM06
    Bank Locator: BANK06
    Type: Other
    Type Detail: Unknown
    Speed: 800 MHz
    Manufacturer: Hynix
    Serial Number: 5781322C
    Asset Tag: Unknown
    Part Number: HMT31GR7BFR4C-H9

 

  經過dmidecode工具能夠查看不少硬件相關的數據,這裏僅之內存爲例。咱們能夠看到,服務器最大支持內存擴充爲192GB,目前已經安裝了一塊海力士(Hynix)生產的8GB內存,該內存插在主板的第六個DIMM插槽上面(物理插槽又稱socket)。

  該命令可以給出物理內存的許多詳細信息,本文並不一一介紹。

 

2. 內存的大致使用狀況

free -m/-h

  free命令用來查看系統內存的總體使用狀況。

# free -m
             total       used       free     shared    buffers     cached
Mem:         11972       6345       5627          1        305       2140
-/+ buffers/cache:       3899       8073
Swap:          856          0        856

   free -m以MB爲單位顯示整個系統的內存使用狀況,free -h則自動選擇以適合理解的容量單位顯示:

# free -h
             total       used       free     shared    buffers     cached
Mem:           11G       6.2G       5.5G       1.2M       305M       2.1G
-/+ buffers/cache:       3.8G       7.9G
Swap:         856M         0B       856M

   能夠看到系統內存12GB(總可用11.7GB),當前已用6.2G,剩餘5.5GB。這個例子中咱們看到系統的內存使用並不高,但即使free命令顯示的"used"的值很高,接近total的值,那麼系統就真的沒有內存空間了嗎?

  咱們能夠看到free 命令下面有一行「-/+ buffers/cache」,該行顯示的used是上一行「used」的值減去buffers和cached的值,同時該行的free是上一行的free加上buffers和cached的值。這裏能夠看到,儘管第一行的used顯示共使用了6.2GB的物理內存,但除去buffers和cached數據後,實際僅僅佔用了3.8GB的內存,而若是剩餘空間加上buffers和cached數據當前佔用的內存,將達到8BG之多。

  這是由於buffers和cache數據是動態變化的,內存充足時,內核出於性能考慮會進行必定的緩存,當內存空間不足時,buffers, cached佔用的空間是能夠爲了程序釋放的。

  所以判斷系統內存是否耗竭的實際指標是看減去buffer和cache的空間後used空間是否依舊很大,以及交換空間是否被大量佔用。顯然這個例子不符合內存耗竭的情形。

  那麼buffers與cached又有什麼區別呢?

  (1) buffers:記錄文件系統的metadata,例如目錄裏面有什麼內容,權限等等;

  (2) cached:用來給文件作緩衝,緩存剛剛訪問的文件。

 

3. 哪些進程消耗內存比較多?

top

  top命令用來查看具體進程消耗的內存空間。

# top
top - 14:45:43 up 35 days, 2:54, 2 users, load average: 0.35, 0.23, 0.21 Tasks: 213 total, 3 running, 210 sleeping, 0 stopped, 0 zombie %Cpu(s): 2.1 us, 2.2 sy, 0.0 ni, 95.3 id, 0.3 wa, 0.0 hi, 0.1 si, 0.0 st KiB Mem: 12260128 total, 6502480 used, 5757648 free, 312864 buffers KiB Swap: 877564 total, 0 used, 877564 free. 2192620 cached Mem

 

  top 命令查看系統的實時負載, 包括進程、CPU負載、內存使用等等;

  進入top的實時界面後,默認按照CPU的使用率排序,經過「shift+m」按鍵將進程按照內存使用狀況排序,能夠查看哪些進程是當前系統中的內存開銷「大戶」。

  top命令中,按下 f 鍵,進入選擇排序列的界面,這裏能夠選擇要顯示的信息列,要按照哪些信息列進行排序等,該界面上有簡要的介紹,這裏再也不贅述。

  能夠看到top命令也會顯示系統總體的內存使用狀況,一樣包括了total, used, free, buffers, cached等,須要注意的是,這裏並無像free命令那樣提供-/+ buffers/cached以後的值,所以須要通過額外計算才能得到當前系統實際剩餘的可用內存。

  另外一方面,咱們查看不一樣進程的內存開銷,

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND    
 1501 mysql     20   0  655848 309724   9928 S   0.7  2.5 266:53.23 mysqld     
 2816 rabbitmq  20   0 2444216 248528   2612 S   1.7  2.0 868:40.86 beam.smp   
22589 nova      20   0  402236 144884   4084 S   0.0  1.2  17:42.08 nova-api   
22591 nova      20   0  401848 144508   4092 S   0.0  1.2  17:44.65 nova-api   
22590 nova      20   0  401312 143884   4068 S   0.0  1.2  17:47.23 nova-api   
22588 nova      20   0  400592 143260   4080 S   0.0  1.2  17:45.53 nova-api 

  經過%MEM列,能夠查看哪幾個進程佔用了大量的內存,在緩解內存不足的緊急狀況時,能夠終止這些佔用內存較多的進程。

  top命令中有如下與內存相關的數據列:

  (1)VIRT:虛擬內存,是進程申請的虛擬內存總量;

  (2)RES: 常駐內存,是進程切實使用的物理內存量,free命令中看到的used列下面的值,就包括常駐內存的加總,但不是虛擬內存的加總;

  (3)SHR:共享內存,好比共享庫佔用的內存等。

 

 4. 交換空間

# swapon
# swapoff
# mkswap

  使用free命令能夠查看內存的整體使用,顯示的內容也包括交換分區的大小,可使用swapon,swapoff,命令開啓或關閉交換空間,交換空間是磁盤上的文件,並非真正的內存空間。

例如:關閉交換分區

# swapoff -a
# free
             total       used       free     shared    buffers     cached
Mem:      12260128    6497332    5762796       1256     312980    2191960
-/+ buffers/cache:    3992392    8267736
Swap:            0          0          0

  此時交換分區顯示全爲0,說明系統沒有開啓交換分區。swapon命令能夠啓用交換分區。

  當內存不足時,系統會選擇經過:1.將部分不常被訪問的內存頁交換到內存空間,或2.刪除部分cache的文件來釋放內存空間。

  系統的可用內存通常等於物理內存 + 交換分區。交換分區在磁盤上, 所以速度比內存讀寫要慢得多。

  交換分區實際上就是磁盤上的文件,能夠經過mkswap命令來建立交換空間。

 

5. 內核態內存佔用

# slabtop

  slab系統用來處理系統中比較小的元數據,如文件描述符等,進而組織內核態的內存分配。

  一個slab包含多個object,例如dentry這些數據結構就是object,能夠經過slabtop命令查看系統中活動的object的數量與內存佔用狀況,從而瞭解哪些數據結構最佔用內核態的內存空間。

例如:使用slabtop命令查看內核數據結構及內存佔用

 Active / Total Objects (% used)    : 1222616 / 1575898 (77.6%)
 Active / Total Slabs (% used)      : 39945 / 39945 (100.0%)
 Active / Total Caches (% used)     : 67 / 125 (53.6%)
 Active / Total Size (% used)       : 276332.00K / 318115.77K (86.9%)
 Minimum / Average / Maximum Object : 0.01K / 0.20K / 15.75K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
848211 516003  60%    0.10K  21749       39     86996K buffer_head
266406 266158  99%    0.19K   6343       42     50744K dentry
 75300  73560  97%    0.63K   3012       25     48192K proc_inode_cache
 70224  70224 100%    0.96K   2128       33     68096K ext4_inode_cache
 56960  56489  99%    0.06K    890       64      3560K kmalloc-64
 52530  50791  96%    0.04K    515      102      2060K ext4_extent_status
 30702  29066  94%    0.19K    731       42      5848K kmalloc-192
 27076  22278  82%    0.55K    967       28     15472K radix_tree_node
 26532  26532 100%    0.11K    737       36      2948K sysfs_dir_cache
 20910  20910 100%    0.05K    246       85       984K shared_policy_node
 12712  12712 100%    0.57K    454       28      7264K inode_cache
 11536  10815  93%    0.07K    206       56       824K anon_vma
  9088   7840  86%    0.03K     71      128       284K kmalloc-32
  6752   3567  52%    0.25K    211       32      1688K kmalloc-256
  6656   6656 100%    0.02K     26      256       104K kmalloc-16
  6560   4747  72%    0.12K    205       32       820K kmalloc-128
  6656   6656 100%    0.02K     26      256       104K kmalloc-16

 

  一般關注1. 哪些數據結構的內存佔用最大,2. 哪些類型的數據結構對應的object最多,好比inode多表明文件系統被大量引用等。

  該交互命令支持的選項與排序標準有:

選項:
--delay=n, -d n    每隔n秒刷新信息
--once, -o         只顯示一次
--sort=S, -s S     按照S排序,其中S爲排序標準

排序標準(shift + 對應的鍵):
a:根據active objects數量高低排序
b:根據 objects / slab高低來排序
c:根據cache大小排序
l:根據slab數量排序
v:根據active slabs數量排序
n:按 name 排序
o:按照 objects 數量排序
p:按照 pages / slab 的值排序
s:按照 object 大小排序
u:按照 cache 使用量排序

 

 

6. 查看內存使用的動態變化

# vmstat

  vmstat命令能夠查看內存使用的動態變化,

例如: 使用vmstat動態監視內存變更

# vmstat  1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 5755120 312980 2192136    0    0     1    33    1    0  5  2 92  1  0
 0  0      0 5755120 312980 2192136    0    0     0     8 2000 2770  1  2 97  0  0
 1  0      0 5755120 312980 2192136    0    0     0    24 2033 2715  1  2 96  1  0
 0  0      0 5755120 312980 2192136    0    0     0     0 1999 2317  1  2 98  0  0
 3  1      0 5754996 312980 2192136    0    0     0     4 2187 3004  6  3 91  0  0

 

  其中# vmstat N 表明每隔N秒更新一次數據。

 

7. dstat

# dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
  5   2  92   1   0   0|4630B  129k|   0     0 |   0     0 |2246  2808
  2   2  93   4   0   0|   0   708k|  53k 6732k|   0     0 |2091  2828
  1   2  96   1   0   0|   0  8192B|  34k 6595k|   0     0 |2198  2621
  1   2  96   0   0   1|   0    12k|  39k 6898k|   0     0 |2209  2679
  2   2  96   0   0   0|   0  4096B|  44k 7256k|   0     0 |2217  2907
  1   2  97   0   0   0|   0     0 |  38k 7109k|   0     0 |2128  2413
  2   3  94   1   0   0|   0    24k|  37k 7295k|   0     0 |2217  2594
  2   2  96   0   0   0|   0    12k|  36k 7482k|   0     0 |2106  2613
  1   1  97   0   0   0|   0  4096B|  37k 6923k|   0     0 |2255  2516

 

 

8. 查看共享內存空間

pmap

  可使用pmap命令查看進程使用的共享內存,包括使用的庫,所在堆棧空間等。

# pmap -d 1
1:   /sbin/init
Address           Kbytes Mode  Offset           Device    Mapping
00007fb45d59c000      44 r-x-- 0000000000000000 008:00002 libnss_files-2.19.so
00007fb45d5a7000    2044 ----- 000000000000b000 008:00002 libnss_files-2.19.so
00007fb45d7a6000       4 r---- 000000000000a000 008:00002 libnss_files-2.19.so
00007fb45d7a7000       4 rw--- 000000000000b000 008:00002 libnss_files-2.19.so
00007fb45d7a8000      44 r-x-- 0000000000000000 008:00002 libnss_nis-2.19.so
00007fb45d7b3000    2044 ----- 000000000000b000 008:00002 libnss_nis-2.19.so
00007fb45d9b2000       4 r---- 000000000000a000 008:00002 libnss_nis-2.19.so
00007fb45d9b3000       4 rw--- 000000000000b000 008:00002 libnss_nis-2.19.so

 

  

9. 查看系統內存歷史記錄

# sar

  可使用sar命令查看一個月之內的內存使用狀況。

 

如何清理內存使用

  1. 釋放佔用的緩存空間

# sync     //先將內存刷出,避免數據丟失
# echo 1 > /proc/sys/vm/drop_caches //釋放pagecache
# echo 2 > /proc/sys/vm/drop_caches //釋放dentry和inode
# echo 3 > /proc/sys/vm/drop_caches //釋放pagecache、dentry和inode

  2. 終止進程

 

與Linux內存相關的文件系統文件

/proc/meminfo

  內存信息

/proc/$pid/status

  進程狀態信息,

/proc/$pid/statm

  進程物理內存信息

/proc/slabinfo

  slab的分佈情況

/proc/vmstat

  虛擬內存信息

 

一些額外的小技巧

1. 下降swap的使用率:

# sysctl -a | grep swappiness
vm.swappiness = 60

  能夠查看當前swap的使用

 

2. 限制其餘用戶的內存使用

# vim /etc/security/limits.conf

user1 hard as 1000 (用戶user1全部累加起來,內存不超過1000kiB)
user1 soft as 800 (用戶user1一次運行,內存不超過800kiB)

  

3. 大量連續內存數據:

# vim /etc/sysctl.conf

vm.nr_hugepage=20

  

4. 調節page cache(大量同樣的請求 調大page cache)

vm.lowmem_reserve_ratio = 256 256 32 (保留多少內存做爲pagecache 當前 最大 最小)
vm.vfs_cache_pressure=100 (大於100,回收pagecache)
vm.page.cluster=3(一次性從swap寫入內存的量爲2的3次方頁)
vm.zone_reclaim_mode=0/1(當內存危機時,是否儘可能回收內存 0:儘可能回收 1:儘可能不回收)
min_free_kbytes:該文件表示強制Linux VM最低保留多少空閒內存(Kbytes)。

 

5.  髒頁

vm.dirty_background_radio=10 (當髒頁佔內存10%,pdflush工做)
vm.dirty_radio=40 (當進程自身髒頁佔內存40%,進程本身處理髒頁,將其寫入磁盤)
vm.dirty_expire_centisecs=3000 (髒頁老化時間爲30秒 3000/100=30秒)
vm.dirty_writeback_centisecs=500 (每隔5秒,pdflush監控一次內存數量 500/100=5秒)

   髒頁是指已經更改但還沒有刷到硬盤的內存頁,由pdflush往硬盤上面刷。

相關文章
相關標籤/搜索