当前位置 : 主页 > 操作系统 > centos >

Linux系统故障定位与优化(二)

来源:互联网 收集:自由互联 发布时间:2022-06-20
内存查看 Ex1、内存使用紧张? 排查思路: 1) 用户访问量增加,导致服务使用内存增加; 2) 程序异常,内存泄漏; 使用vmstat查看内存使用 [root@inf-c7-n1 ~]# vmstat 1 10procs -----------memory---

内存查看

Ex1、内存使用紧张?

排查思路:

1) 用户访问量增加,导致服务使用内存增加;

2) 程序异常,内存泄漏;

使用vmstat查看内存使用

[root@inf-c7-n1 ~]# vmstat 1 10 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 15788388 2108 240736 0 0 0 0 5 4 0 0 100 0 0 0 0 0 15788388 2108 240736 0 0 0 0 37 23 0 0 100 0 0 0 0 0 15788388 2108 240736 0 0 0 0 43 30 0 0 100 0 0 0 0 0 15788388 2108 240736 0 0 0 0 29 27 0 0 100 0 0 0 0 0 15788388 2108 240736 0 0 0 0 29 19 0 0 100 0 0 0 0 0 15788388 2108 240736 0 0 0 0 31 24 0 0 100 0 0 0 0 0 15788388 2108 240736 0 0 0 0 19 13 0 0 100 0 0 0 0 0 15788388 2108 240736 0 0 0 0 45 39 0 0 100 0 0 0 0 0 15788248 2108 240736 0 0 0 2 55 51 0 0 100 0 0 0 0 0 15788248 2108 240736 0 0 0 0 23 20 0 0 100 0 0 显示说明:  

字段

含义

procs

进程信息字段:

· -r:等待运行的进程数,数量越大,系统越繁忙。

· -b:不可被唤醒的进程数量,数量越大,系统越繁忙。

memory

内存信息字段:

· -swpd:虚拟内存的使用情况,单位为 KB

· -free:空闲的内存容量,单位为 KB

· -buff:缓冲的内存容量,单位为 KB

· -cache:缓存的内存容量,单位为 KB

swap

交换分区信息字段:

· -si:从磁盘中交换到内存中数据的数量,单位为 KB

· -so:从内存中交换到磁盘中数据的数量,单位为 KB

这两个数越大,表明数据需要经常在磁盘和内存之间进行交换,系统性能越差。

io

磁盘读/写信息字段:

· -bi:从块设备中读入的数据的总量,单位是块。

· -bo:写到块设备的数据的总量,单位是块。

这两个数越大,代表系统的 I/O 越繁忙。

system

系统信息字段:

· -in:每秒被中断的进程次数。

· -cs:每秒进行的事件切换次数。

这两个数越大,代表系统与接口设备的通信越繁忙。

cpu

CPU信息字段:

· -us:非内核进程消耗 CPU 运算时间的百分比。

· -sy:内核进程消耗 CPU 运算时间的百分比。

· -id:空闲 CPU 的百分比。

· -wa:等待 I/O 所消耗的 CPU 百分比。

· -st:被虚拟机所盗用的 CPU 百分比。

查看网络服务使用的内存

[root@localhost vmfs]# ss -tmpio State Recv-Q Send-Q Local Address:Port Peer Address:Port ESTAB 0 0 10.199.13.25:ssh 10.199.5.128:50143 users:(("sshd",pid=37674,fd=3)) timer:(keepalive,104min,0) skmem:(r0,rb934516,t0,tb1000960,f8192,w0,o0,bl0,d0) sack cubic wscale:8,7 rto:227 rtt:26.317/18.779 ato:40 mss:1460 rcvmss:1460 advmss:1460 cwnd:10 ssthresh:16 bytes_acked:1257181613 bytes_received:5834836 segs_out:973509 segs_in:218250 send 4.4Mbps lastsnd:1 lastrcv:29 pacing_rate 8.9Mbps retrans:0/124 rcv_rtt:360 rcv_space:104368 ESTAB 0 0 [::1]:x11-ssh-offset [::1]:56476 users:(("sshd",pid=37674,fd=12)) skmem:(r0,rb1061184,t0,tb2626560,f0,w0,o0,bl0,d2) ts sack cubic wscale:7,7 rto:205 rtt:4.411/8.689 ato:40 mss:65464 rcvmss:536 advmss:65464 cwnd:10 bytes_acked:2248 bytes_received:484 segs_out:15 segs_in:19 send 1187.3Mbps lastsnd:15309980 lastrcv:15309980 lastack:15309980 pacing_rate 2374.5Mbps rcv_space:43690 ESTAB 0 0 [::1]:x11-ssh-offset [::1]:56472 users:(("sshd",pid=37674,fd=11)) skmem:(r0,rb6291456,t0,tb2626560,f0,w0,o0,bl0,d11) ts sack cubic wscale:7,7 rto:222 rtt:21.07/21.032 ato:40 mss:65464 rcvmss:25784 advmss:65464 cwnd:3 ssthresh:2 bytes_acked:2618904 bytes_received:1247927456 segs_out:68092 segs_in:110429 send 74.6Mbps lastsnd:2470 lastrcv:2476 lastack:2430 pacing_rate 149.1Mbps retrans:0/19 rcv_rtt:1229.38 rcv_space:1463216

使用 Memcheck 分析内存使用量

Memcheck 是默认的 valgrind 工具。它检测并报告大量难以检测和诊断到的内存错误,例如:

1) 不应发生的内存访问

2) 使用未定义或未初始化的值

3) 不正确的释放堆内存

4) 指示字重叠

5) 内存泄露

>>使用memcheck分析内存使用

[root@inf-c7-n1 media]# valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all echo hello ==7637== Memcheck, a memory error detector ==7637== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==7637== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==7637== Command: echo hello ==7637== hello ==7637== ==7637== HEAP SUMMARY: ==7637== in use at exit: 0 bytes in 0 blocks ==7637== total heap usage: 30 allocs, 30 frees, 3,681 bytes allocated ==7637== ==7637== All heap blocks were freed -- no leaks are possible ==7637== ==7637== For lists of detected and suppressed errors, rerun with: -s ==7637== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

 >>使用cachegrind分析缓存

[root@inf-c7-n1 ~]# valgrind --tool=cachegrind echo hoo ==25512== Cachegrind, a cache and branch-prediction profiler ==25512== Copyright (C) 2002-2017, and GNU GPL'd, by Nicholas Nethercote et al. ==25512== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==25512== Command: echo hoo ==25512== hoo ==25512== ==25512== I refs: 202,301 ==25512== I1 misses: 1,036 ==25512== LLi misses: 1,029 ==25512== I1 miss rate: 0.51% ==25512== LLi miss rate: 0.51% ==25512== ==25512== D refs: 70,674 (51,869 rd + 18,805 wr) ==25512== D1 misses: 3,312 ( 2,657 rd + 655 wr) ==25512== LLd misses: 2,677 ( 2,068 rd + 609 wr) ==25512== D1 miss rate: 4.7% ( 5.1% + 3.5% ) ==25512== LLd miss rate: 3.8% ( 4.0% + 3.2% ) ==25512== ==25512== LL refs: 4,348 ( 3,693 rd + 655 wr) ==25512== LL misses: 3,706 ( 3,097 rd + 609 wr) ==25512== LL miss rate: 1.4% ( 1.2% + 3.2% )

>>使用cg_annotate查看分析结果

[root@inf-c7-n1 ~]# cg_annotate cachegrind.out.25512 -------------------------------------------------------------------------------- I1 cache: 32768 B, 64 B, 8-way associative D1 cache: 32768 B, 64 B, 8-way associative LL cache: 2097152 B, 64 B, 8-way associative Command: echo hoo Data file: cachegrind.out.25512 Events recorded: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw Events shown: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw Event sort order: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw Thresholds: 0.1 100 100 100 100 100 100 100 100 Include dirs: User annotated: Auto-annotation: off -------------------------------------------------------------------------------- Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw -------------------------------------------------------------------------------- 202,301 1,036 1,029 51,869 2,657 2,068 18,805 655 609 PROGRAM TOTALS -------------------------------------------------------------------------------- Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw file:function -------------------------------------------------------------------------------- 56,525 12 12 13,788 1,034 859 16 3 0 ???:_dl_addr 27,862 14 14 9,106 215 138 4,363 12 9 ???:do_lookup_x 21,800 11 11 4,416 115 97 2,623 10 5 ???:_dl_lookup_symbol_x 19,501 47 47 5,298 696 643 2,296 254 243 ???:_dl_relocate_object 14,102 2 2 4,243 45 25 0 0 0 ???:strcmp 6,350 4 4 2,154 13 0 279 0 0 ???:getenv 5,700 5 5 2,362 54 20 680 6 4 ???:check_match.9525 5,655 6 6 1,084 65 62 490 42 42 ???:_nl_intern_locale_data 4,343 20 20 560 3 2 675 22 21 ???:_int_malloc 2,811 17 17 458 13 10 0 0 0 ???:__GI_strcmp 2,130 4 3 13 0 0 2,068 33 33 ???:memset 1,967 2 2 509 5 0 292 6 5 ???:_dl_name_match_p 1,733 46 46 380 19 19 183 25 25 ???:_dl_map_object_from_fd 1,354 4 4 177 7 5 0 0 0 ???:__GI_strlen 1,348 14 14 447 6 5 182 14 14 ???:_dl_check_map_versions 1,267 4 4 366 3 0 92 0 0 ???:malloc 1,169 6 6 438 44 11 104 0 0 ???:_dl_fixup 1,145 38 38 248 1 1 120 5 5 ???:_dl_map_object_deps 1,137 21 21 277 11 5 257 6 2 ???:_nl_load_locale_from_archive 1,080 8 8 156 6 1 252 0 0 ???:_nl_find_locale 1,049 74 74 215 27 20 135 16 16 ???:dl_main 1,037 14 14 258 13 13 76 4 4 ???:bcmp 904 2 2 164 0 0 118 1 1 ???:bsearch

>>使用massif查看程序使用堆栈

[root@inf-c7-n1 ~]# valgrind --tool=massif echo hello ==25380== Massif, a heap profiler ==25380== Copyright (C) 2003-2017, and GNU GPL'd, by Nicholas Nethercote ==25380== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==25380== Command: echo hello ==25380== hello ==25380== [root@inf-c7-n1 ~]# ls anaconda-ks.cfg massif.out.25380 MemoryLeak MemoryLeak.cpp test

>>使用ms_print查看分析结果

[root@inf-c7-n1 ~]# ms_print massif.out.25380 -------------------------------------------------------------------------------- Command: echo hello Massif arguments: (none) ms_print arguments: massif.out.25380 -------------------------------------------------------------------------------- KB 3.961^ @@@@@@@# | :::@ # | ::@::::@ # | ::@::::@ # | ::@::::@ # | ::@::::@ # | @:@::::@ # | :@:@::::@ # | :@:@::::@ # | :@:@::::@ # | ::@:@::::@ # | ::@:@::::@ # | ::@:@::::@ # | ::@:@::::@ # | ::@:@::::@ # | ::@:@::::@ # | :::@:@::::@ # | :::@:@::::@ # | :::@:@::::@ # | :::@:@::::@ # 0 +----------------------------------------------------------------------->ki 0 153.1 Number of snapshots: 63 Detailed snapshots: [2, 12, 22, 32, 33 (peak), 43, 53] -------------------------------------------------------------------------------- n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B) -------------------------------------------------------------------------------- 0 0 0 0 0 0 1 118,412 24 5 19 0 2 118,680 24 5 19 0 20.83% (5B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. ->20.83% (5B) 0x4E60E04: _nl_normalize_codeset (in /usr/lib64/libc-2.17.so) ->20.83% (5B) 0x4E5B15E: _nl_load_locale_from_archive (in /usr/lib64/libc-2.17.so) ->20.83% (5B) 0x4E5A35D: _nl_find_locale (in /usr/lib64/libc-2.17.so) ->20.83% (5B) 0x4E59CC2: setlocale (in /usr/lib64/libc-2.17.so) ->20.83% (5B) 0x401428: ??? (in /usr/bin/echo) ->20.83% (5B) 0x4E4F554: (below main) (in /usr/lib64/libc-2.17.so) -------------------------------------------------------------------------------- n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B) -------------------------------------------------------------------------------- 3 118,680 0 0 0 0 4 119,175 136 120 16 0 5 119,234 160 132 28 0 6 119,348 952 908 44 0 7 120,812 1,072 1,020 52 0 8 121,016 2,040 1,972 68 0 9 122,870 2,272 2,188 84 0 10 123,269 2,712 2,620 92 0 11 124,085 2,832 2,724 108 0 12 124,273 2,936 2,812 124 0 95.78% (2,812B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. ->91.28% (2,680B) 0x4E5A9BF: _nl_intern_locale_data (in /usr/lib64/libc-2.17.so) | ->91.28% (2,680B) 0x4E5B0A5: _nl_load_locale_from_archive (in /usr/lib64/libc-2.17.so) | ->91.28% (2,680B) 0x4E5A35D: _nl_find_locale (in /usr/lib64/libc-2.17.so) | ->91.28% (2,680B) 0x4E59CC2: setlocale (in /usr/lib64/libc-2.17.so) | ->91.28% (2,680B) 0x401428: ??? (in /usr/bin/echo) | ->91.28% (2,680B) 0x4E4F554: (below main) (in /usr/lib64/libc-2.17.so) | ->04.09% (120B) 0x4E5B025: _nl_load_locale_from_archive (in /usr/lib64/libc-2.17.so) | ->04.09% (120B) 0x4E5A35D: _nl_find_locale (in /usr/lib64/libc-2.17.so) | ->04.09% (120B) 0x4E59CC2: setlocale (in /usr/lib64/libc-2.17.so) | ->04.09% (120B) 0x401428: ??? (in /usr/bin/echo) | ->04.09% (120B) 0x4E4F554: (below main) (in /usr/lib64/libc-2.17.so) | ......

内存优化配置

配置HugeTLB Huge Page

>>查看当前hugepage大小,默认2MB,配置大页数量

[root@inf-c7-n1 ~]# cat /proc/sys/vm/nr_hugepages 0 [root@inf-c7-n1 ~]# cat /proc/meminfo |grep -i hugepage AnonHugePages: 8192 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB [root@inf-c7-n1 sysctl.d]# sysctl -p 100-memctl.conf vm.nr_hugepages = 10 [root@inf-c7-n1 sysctl.d]# cat /proc/meminfo |grep -i hugepage AnonHugePages: 8192 kB HugePages_Total: 10 HugePages_Free: 10 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB

>>在内核启动参数中配置Hugepagesize

[root@inf-c7-n1 vm]# vim /etc/default/grub [root@inf-c7-n1 vm]# cat /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=c01/root rd.lvm.lv=c01/swap rhgb quiet default_hugepagesz=1G hugepagesz=1G" GRUB_DISABLE_RECOVERY="true" [root@inf-c7-n1 vm]# grub2-mkconfig -o /boot/grub2/grub.cfg Generating grub configuration file ... Found linux image: /boot/vmlinuz-3.10.0-862.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-862.el7.x86_64.img Found linux image: /boot/vmlinuz-0-rescue-6fde1470ec6d473c8db4edb9e122c965 Found initrd image: /boot/initramfs-0-rescue-6fde1470ec6d473c8db4edb9e122c965.img done [root@inf-c7-n1 vm]# [root@inf-c7-n1 vm]# [root@inf-c7-n1 vm]# reboot [root@inf-c7-n1 ~]# cat /proc/meminfo |grep -i hugepage AnonHugePages: 8192 kB HugePages_Total: 10 HugePages_Free: 10 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 1048576 kB [root@inf-c7-n1 ~]# numastat -cm |egrep 'Node|Huge' Node 0 Total AnonHugePages 8 8 HugePages_Total 10240 10240 HugePages_Free 10240 10240 HugePages_Surp 0 0

无numa结构按以上的配置即可,如下有numa结构的还需要配置脚本,开机服务来判断设定;

[root@localhost ~]# numastat -cm |egrep 'Node|Huge' Node 0 Node 1 Node 2 Node 3 Total AnonHugePages 16380 8752 5726 12612 43470 HugePages_Total 0 0 0 0 0 HugePages_Free 0 0 0 0 0 HugePages_Surp 0 0 0 0 0

配置Transparent Hug Page

>>查看透明大页默认状态

[root@inf-c7-n1 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled [always] madvise never

always:全局开启

madvise:局部程序开启

never:禁用透明大页

>>查看透明大页内存整理

[root@inf-c7-n1 ~]# cat /sys/kernel/mm/transparent_hugepage/defrag [always] madvise never

内存参数调优

路径:/proc/sys/vm

dirty_ratio:

触发pdflush将内存数据写入磁盘的阀值,默认20%;

 

dirty_bytes:

触发一个写入进程开始回写的脏存储器量,默认值为0;

 

⁠dirty_background_ratio:

当脏页达到系统内存的10%时,强制回收写入磁盘,默认值10%;

 

dirty_background_bytes:

触发pdflush后台回写的脏存储器量,默认值为0;

 

dirty_expire_centisecs:

使用pdflush的脏存储器最小时间,默认值为3000;

 

dirty_writeback_centisecs:

pdflush活跃时间间隔(0为停用),默认值为500;

 

⁠overcommit_memory

是否接受或拒绝大内存请求,默认值0;0超分;1不超分,2超分但不超过⁠overcommit_ratio阀值;

 

⁠overcommit_ratio

内存超分阀值,默认50%;

 

⁠max_map_count

一个进程可使用的最大内存映射,默认值65530;

 

min_free_kbytes

预留内存空间大小,注意,这个参数不要随便设置,如果值太小,会影响系统的内存回收,可能导致系统hang住,或者触发oom-kill进程,如果太大(达到系统内存的5%-10%),容易导致内存溢出,或系统花费太长时间来回收内存。

 

⁠oom_adj

当系统中panic_on_oom参数为0时,系统内存资源使用紧张时,oom_killer触发kill进程开始按照oom_score值的大小杀死进程(值越小越不容易被杀死)。Oom_adj的设置值会影响进程的oom_score,当值为-17禁用oom_killer杀死此进程,其他设置值范围为-16~15。

 

Swappiness

值的范围0~100,rhel7默认值30,控制系统使用匿名内存和页面内存的倾向,

值大:提高文件系统性能,同时将不太活跃的进程从内存中置换出来;

值小:避免进程从内存中置换出去,以牺牲I/O性能为代价来降低延迟;

 

Linux的进程使用的内存分为2种:

1) file-backed pages(有文件背景的页面,比如代码段、比如read/write方法读写的文件、比如mmap读写的文件,它们有对应的硬盘文件,因此如果要交换,可以直接和硬盘对应的文件进行交换;比如读取一个文件,没有关闭,也没有修改,交换时,就可以将这个文件直接放回硬盘,代码处理其实就是删除这部分内容,只保留一个索引,让系统知道这个文件还处于打开状态,只是它的内容不在内存,还在硬盘上),此部分页面叫做page cache;

2) anonymous pages(匿名页,如stack,heap,CoW后的数据段等;他们没有对应的硬盘文件,因此如果要交换,只能交换到swap分区),此部分页面,如果系统内存不充分,可以被swap到swapfile或者硬盘的swap分区。

因此,Linux在进行内存回收(memory reclaim)的时候,实际上可以从1类和2类这两种页面里面进行回收,而swappiness值就决定了回收这2类页面的优先级。swappiness越大,越倾向于回收匿名页;swappiness越小,越倾向于回收file-backed的页面。当然,它们的回收方法都是一样的LRU算法。(缓存淘汰算法--LRU算法LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高"。新数据插入到链表头部;每当缓存命中(即缓存数据被访问),则将数据移到链表头部;当链表满的时候,将链表尾部的数据丢弃。)

 

vm.swappiness = 0

仅在内存不足的情况下--当剩余空闲内存低于vm.min_free_kbytes limit时,使用交换空间。

 

vm.swappiness = 1

内核版本3.5及以上、Red Hat内核版本2.6.32-303及以上,进行最少量的交换,而不禁用交换。

 

vm.swappiness = 10

当系统存在足够内存时,推荐设置为该值以提高性能。

 

如果swappiness=0,除非系统的内存过小(nr_free + nr_filebacked < high watermark)这种恶劣情况发生,都只是考虑交换file-backed的pages,就不会考虑交换匿名页了。

于是,现在的swappiness如果等于0的话,意味着哪怕匿名页占据的内存很大,哪怕swap分区还有很多的剩余空间,除非恶劣情况发生,都不会交换匿名页,因此这可能造成更大的OOM(Out Of Memory)压力。

 

红帽官方说明:

Warning

Setting swappiness==0 will very aggressively avoids swapping out, which increase the risk of OOM killing under strong memory and I/O pressure.

 

文件系统参数

路径:/proc/sys/fs

⁠aio-max-nr

定义在异步输入/输出环境中允许的最大事件数量,默认值65536.

 

⁠file-max

定义整个系统中最大的文件句柄,rhel7中默认最大值8192【或(mempages * (PAGE_SIZE / 1024)) / 10】.增加参数值可以解决由于缺少可用的文件句柄而引起的错误。

 

内核参数

路径:/proc/sys/kernel

⁠msgmax

定义一个消息队列中单个消息最大值(KB),默认值65535,值不能超过队列大小(msgmnb)。

 

⁠msgmnb

定义单个消息队列最大值(KB),默认65535.

 

⁠msgmni

定义信息队列标识符的最大数量(以及队列的最大数量)。在 64 位架构的系统中,默认值为 1985。

 

⁠shmall

定义系统中可使用的共享的页面数,在64位系统中,单个页面为4096bytes。

[root@rhel7 vm]# getconf PAGESIZE

4096

 

⁠shmmax

定义页面上内核允许的单个共享内存片段的最大值(bytes)。

 

⁠shmmni

定义系统范围内最大的共享内存片段数量。在所有系统中的默认值为4096。

 

⁠threads-max

定义系统范围内内核能同时使用的最大线程量。默认值与内核参数max_threads 相同,【或mempages / (8 * THREAD_SIZE / PAGE SIZE )】,最小值为20.



【文章转自:日本站群服务器 http://www.558idc.com/japzq.html处的文章,转载请说明出处】
上一篇:kubernetes 二进制多master部署 v-1.18.6
下一篇:没有了
网友评论