写点什么

在 x86 和 arm 混合部署架构下排查 TiKV 节点内存占用极高的问题

  • 2022 年 7 月 11 日
  • 本文字数:3404 字

    阅读完需:约 11 分钟

作者: hey-hoho 原文来源:https://tidb.net/blog/91cb51aa


【是否原创】是


【首发渠道】TiDB 社区

前言

前不久我们在混合部署架构下测试了 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命令查看:


[root@localhost ~]# cat /proc/meminfoMemTotal:       32943872 kBMemFree:         3809408 kBMemAvailable:    1467264 kBBuffers:             192 kBCached:           457856 kBSwapCached:       669248 kBActive:         26691328 kBInactive:        2040832 kBActive(anon):   26565568 kBInactive(anon):  1726912 kBActive(file):     125760 kBInactive(file):   313920 kBUnevictable:           0 kBMlocked:               0 kBSwapTotal:      16711616 kBSwapFree:       15044608 kBDirty:               256 kBWriteback:             0 kBAnonPages:      27385216 kBMapped:            75968 kBShmem:             18240 kBKReclaimable:      37120 kBSlab:             245440 kBSReclaimable:      37120 kBSUnreclaim:       208320 kBKernelStack:       29696 kBPageTables:        16384 kBNFS_Unstable:          0 kBBounce:                0 kBWritebackTmp:          0 kBCommitLimit:    33183552 kBCommitted_AS:    1009344 kBVmallocTotal:   133009506240 kBVmallocUsed:           0 kBVmallocChunk:          0 kBPercpu:            17408 kBHardwareCorrupted:     0 kBAnonHugePages:  18874368 kBShmemHugePages:        0 kBShmemPmdMapped:        0 kBHugePages_Total:       0HugePages_Free:        0HugePages_Rsvd:        0HugePages_Surp:        0Hugepagesize:     524288 kBHugetlb:               0 kB
复制代码


其中比较诡异的是 AnonHugePages 字段占到了 18G 内存,而实际的用户进程空间(Active)也才 26G。


继续验证这里的 AnonHugePages 占用是否都来自 TiKV Server 进程(PID 是 3996),用如下命令筛选:


[root@localhost ~]# awk  '/AnonHugePages/ { if($2>4){print FILENAME " " $0; system("ps -fp " gensub(/.*\"/([0-9]+).*/, "\"\"1", "g", FILENAME))}}' /proc/3996/smaps/proc/3996/smaps AnonHugePages:  10485760 kBUID        PID  PPID  C STIME TTY          TIME CMDtidb      3996     1  0 May21 ?        04:40:06 bin/tikv-server --addr 0.0.0.0:20160 --advertise-addr 10.3.65.133:20160 --status-addr 0.0.0.0:20180 --advertise-status-addr 10.3.65.133:20180 --pd 10.3.65.130:2379,10.3.65.131:2/proc/3996/smaps AnonHugePages:   8388608 kBUID        PID  PPID  C STIME TTY          TIME CMDtidb      3996     1  0 May21 ?        04:40:06 bin/tikv-server --addr 0.0.0.0:20160 --advertise-addr 10.3.65.133:20160 --status-addr 0.0.0.0:20180 --advertise-status-addr 10.3.65.133:20180 --pd 10.3.65.130:2379,10.3.65.131:2
复制代码


从以上信息可以断定所有的 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 的启用开关,我们可以通过如下方式关闭透明大页特性:


# echo never > /sys/kernel/mm/transparent_hugepage/enabled# echo never > /sys/kernel/mm/transparent_hugepage/defrag
复制代码


要注意的是,这种方式只是临时禁用,当系统重启后还是会恢复 always 状态。


通过以上命令关闭了 3 台 ARM TiKV 节点的 THP 后,我重启了 TiDB 集群:


tiup cluster restart tidb-test
复制代码


再次登录到 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 cluster check <topology.yml | cluster-name> --apply
复制代码


最后说一句,TIUP 真香啊~

推荐阅读

/PROC/MEMINFO 之谜


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 内存居高不下


部署机环境检查


发布于: 刚刚阅读数: 3
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
在x86和arm混合部署架构下排查TiKV节点内存占用极高的问题_性能调优_TiDB 社区干货传送门_InfoQ写作社区