下图是HBase官方文档上对操作系统环境的几点配置要求:
1、关闭透明大页
echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled
echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag
//这一步是需要加入到开机自启动中,才可以关闭的
//THP是一种动态管理策略,会在运行期分配管理大页,因此会有一定程度的分配延时,这对追求响应延时的数据库系统来说不可接受。TPH关闭场景下(never)HBase性能最优,比较稳定。而THP开启的场景(always),性能相比关闭的场景有30%左右的下降,而且曲线抖动很大。可见,HBase线上切记要关闭THP。
2、set vm.swappiness = 0 //这里要设置成0
//禁止交换(可选),内存页面交换在某些情况下会导致CDH 性能下降
[root@cloudera01 parcels513.el7]# echo vm.swappiness=1 >> /etc/sysctl.conf
[root@cloudera01 parcels513.el7]# sysctl -p
vm.swappiness = 1
//具体含义解释为:
swappiness,这个值用来定义内核使用swap的积极程度,值越高,内核就会积极地使用swap,值越低,就会降低对swap的使用积极性。该值取值范围在0~100,默认是60。
对于数据库来讲,swap是尽量需要避免的,所以需要将其设置为1。此处需要注意,设置为1并不代表不执行swap哦!
提示:
swappiness的值的大小对如何使用swap分区是有着很大的联系的。先前,人们建议把vm.swapiness设置为0,它意味着“除非发生内存益处,否则不要进行内存交换”。直到Linux内核3.5-rcl版本发布,这个值的意义才发生了变化。这个变化被一直到其他的发行版本上,包括RedHat企业版内核2.6.32-303。在发生变化之后,0意味着“在任何情况下都不要发生交换”。所以现在建议把这个值设置为1。swappiness=100的时候表示积极的使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。
3、set vm.min_free_kbytes to least 1GB(8GB on larger memory systems)
//该文件表示强制Linux VM最低保留多少空闲内存(Kbytes)。 //代表系统所保留空闲内存的最低限
官方文档中要求min_free_kbytes不能小于1G(在大内存系统中设置8G),就是不要轻易触发直接回收。
当可用内存低于这个参数时,系统开始回收cache内存,以释放内存,直到可用内存大于这个值。
vm.min_free_kbytes=409600;
vm.vfs_cache_pressure=200;
vm.swappiness=40。
调整MIN_FREE_KBYTES的目的是保持物理内存有足够的空闲空间,防止突发性的换页。
swapiness缺省为60,减少swapiness会使系统尽快通过swapout不使用的进程资源来释放更多的物理内存。
vfs_cache_pressure的缺省值是100,加大这个参数设置了虚拟内存回收directory和i-node缓冲的倾向,这个值越大,回收的倾向越严重。调整这3个参数的目的就是让操作系统在平时就尽快回收缓冲,释放物理内存,这样就可以避免突发性的大规模换页。
https://blog.csdn.net/hanyingzhong/article/details/71637391?utm_source=blogxgwz0
具体操作如下:
[root@NewCDH-0--141 ~]# cat /proc/sys/vm/min_free_kbytes //原来的
67584
[root@NewCDH-0--141 ~]# cat /proc/sys/vm/min_free_kbytes //设置成
1048576
[root@NewCDH-0--141 ~]# ll /proc/sys/vm/|wc -l
42
4、disable numa zone reclaim with vm.zone_reclaim_mode = 0
//官方建议把vm.zone_reclaim_mode = 0 设置成0
[root@NewCDH-0--141 vm]# cat /proc/sys/vm/zone_reclaim_mode //这个参数系统默认就是0
0
//UMA是什么?NUMA和swap有什么关系?zone_reclaim_mode的具体意义?
zone_reclaim_mode,这个参数定义了NUMA架构下不同的内存回收策略,可以取值0/1/3/4,其中0表示在local内存不够用的情况下可以去其他的内存区域分配内存;1表示在local内存不够用的情况下本地先回收再分配;3表示本地回收尽可能先回收文件缓存对象;4表示本地回收优先使用swap回收匿名内存。

swap是干什么的?
SWAP意思是交换,顾名思义,当某进程向OS请求内存发现不足时,OS会把内存中暂时不用的数据交换出去,放在SWAP分区中,这个过程称为SWAP OUT。当某进程又需要这些数据且OS发现还有空闲物理内存时,又会把SWAP分区中的数据交换回物理内存中,这个过程称为SWAP IN。
当然,swap大小是有上限的,一旦swap使用完,操作系统会触发OOM-Killer机制,把消耗内存最多的进程kill掉以释放内存。
显然,swap机制的初衷是为了缓解物理内存用尽而选择直接粗暴OOM进程的尴尬。

数据库系统为什么嫌弃swap?
1、数据库系统一般都对响应延迟比较敏感,如果使用swap代替内存,数据库服务性能必然不可接受。
2、对于响应延迟极其敏感的系统来讲,延迟太大和服务不可用没有任何区别,比服务不可用更严重的是,swap场景下进程就是不死,这就意味着系统一直不可用……再想想如果不使用swap直接oom,是不是一种更好的选择,这样很多高可用系统直接会主从切换掉,用户基本无感知。
3、 另外对于诸如HBase这类分布式系统来说,其实并不担心某个节点宕掉,而恰恰担心某个节点夯住。
4、一个节点宕掉,最多就是小部分请求短暂不可用,重试即可恢复。但是一个节点夯住会将所有分布式请求都夯住,服务器端线程资源被占用不放,导致整个集群请求阻塞,甚至集群被拖垮。

swap的工作机制
既然数据库们对swap不待见,那是不是就要使用swapoff命令关闭磁盘缓存特性呢?非也
HBase官方文档的几点要求实际上就是落实这个方针:尽可能降低swap影响。知己知彼才能百战不殆,要降低swap影响就必须弄清楚Linux内存回收是怎么工作的,这样才能不遗漏任何可能的疑点。

先来看看swap是如何触发的?
Linux会在两种场景下触发内存回收,
1、一种是在内存分配时发现没有足够空闲内存时会立刻触发内存回收;
2、一种是开启了一个守护进程(swapd进程)周期性对系统内存进行检查,在可用内存降低到特定阈值之后主动触发内存回收。

Linux内存回收对象主要分为两种:

  1. 文件缓存,这个容易理解,为了避免文件数据每次都要从硬盘读取,系统会将热点数据存储在内存中,提高性能。
  2. 匿名内存,这部分内存没有实际载体,不像文件缓存有硬盘文件这样一个载体,比如典型的堆、栈数据等。这部分内存在回收的时候不能直接释放或者写回类似文件的媒介中,这才搞出来swap这个机制,将这类内存换出到硬盘中,需要的时候再加载出来。

找到MySQL服务器发生SWAP罪魁祸首 https://mp.weixin.qq.com/s?__biz=MjM5NzAzMTY4NQ==&mid=2653929537&idx=1&sn=3fad622f505175d9ca8399cfb14b925f&chksm=bd3b5a2b8a4cd33d0bd75078614106ee4065b732684fb949d7477f45af56ae8be0a472fc75b1#rd
https://weibo.com/1680980510/EmvG57wVL?type=comment
物理内存还有不少空闲,但把swap都耗尽了。
绝大多数情况是因为没有关闭NUMA引起的。在运行数据库进程的服务器上,强烈建议关闭NUMA,
解决方法:
由于服务器硬件、系统设置不当,没有关闭NUMA,导致发生SWAP。建议方案有:
在BIOS设置层面关闭NUMA,缺点是需要重启OS;
或修改GRUB配置文件,缺点也是要重启OS;
升级MySQL版本到5.6.27及以后,新增了一个选项 innodb_numa_interleave,只需要重启mysqld实例,无需重启OS,推荐此方案。

    以上部分在 Linux 初始化脚本 (centos6 centos7 通用)https://blog.51cto.com/12445535/2362407 中提到
    参考链接为:http://hbasefly.com/2017/05/24/hbase-linux/