SWAP的罪与罚&&NUMA的取舍
说个案例:一台Apache服务器,由于其MaxClients参数设置过大,并且恰好又碰到访问量激增,结果内存被耗光,从而引发SWAP,进而负载攀升,最终导致宕机。
正所谓:SWAP,性能之大事,死生之地,存亡之道,不可不察也。
哪些工具可以监测SWAP
最容易想到的就是free命令了,它指明了当前SWAP的使用情况:
1
2
3
|
shell> free -m total used free Swap: 34175 11374 22801 |
另一个常用的是sar命令,它能列出系统在各个时间的SWAP使用情况:
1
2
3
4
5
6
7
|
shell> sar -r kbswpfree kbswpused %swpused kbswpcad 23345644 11650572 33.29 4656908 23346452 11649764 33.29 4656216 23346556 11649660 33.29 4650308 23346932 11649284 33.29 4649888 23346992 11649224 33.29 4648848 |
不过free命令和sar命令显示的都不是实时数据,如果需要,可以使用vmstat命令:
1
2
3
4
5
6
7
8
|
shell> vmstat 1 -----------memory------------- ---swap-- swpd free buff cache si so 11647532 123664 305064 7193168 0 0 11647532 123672 305064 7193172 0 0 11647532 125728 305064 7193468 0 0 11647532 125376 305064 7193476 0 0 11647532 124508 305068 7193624 0 0 |
每秒刷新一次结果,在SWAP一栏里列出了相关数据,至于si和so的解释,大致如下:
1
2
|
si: Amount of memory swapped in from disk ( /s ). so: Amount of memory swapped to disk ( /s ). |
如果它们一直是零当然最好不过了,偶尔不为零也没啥,糟糕的是一直不为零。
前面介绍的方法,看到的都是SWAP的整体情况,可是如果我想查看到底是哪些进程使用了SWAP,应该如何操作呢?这个问题有点棘手,我们来研究一下:
好消息是top命令能提供这个信息,不过缺省并没有显示,我们需要激活一下:
- 打开top;
- 按「f」进入选择字段的界面;
- 按「p」选择「SWAP」字段;
- 按回车确认。
坏消息是top命令提供的SWAP信息只是一个理论值,或者更直白一点儿来说它根本就是不可信的(在top里SWAP的计算公式是:SWAP=VIRT-RES)。
BTW:相比之下,top里的「nFLT」字段更有价值,它表示PageFault的次数。
那到底我们能不能获取到进程的SWAP情况呢?别着急,看代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#!/bin/bash cd /proc for pid in [0-9]*; do command =$( cat /proc/ $pid /cmdline ) swap=$( awk ' BEGIN { total = 0 } /Swap/ { total += $2 } END { print total } ' /proc/ $pid /smaps ) if (( $swap > 0 )); then if [[ "${head}" != "yes" ]]; then echo -e "PID\tSWAP\tCOMMAND" head = "yes" fi echo -e "${pid}\t${swap}\t${command}" fi done |
说明:请使用root权限来运行此脚本。
哪些因素可能影响SWAP
内存不足无疑会SWAP,但有些时候,即便看上去内存很充裕,还可能会SWAP,这种现象被称为SWAP Insanity,罪魁祸首主要有以下几点:
Swappiness的迷失
实际上,当可用内存不足时,系统有两个选择:一个是通过SWAP来释放内存,另一个是删除Cache中的Page来释放内存。一个很常见的例子是:当拷贝大文件的时候,时常会发生SWAP现象。这是因为拷贝文件的时候,系统会把文件内容在Cache中按Page来缓存,此时一旦可用内存不足,系统便会倾向于通过SWAP来释放内存。
内核中的swappiness参数可以用来控制这种行为,缺省情况下,swappiness的值是60:
1
2
|
shell> sysctl -a | grep swappiness vm.swappiness = 60 |
它的含义是:如果系统需要内存,有百分之六十的概率执行SWAP。知道了这一点,我们很自然的会想到用下面的方法来降低执行SWAP的概率:
1
2
|
shell> echo "vm.swappiness = 0" >> /etc/sysctl .conf shell> sysctl -p |
这样做的确可以降低执行SWAP的概率,但并不意味着永远不会执行SWAP。
NUMA的诅咒
NUMA在MySQL社区有很多讨论,这里不多说了,直击NUMA和SWAP的恩怨纠葛。
大概了解一下NUMA最核心的numactl命令:
1
2
3
4
5
6
7
8
9
10
|
shell> numactl --hardware available: 2 nodes (0-1) node 0 size: 16131 MB node 0 free : 100 MB node 1 size: 16160 MB node 1 free : 10 MB node distances: node 0 1 0: 10 20 1: 20 10 |
可以看到系统有两个节点(其实就是两个物理CPU),它们各自分了16G内存,其中零号节点还剩100M内存,一号节点还剩10M内存。设想启动了一个需要11M内存的进程,系统把它分给了一号节点来执行,此时虽然系统总体的可用内存大于该进程需要的内存,但因为一号节点本身剩余的可用内存不足,所以仍然可能会触发SWAP行为。
需要说明的一点事,numactl命令中看到的各节点剩余内存中时不包括Cache内存的,如果需要知道,我们可以利用drop_caches参数先释放它:
1
|
shell> sysctl vm.drop_caches=1 |
注:这步操作可能会引起系统负载的震荡。
另:如何确定一个进程的节点及内存分配情况?网络上有现成的脚本。
如果要规避NUMA对SWAP的影响,最简单的方法就是在启动进程的时候禁用它:
1
|
shell> numactl --interleave=all ... |
此外,内核参数zone_reclaim_mode通常也很重要,当某个节点可用内存不足时,如果为0的话,那么系统会倾向于从远程节点分配内存;如果为1的话,那么系统会倾向于从本地节点回收Cache内存。多数时候,Cache对性能很重要,所以0是一个更好的选择。
1
2
|
shell> echo "vm.zone_reclaim_mode = 0" >> /etc/sysctl .conf shell> sysctl -p |
另:网络上有一些关于MySQL和SWAP的讨论,对于理解SWAP有一定意义,推荐
补:Memcached在启动的时候如果带上了k选项,就能避免使用SWAP,但要慎用。
…
早些年,YouTube曾经被SWAP问题困扰过,他们当时的解决方法很极端:删除SWAP!不得不说这真是艺高人胆大,可惜对芸芸众生的我们而言,这实在是太危险了,因为如此一来,一旦内存耗尽,由于没有SWAP的缓冲,系统会立即开始OOM,结果可能会让问题变得更加复杂,所以大家还是安分守己做个老实人吧。
NUMA的取舍
现在的机器上都是有多个CPU和多个内存块的。以前我们都是将内存块看成是一大块内存,所有CPU到这个共享内存的访问消息是一样的。这就是之前普遍使用的SMP模型。但是随着处理器的增加,共享内存可能会导致内存访问冲突越来越厉害,且如果内存访问达到瓶颈的时候,性能就不能随之增加。NUMA(Non-Uniform Memory Access)就是这样的环境下引入的一个模型。比如一台机器是有2个处理器,有4个内存块。我们将1个处理器和两个内存块合起来,称为一个NUMA node,这样这个机器就会有两个NUMA node。在物理分布上,NUMA node的处理器和内存块的物理距离更小,因此访问也更快。比如这台机器会分左右两个处理器(cpu1, cpu2),在每个处理器两边放两个内存块(memory1.1, memory1.2, memory2.1,memory2.2),这样NUMA node1的cpu1访问memory1.1和memory1.2就比访问memory2.1和memory2.2更快。所以使用NUMA的模式如果能尽量保证本node内的CPU只访问本node内的内存块,那这样的效率就是最高的。
在运行程序的时候使用numactl -m和-physcpubind就能制定将这个程序运行在哪个cpu和哪个memory中。玩转cpu-topology 给了一个表格,当程序只使用一个node资源和使用多个node资源的比较表(差不多是38s与28s的差距)。所以限定程序在numa node中运行是有实际意义的。
但是呢,话又说回来了,制定numa就一定好吗?--numa的陷阱。SWAP的罪与罚文章就说到了一个numa的陷阱的问题。现象是当你的服务器还有内存的时候,发现它已经在开始使用swap了,甚至已经导致机器出现停滞的现象。这个就有可能是由于numa的限制,如果一个进程限制它只能使用自己的numa节点的内存,那么当自身numa node内存使用光之后,就不会去使用其他numa node的内存了,会开始使用swap,甚至更糟的情况,机器没有设置swap的时候,可能会直接死机!所以你可以使用numactl --interleave=all来取消numa node的限制。
综上所述得出的结论就是,根据具体业务决定NUMA的使用。
如果你的程序是会占用大规模内存的,你大多应该选择关闭numa node的限制。因为这个时候你的程序很有几率会碰到numa陷阱。
另外,如果你的程序并不占用大内存,而是要求更快的程序运行时间。你大多应该选择限制只访问本numa node的方法来进行处理。
CPU绑定操作
使用virsh vcpuinfp命令查看虚拟机VCPU和物理CPU的对应关系
1
2
3
4
5
6
7
8
|
[root@svn ~] # virsh vcpuinfo 16 VCPU: 0 CPU: 3 状态: running CPU 时间: 12581.6s CPU关系: yyyy #可以看到VCPU0被调度到物理机CPU3上,目前是使用状态,使用时间是12581.6s。 |
使用emulatorpin命令可以查看虚拟机可以使用哪些物理逻辑CPU

virsh #进入虚拟化的交互式终端
virsh # emulatorpin 16
模拟器: CPU 亲和性
----------------------------------
*: 0-3 可以看到0-3都可以使用,意味着可以强制将VCPU调度到任何物理CPU核上

在线绑定虚拟机的CPU
可以强制虚拟机只能在部分物理CPU之间调度。例如,使编号为16的虚拟机CPU在26-31之间调度
1
2
3
4
5
6
7
|
virsh emulatorpin 16 26-31 --live 通过以下命令查看绑定是否生效 virsh emulatorpin 21 emulator: CPU Affinity ----------------------------------------------------------- *: 26-31 |
强制VCPU和物理机CPU-对一绑定
强制VCPU和物理机CPU-对一地绑定,例如强制VCPU 0和物理机CPU 28绑定,强制VCPU 1和物理机CPU 29绑定,强制VCPU 2和物理机CPU 30绑定,强制VCPU 3和物理机CPU
1
2
3
4
|
virsh vcpupin 21 0 28 virsh vcpupin 21 1 29 virsh vcpuin 21 2 30 virsh vcpuin 21 3 31 |
CPU绑定技术的原理:CPU绑定实际上是Libvirt通过CGROUP来实现的,通过CGROUP直接去绑定KVM虚拟机进程也可以。CGROUP不仅可以做CPU绑定,还可以限制虚拟机磁盘、网络资源控制。
CPU绑定技术适用的应用场景:
- 系统的CPU压力比较大
- 多核CPU压力不平衡,可以通过cpu pinning技术人工进行调配
补充:
NUMA在虚拟机话应用之外的提示:
某些应用,比如数据库,为了保证性能,需要尽量适用更多的内存,如果使用系统默认的NUMA自动平衡策略,有可能一个CPU的内存消耗光,另外一个CPU还有大量的内存可以使用,但是系统却去调用swap来使用,造成性能严重降低。使用这些内存消耗型的应用时,可以考虑直接将系统的NUMA自动平衡策略关闭
SWAP的罪与罚&&NUMA的取舍的更多相关文章
- NUMA的取舍与优化设置【转】
NUMA的取舍与优化设置 在os层numa关闭时,打开bios层的numa会影响性能,QPS会下降15-30%; 在bios层面numa关闭时,无论os层面的numa是否打开,都不会影响性能. 安装n ...
- 【转贴】NUMA的取舍与优化设置
NUMA的取舍与优化设置 https://www.cnblogs.com/tcicy/p/10191505.html 在os层numa关闭时,打开bios层的numa会影响性能,QPS会下降15-30 ...
- NUMA的取舍与优化设置
在os层numa关闭时,打开bios层的numa会影响性能,QPS会下降15-30%; 在bios层面numa关闭时,无论os层面的numa是否打开,都不会影响性能. 安装numactl: ...
- NUMA导致的MySQL服务器SWAP问题分析
[作者] 王栋:携程技术保障中心数据库专家,对数据库疑难问题的排查和数据库自动化智能化运维工具的开发有强烈的兴趣. [问题描述] 我们知道当mysqld进程使用到SWAP时,就会严重影响到MySQL的 ...
- MongoDB 启动时关于 NUMA 警告 的分析----(To avoid performance problems)
1. 需求描述 观察MongoDB的启动Log,会看到一个关于 NUMA 的警告 和 优化建议 --17T17:: I CONTROL [initandlisten] ** WARNING: You ...
- mongodb的NUMA问题
问题: 在mongodb登录时日志显演示样例如以下: [loguser@32_180 ~]$ mongo -u root -p xxxxx --authenticationDatabase adm ...
- [转]找到MySQL发生swap的原因
背景: 最近遇到了一个郁闷的问题:明明OS还有大量的空闲内存,可是却发生了SWAP,百思不得其解.先看下SWAP是干嘛的,了解下它的背景知识.在Linux下,SWAP的作用类似Windows系统下的“ ...
- 关闭swap的危害——一旦内存耗尽,由于没有SWAP的缓冲,系统会立即开始OOM
SWAP的罪与罚 发表于2012-11-08 说个案例:一台Apache服务器,由于其MaxClients参数设置过大,并且恰好又碰到访问量激增,结果内存被耗光,从而引发SWAP,进而负载攀升,最终导 ...
- numastat命令详解
基础命令学习目录 作者:[吴业亮]博客:http://blog.csdn.net/wylfengyujiancheng一.系统架构的演进从SMP到NUMA1.SMP(Symmetric Multi-P ...
随机推荐
- RabbitMQ重试机制
消费端在处理消息过程中可能会报错,此时该如何重新处理消息呢?解决方案有以下两种. 在redis或者数据库中记录重试次数,达到最大重试次数以后消息进入死信队列或者其他队列,再单独针对这些消息进行处理: ...
- rabbitmq概念简介
AMQP协议 AMQP: Advanced Message Queue,高级队列协议. 特征: 这是一个在进程间传递异步消息的网络协议,因此数据的发送方.接收方以及容器(MQ)都可以在不同的设备上. ...
- spring boot项目的maven库查询地址
阿里巴巴地址 http://maven.aliyun.com/nexus/#welcome maven通用地址 http://mvnrepository.com/ gradle默认mavenCentr ...
- java面试一日一题:字节java后端工程师面试题
今天来分享下字节一面面试题,各位小伙伴看看都能答上来吗,弄懂下面的问题你离字节又近了一步哦,加油吧 1.自我介绍: 2.问到项目中为什么选择hbase,如果有多个查询条件如何设置数据存储方案: 3.t ...
- 浅谈C++11中的多线程(一)
摘要 本篇文章围绕以下几个问题展开: 进程和线程的区别 何为并发?C++中如何解决并发问题?C++中多线程的基本操作 同步互斥原理以及多进程和多线程中实现同步互斥的两种方法 Qt中的多线程应用 c++ ...
- [002] - JavaSE面试题(二):基本数据类型与访问修饰符
第一期:Java面试 - 100题,梳理各大网站优秀面试题.大家可以跟着我一起来刷刷Java理论知识 [002] - JavaSE面试题(二):基本数据类型与访问修饰符 第1问:Java的数据类型有哪 ...
- 字典get方法和setdesault方法,统计message中各元素的出现频次
message= 'There are moments in life when you miss someone so much that you just want to pick them fr ...
- HTML5-CSS(一)
一.创建 CSS 样式表有三种方式 1. 元素内嵌样式<p style="color:red;font-size:50px;">这是一段文本</p>解释:即 ...
- js中的 true 与 false
可判断为 false 的情况: 0,-0,NaN,undedined,"",false,null,缺省的值 可判断为 true 的情况: 除false的其他情况均可,包括负数.&q ...
- C++第四十三篇 -- VS2017创建控制台程序勾选MFC类库
用VS2017创建EXE带MFC类库方法 1. File --> New --> Project 2. Windows桌面向导 3. 勾选MFC类库 4. 创建成功 如果项目编译出错 1. ...