常見工做中,計算機系統的資源主要包括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往硬盤上面刷。