前言
前不久我们在混合部署架构下测试了TiDB 5.0的性能,测试过程可以参考 TiDB 5.0 异步事务特性体验——基于X86和ARM混合部署架构 。在测试中我们使用了3台X86的TiKV和3台ARM的TiKV,在双方的对比参照下,我发现了一个奇怪的问题,就是相同配置的机器下ARM平台的TiKV Server内存占用量总是比X86平台大,而且不是大了一点点,本文会详细还原这个问题的发现和排查过程,以及如何解决内存异常问题。
发现问题
在部署完TiDB 4.0集群后,我习惯性地打开Dashboard查看各节点的运行状态,在主机页面看到了和往常不一样的画面,一个刚创建完的空集群,有一部分节点内存占用明显偏高,此事必有蹊跷,特别是其中的3台TiKV几乎达到了80%,而另外3台TiKV却处于正常水平:
经过初步判断,超标的3台TiKV刚好都是ARM节点,首先想到的是4.0版本是不是在ARM上有bug,于是把集群升级到5.0后发现问题依旧,说明并不是版本问题。
仔细对比后,发现不仅仅是TiKV节点,其他ARM的TiDB和PD节点内存都比X86的要高,进一步怀疑是TiDB本身对ARM的兼容性问题。为了验证高内存确实由TiDB引起,我以X86节点为参照,开始做一步步排查。
排查问题
以其中一台ARM TiKV为排查对象,首先登录到服务器中查看资源占用情况,直接使用 top 命令:
可以看到,内存占用最高的进程就是TiKV本身无疑,为了不冤枉它,我们还是要对比看看此时X86的情况:
果然和我们预期的一致,面对铁证如山的事实,TiKV背锅背定了。
我们进一步分析此时的节点内存使用情况,使用 cat /proc/meminfo 命令查看:
暂时无法在飞书文档外展示此内容
其中比较诡异的是AnonHugePages字段占到了18G内存,而实际的用户进程空间(Active)也才26G。
继续验证这里的AnonHugePages占用是否都来自TiKV Server进程(PID是3996),用如下命令筛选:
暂时无法在飞书文档外展示此内容
从以上信息可以断定所有的AnonHugePages都是来自TiKV进程。
AnonHugePages统计的是透明大页(Transparent HugePages,THP)的使用量,它在RHEL 6以上的版本中是默认开启的。我们都知道操作系统对内存是以页(Page)为使用单位,通常这个大小是4KB,透明大页的设计初衷是尽可能地为应用程序分配大页面(比如2M)来提升性能,减少大内存寻址带来的开销,并且能实现对大页的动态分配和使用。
它对于需要大量内存并对性能敏感的应用程序来说有一些作用,但同时也带来了一个非常严重的问题就是内存泄漏。从RedHat官网的 文档 来看,它不推荐在数据库程序中开启THP:
THP hides much of the complexity in using huge pages from system administrators and developers. As the goal of THP is improving performance, its developers (both from the community and Red Hat) have tested and optimized THP across a wide range of systems, configurations, applications, and workloads. This allows the default settings of THP to improve the performance of most system configurations. However, THP is not recommended for database workloads.
THP支持三种类型的状态,分别是:
- always,启用状态,系统默认
- never,禁用状态
- madvise,应用程序通过MADV_HUGEPAGE标志自己选择
关于透明大页的介绍这里不做过多介绍,大家可以参考文章后面的推荐链接,写的非常详细。
好在RHEL预留了THP的启用开关,我们可以通过如下方式关闭透明大页特性:
暂时无法在飞书文档外展示此内容
要注意的是,这种方式只是临时禁用,当系统重启后还是会恢复always状态。
通过以上命令关闭了3台ARM TiKV节点的THP后,我重启了TiDB集群:
暂时无法在飞书文档外展示此内容
再次登录到Dashboard查看集群中的节点状态,已经全部恢复正常:
整个过程的内存变化情况通过Grafana的监控曲线看的更加明显:
思考问题
虽然问题已经得到解决,但是仔细思考一下的话里面还有一些疑点没搞明白。
在X86的系统中同样也开启了THP特性,为什么内存使用没有出现明显异常呢?
还有一点就是,ARM的TiDB和PD节点虽然也出现了内存升高,但并不像TiKV节点这样特别明显,这又是什么原因?
我带着疑问去GitHub发起了Issue,不过遗憾的是还没找到问题的根本原因:
https://github.com/tikv/tikv/issues/10203
欢迎各路大佬来一起讨论。
如何避免
其实,因为服务器环境导致可能存在的性能问题TiDB官方已经帮大家考虑到了,并且提供了解决方案,只是这个步骤往往容易被忽略。
从TiDB 4.0版本开始,TiUP的Cluster组件可以提供对部署机器环境检测功能,我们使用 tiup cluster check 命令就可以对部署拓扑文件或者是已有的集群进行监测,效果如下图所示:
我们应该重点关注那些状态为fail的检查项,并且根据后面的提示做相应的调整,这一步对生产环境来说尤其重要。 以本文中的案例来说,tiup提示为了达到最好的性能请禁用THP,当我关闭了系统的THP特性后重新检测TiDB集群,会发现THP这一项已经变为pass状态:
有的人会说这么多检查项一个个去处理太麻烦了,有没有什么快捷的办法。还真有,tiup支持使用 --apply 参数对检测失败的项自动修复,不过也只是支持一部分可通过修改配置或系统参数调整的项目。
暂时无法在飞书文档外展示此内容
最后说一句,TIUP真香啊~
推荐阅读
HUGE PAGES AND TRANSPARENT HUGE PAGES How to use, monitor, and disable transparent hugepages in Red Hat Enterprise Linux 6 and 7? CentOS 7 关闭透明大页 使用tiup在x86和arm上混合部署arm内存居高不下 部署机环境检查




