文章目录

  • 1 问题分析
  • 2 难道是zone_reclaim_mode?
    • 2.1 NUMA是什么?
    • 2.2 zone_reclaim_mode=0管用么?
  • 3 内存回收
    • 3.1 内存回收的触发路径(min_free_kbytes)
    • 3.2 Linux内存回收对象主要分为两种(swappiness)
    • 4 实际情况
    • 4.1 优化前的情况
    • 4.2 优化后
    • 4.3 优化后的效果
  • 5 参考文档
  • 技术交流

1 问题分析

CleverCode公司部署的redis是集群模式,使用的是3主3从,部分redis集群直接部署在物理机上面。为了充分利用物理机资源。物理机上面还跑着fastdfs进程。这样redis使用物理机的内存。fastdfs使用物理机的磁盘。
但是跑了一段时间后发现redis经常会有连接超时情况。如下出现Connection timed out [tcp://10.x.x.74:6416],
Error while reading line from the server. [tcp://10.x.x.74:6392]

某一天的报错情况:

很多天的报错情况:

从zabbix里面查找内存的使用监控:发现11月17号redis开始使用后,Mem_used会周期性的接近94.37G(物理内存最大值)。每次Mem_use接近到达94.37G后,发现会有一次内存回收释放操作,Mem_cached减少,Mem_free开始增加。

2 难道是zone_reclaim_mode?

2.1 NUMA是什么?

经过一顿排查,发现我们系统内核参数里面 /etc/sysctl.conf 配置的vm.zone_reclaim_mode=1

vm.zone_reclaim_mode=1是什么东西?这个参数是控制NUMA开关的。NUMA又是什么?

NUMA(Non-Uniform Memory Access)是相对UMA来说的,两者都是CPU的设计架构,早期CPU设计为UMA结构,如下图(图片来自网络)所示:

为了缓解多核CPU读取同一块内存所遇到的通道瓶颈问题,芯片工程师又设计了NUMA结构,如下图(图片来自网络)所示:

这种架构可以很好解决UMA的问题,即不同CPU有专属内存区,为了实现CPU之间的”内存隔离”,还需要软件层面两点支持:

内存分配需要在请求线程当前所处CPU的专属内存区域进行分配。如果分配到其他CPU专属内存区,势必隔离性会受到一定影响,并且跨越总线的内存访问性能必然会有一定程度降低。

另外,一旦local内存(专属内存)不够用,优先淘汰local内存中的内存页,而不是去查看远程内存区是否会有空闲内存借用。

这样实现,隔离性确实好了,但问题也来了:NUMA这种特性可能会导致CPU内存使用不均衡,部分CPU专属内存不够使用,频繁需要回收,进而可能发生大量swap,系统响应延迟会严重抖动。而与此同时其他部分CPU专属内存可能都很空闲。这就会产生一种怪现象:使用free命令查看当前系统还有部分空闲物理内存,系统却不断发生swap,导致某些应用性能急剧下降。见叶金荣老师的MySQL案例分析:《找到MySQL服务器发生SWAP罪魁祸首》。

所以,对于小内存应用来讲,NUMA所带来的这种问题并不突出,相反,local内存所带来的性能提升相当可观。但是对于数据库这类内存大户来说,NUMA默认策略所带来的稳定性隐患是不可接受的。因此数据库们都强烈要求对NUMA的默认策略进行改进,有两个方面可以进行改进:

  • 将内存分配策略由默认的亲和模式改为interleave模式,即会将内存page打散分配到不同的CPU
    zone中。通过这种方式解决内存可能分布不均的问题,一定程度上缓解上述案例中的诡异问题。对于MongoDB来说,在启动的时候就会提示使用interleave内存分配策略.

  • 改进内存回收策略:此处终于请出今天的第三个主角参数zone_reclaim_mode,这个参数定义了NUMA架构下不同的内存回收策略,可以取值0/1/3/4,其中0表示在local内存不够用的情况下可以去其他的内存区域分配内存;1表示在local内存不够用的情况下本地先回收再分配;3表示本地回收尽可能先回收文件缓存对象;4表示本地回收优先使用swap回收匿名内存。可见,HBase推荐配置zone_reclaim_mode=0一定程度上降低了swap发生的概率。

NUMA部分详细的说明可以查看:《Linux Swap的那些事》https://www.jianshu.com/p/73847b688728。

2.2 zone_reclaim_mode=0管用么?

发现NUMA这个特征之后发现我们机器,果然使用这个zone_reclaim_mode=1这个配置,赶紧联系运维注释掉/etc/sysctl.conf,#vm.zone_reclaim_mode=1,然后sysctl -p让配置生效。

然后观察一段时间后。。。。。。问题依然存在。所以根本问题不是NUMA架构导致的。

3 内存回收

3.1 内存回收的触发路径(min_free_kbytes)

Linux会在两种场景下触发内存回收,一种是在内存分配时发现没有足够空闲内存时会立刻触发内存回收;一种是开启了一个守护进程(swapd进程)周期性对系统内存进行检查,在可用内存降低到特定阈值之后主动触发内存回收。第一种场景没什么可说,来重点聊聊第二种场景,如下图所示:

watermark[min] = min_free_kbytes
watermark[low] = watermark[min] * 5 / 4 = min_free_kbytes * 5 / 4
watermark[high] = watermark[min] * 3 / 2 = min_free_kbytes * 3 / 2
watermark[high] - watermark[low] = watermark[low] - watermark[min] = min_free_kbytes / 4

可见,LInux的这几个水位线与参数min_free_kbytes密不可分。min_free_kbytes对于系统的重要性不言而喻,既不能太大,也不能太小。

min_free_kbytes如果太小,[min,low]之间水位的buffer就会很小,在kswapd回收的过程中一旦上层申请内存的速度太快(典型应用:数据库,fastdfs),就会导致空闲内存极易降至watermark[min]以下,此时内核就会进行direct reclaim(直接回收),直接在应用程序的进程上下文中进行回收,再用回收上来的空闲页满足内存申请,因此实际会阻塞应用程序,带来一定的响应延迟。

当然,min_free_kbytes也不宜太大,太大一方面会导致应用程序进程内存减少,浪费系统内存资源,另一方面还会导致kswapd进程花费大量时间进行内存回收。

3.2 Linux内存回收对象主要分为两种(swappiness)

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

既然有两类内存可以被回收,那么在这两类内存都可以被回收的情况下,Linux到底是如何决定到底是回收哪类内存呢?还是两者都会被回收?这里就牵出来了我们第二个关心的参数:swappiness,这个值用来定义内核使用swap的积极程度,值越高,内核就会积极地使用swap,值越低,就会降低对swap的使用积极性。该值取值范围在0~100,默认是60。这个swappiness到底是怎么实现的呢?具体原理很复杂,简单来讲,swappiness通过控制内存回收时,回收的匿名页更多一些还是回收的文件缓存更多一些来达到这个效果。swappiness等于100,表示匿名内存和文件缓存将用同样的优先级进行回收,默认60表示文件缓存会优先被回收掉,至于为什么文件缓存要被优先回收掉,大家不妨想想(回收文件缓存通常情况下不会引起IO操作,对系统性能影响较小)。对于数据库来讲,swap是尽量需要避免的,所以需要将其设置为0。此处需要注意,设置为0并不代表不执行swap哦!

4 实际情况

根据第3章节的内存回收的知识,我们来看看我们这两个配置min_free_kbytes和swappiness。特别是min_free_kbytes如果太小,此时内核就会进行direct reclaim(直接回收),直接在应用程序的进程上下文中进行回收,再用回收上来的空闲页满足内存申请,因此实际会阻塞应用程序,带来一定的响应延迟。

4.1 优化前的情况

min_free_kbytes 设置的只有90M
cat /proc/sys/vm/min_free_kbytes

swappiness 设置的是60。默认情况。
cat /proc/sys/vm/swappiness

4.2 优化后

min_free_kbytes改成了2G

[logdev@g4-xxxxx.ops.prod.idc1 ~]$ cat /proc/sys/vm/min_free_kbytes
2048000
[logdev@g4-xxxxx.ops.prod.idc1 ~]$

swappiness变成了10,就会降低对swap的使用积极性,尽可能的使用物理内存。

[logdev@g4-xxxxx.ops.prod.idc1 ~]$ cat /proc/sys/vm/swappiness
10
[logdev@g4-xxxxx.ops.prod.idc1 ~]$

4.3 优化后的效果

发现Mem_free一直在2G左右。也没有出现连接超时的情况。

5 参考文档

《numa详解》:https://www.cnblogs.com/klb561/p/9053692.html

《Linux Swap的那些事》:https://www.jianshu.com/p/73847b688728 这篇文章解释的很清楚。

《找到MySQL服务器发生SWAP罪魁祸首》:https://mp.weixin.qq.com/s?__biz=MjM5NzAzMTY4NQ==&mid=2653929537&idx=1&sn=3fad622f505175d9ca8399cfb14b925f&chksm=bd3b5a2b8a4cd33d0bd75078614106ee4065b732684fb949d7477f45af56ae8be0a472fc75b1#rd

《Linux内存管理学习笔记–物理内存分配》:https://www.xuebuyuan.com/3214566.html

https://mp.weixin.qq.com/s?src=11&timestamp=1575973816&ver=2026&signature=NNSmXPLZkTSUjMq8EWEemC4zycdLwidcJ2PPs07rKVSCDNNKu64xnoMHtN0XD7q-TvGwhJarZg89Osu-bWWlc81958vwSMcR1ymnAZ*BvYf9JjOt6CbczjlxbE3y7SKZ&new=1

《linux 的swap、swappiness及kswapd原理【转】》https://cloud.tencent.com/developer/article/1512940

《Linux内存管理回收机制》:https://blog.csdn.net/xiejianjun417/article/details/89400115

《Linux学习-内存管理篇(六)-内存回收(lru链表)》:https://blog.csdn.net/xiejianjun417/article/details/89400115

技术交流

CleverCode是一名架构师,技术交流,咨询问题,请加CleverCode创建的qq群(架构师俱乐部):517133582。加群和腾讯,阿里,百度,新浪等公司的架构师交流。【架构师俱乐部】宗旨:帮助你成长为架构师!

一次redis诡异的连接超时问题排查与解决相关推荐

  1. ES High Level Rest Client 超时问题排查及解决

    (1048条消息) ES异常:Connection reset by peer_浊酒入清梦的博客-CSDN博客https://blog.csdn.net/m0_37862405/article/det ...

  2. 英雄联盟手游显示连接服务器失败,英雄联盟手游连接超时怎么办 无法登录解决方法...

    LOL手游国服开启了新一轮的超燃测试,想必不少小伙伴们都拿到了此次测试的资格,不过一些小伙伴们在登录的时候却遇到了连接超时的情况,遇到英雄联盟手游连接超时怎么办?这里就来和大家分享一下连招超时.无法登 ...

  3. icloud连接服务器时出现问题_iCloud服务器连接超时怎么办 试试这个解决方法

    有iPhone用户备份时遇到"验证失败与iCloud服务器的连接超时",下文介绍iCloud服务器连接超时解决方法,一起来了解下吧! 产生"iCloud连接超时/验证失败 ...

  4. 记一次生产数据库连接池大量连接超时问题排查

    最近一段时间公司业务量上来了,与此同时伴随着程序猿终生的问题出现了. 服务异常总体的表现就是每天不定时间出现访问超时并持续一段时间,偶尔又好了.刚开始出现次数很少,服务中断一小段时间后就自己恢复了.但 ...

  5. Redis 突然变慢了如何排查并解决?

    作者 | 码哥字节 来源 | 码哥字节 Redis 通常是我们业务系统中一个重要的组件,比如:缓存.账号登录信息.排行榜等. 一旦 Redis 请求延迟增加,可能就会导致业务系统"雪崩&qu ...

  6. conda下载出现连接超时怎么办

    conda下载出现连接超时怎么办 文章目录: 一.连接超时原因 二.解决conda下载超时的两种办法 1.添加下载镜像地址 2.conda通过参数设置修改超时时间 三.超时依旧没有解决的其他原因 一. ...

  7. 吃鸡手游服务器响应超时闪退,吃鸡连接超时怎么解决 | 手游网游页游攻略大全...

    发布时间:2015-11-13 unturnde官方服务器我想现在很多玩家都想知道到底出了没有?没出会是在什么时候出?出了之后我们又该怎么进,对于这些问题,大家可以在本站进行搜索便知,另外,我们还是来 ...

  8. 方舟服务器直连服务器无响应,为什么我方舟加入服务器会显示连接超时 | 手游网游页游攻略大全...

    发布时间:2015-09-05 正当防卫3是刚出来的游戏呢,很多玩家都想要玩吧,但是由于这款游戏要全程联网才能够玩呢,很多玩家无法连接服务器,这是咋回事呢,下面看看正当防卫3无法连接服务器怎么办 总是 ...

  9. 方块方舟服务器维护,方块方舟主机连接超时 | 手游网游页游攻略大全

    发布时间:2015-11-13 unturnde官方服务器我想现在很多玩家都想知道到底出了没有?没出会是在什么时候出?出了之后我们又该怎么进,对于这些问题,大家可以在本站进行搜索便知,另外,我们还是来 ...

最新文章

  1. Maven多模块项目中应用maven-tomcat-plugin热部署
  2. 网站制作时应该如何更合理定位与策划
  3. 独家 | 一文读懂Apache Kudu
  4. 【Linux】一步一步学Linux——ldd命令(251)
  5. [html] 举例说明原生的html组件有哪些?
  6. 面试官十大常问面试问题总结
  7. Mysql的备份与恢复类型
  8. mysql批量插入跟更新_Mysql批量插入和更新的性能-问答-阿里云开发者社区-阿里云...
  9. 38. Element cloneNode() 方法
  10. java贪吃蛇详细设计,javascript贪吃蛇游戏设计与实现
  11. 网页设计(二)——HTML与BOX
  12. 通用的电子商务商城后台管理界面模板——后台
  13. “2019/10/17创新创业工坊第六期第二课”心得体会
  14. sql注入数据库原理详解
  15. grafana配置alert
  16. multisim中示波器显示电流变化波形
  17. 表值函数和标量值函数
  18. Conclusion for Inheritance and Object Oriented Design
  19. C#手机号码段生成 前7位补全后4位
  20. SpringMVC+Vue实现前后端的志愿者招募网站

热门文章

  1. python12306下单步骤_python+splinter实现12306网站刷票并自动购票流程
  2. 为什么有时我们需要配置HOSTS来本地测试?和什么有关?若不配置HOSTS会影响什么?
  3. 每日一问(20210922)——为什么要区分 icache 和 dcache ?
  4. mysqli mysql assoc_在预准备语句上使用fetch_assoc(php mysqli)
  5. Android基础知识 - ListView
  6. 计算机网络OSI模型
  7. Java实现图片复制
  8. 华天软件MES系统,让众泰汽车开足马力
  9. U99、Bug集中营 - U系列总纲
  10. 终端256色颜色代码一览表