基于 PKS 体系的 CockroachDB 性能优化研究

2023-12-25 09:01谢小龙蔡仁锋方鲁杰
电子技术应用 2023年12期
关键词:二进制实例内存

李 博,谢小龙,蔡仁锋,李 亮,方鲁杰

(1.中电(海南)联合创新研究院,海南 澄迈 571924;2.中软信息系统工程有限公司,北京 102209)

0 引言

随着互联网经济的飞速发展,传统的集中式数据库逐渐成为金融核心业务发展的瓶颈,迫使金融核心业务系统向分布式架构转型,利用分布式数据库替换集中式数据库,从而获得高性能、高扩展、高可用等关键优势。金融产业是一个国家的经济命脉,安全不容忽视,中国电子PKS 体系为助力金融国产化提供安全底座,从芯片到整机外设、操作系统等为金融国产化提供安全支持。通过前期调研数款分布式数据库产品,选取可扩展、强一致性、高可靠和支持HATP 混合工作负载的分布式数据库 CockroachDB[1]为研究对象,在PKS 体系下进行性能优化工作,其性能的提升对金融产业的发展有重要意义。

1 相关工作

在对数据库系统调优时,基本手段是在配置参数维度进行,主要通过改变配置参数以达到优化性能的目的,配置参数包括数据库配置参数,如用于缓存的内存量、缓冲区大小等[2]。比如 BestConfig[3]方法,该工作基于递归限定查找算法搜索最佳配置参数。Thummala[2]等人对部分关系型数据库参数进行调优,寻找对其调优效果最大的配置。与数据库物理设计工具不同,配置工具不能使用关系型数据库查询优化器中的内置成本模型,此类模型根据系统预期为特定查询执行所需要的工作量进行估计并生成预估值[4]。这些预估值针对单个关系型数据库管理系统的备选查询执行策略与固定的执行环境进行比较。IBM 发布了DB2 Performance Wizard[4]根据具体工作负载来设置参数,但由于模型是手动创建,因此无法准确反映实际工作负载或操作环境。Oracle[5]开发了以识别由于数据库系统内部组件中的错误配置而导致的瓶颈的一个内部监控系统,虽然可以为工程师提供建议,但因为 Oracle 系统采用基于性能测量的启发式方法来管理内存分配,无法对所有参数进行调优。SQL Server[6]也采用类似的方法。

随着数据库和应用程序在规模和复杂性上的增长,优化数据库以满足应用程序的需求已经超出了人类的能力,因为数据库的正确配置高度依赖于许多超出人类推理范围的因素。上述的自动数据库配置工具存在某些不足之处,使其不适合于通用数据库应用程序。同时许多调优工具都是由供应商创建的,它们只支持特定的数据库。鉴于此,Aken[7]等人提出了基于深度学习的OtterTune 调优框架,该框架主要分为两块:客户端和服务端。客户端和数据库进行交互,比如采集数据,执行参数设置。服务端作为OtterTune 的大脑,分析收集到数据,形成深度模型,并在产出参数的优化策略,文献[8-9]在OtterTune 的基础上继续发展应用。类似利用深度学习网络进行数据库优化的工作还有CDBtune[10]等。PingCAP[11]团队使用TiDB 数据库针对金融场景进行调优,采用了包括索引优化、拓展集群和负载均衡调整等手段,提升效果比较可观。另外除了调整数据库参数,还有结合分布式数据库自身特性进行软硬件调优,如操作系统内核调优、网络调优、线程调度调优、I/O 读写性能调优、PCIE 速率调优、软硬中断调优、热点代码分析,这些方法在实际性能调优过程中发挥了重要作用,文献[11]有实际应用。

本文所研究的调优方法则是在上述调优方法的基础上,重点研究数据库与操作系统和CPU 等软硬件协同工作,尤其在非一致性内存访问和操作系统内核中页缓存管理机制进行深入研究,并提出拆分二进制实例的调优方法。

2 调优方法

本节将对拆分二进制实例的调优方法进行详细介绍,在开始介绍之前,将对Numa 架构和CPU 绑核原理进行介绍,有利于更好地理解拆分二进制实例的调优方法。

2.1 NUMA 架构和CPU 绑核原理介绍

2.1.1 NUMA 架构

非一致性内存访问(Non-Uniform Memory Access,NUMA)是处理器地址空间中不同Node 的内存具有不同性能特征,与之对应的是早期使用的统一内存访问,即每个处理器核心享有相同的内存地址空间。随着CPU 架构朝着多核心方向发展,多核心访问内存的瓶颈越来越明显。NUMA 的基本思想是将各个CPU 划分为不同的NUMA Node,每个Node 拥有自己的内存,从处理器到内存的信号路径长度起着重要作用,只有当CPU访问与自身直接相连的内存对应的物理地址时,才会有较短的响应时间。访问其他CPU 的内存时,增加的信号路径长度不仅会增加内存延迟,而且如果信号路径由多个处理器共享,也会很快成为吞吐量瓶颈。

以飞腾S2500 高性能CPU 为例说明NUMA,图1 为该CPU 的架构图,该CPU 以8 个核心(图中使用 C 表示)为一组直接连接一个 L3 内存,这个组合被称为一个 Node,可以看到 S2500 有8 个 Node,若跨 Node 访问内存则需要通过黑色双向箭头表示的系统总线。当Node 访问非本地内存时,就涉及访问距离,在 S2500 中Nodei与 Nodej间的访问距离dij可以表示为式(1)中的代价矩阵D,其中矩阵的对角线表示 Node 访问本地内存的距离,即最短访问距离。

图1 飞腾 S2500 处理器架构图

2.1.2 CPU 绑核

在Linux 操作系统中,线程调度默认由内核自由调度,在多核 CPU 上,进程可能在不同的 CPU 核心上来回切换执行,这对 CPU 的缓存读取是不利的,因为CPU 存在上下文切换(Context Switch)。每个物理核有独立的 L1 和 L2 级缓存,程序执行最频繁的指令和数据会被缓存到 L1 和 L2 级缓存中,一旦程序被切换到另一个物理核时,对应的指令和数据需要被重新刷到相应的 L1、L2 缓存中,造成频繁地进行上下文切换,程序不能很好地利用 L1 和 L2 级缓存,增加程序的延时性。针对这种频繁切换 CPU 核进行操作,可以采用绑核操作,将程序绑核到指定 CPU 核上,程序只在对应的CPU 核上执行,不会切换到其他 CPU 核上。以飞腾S2500 处理器为例,可以参考式(1)中距离矩阵选择距离较近的Node 进行绑定,至于绑定方法及其试验结果将在第3 节进行讨论。

2.2 拆分二进制实例

本次研究采用单机四实例的部署方式,即一台服务器上开启四个 CockroachDB 的二进制实例,四个二进制实例绑核在不同的 Node 上,通常做法是将一个 CockroachDB 的二进制实例运行四次。用 numastat 命令查看二进制实例在 Node 内存的分布情况,发现少部分内存在非绑定 Node 内存中。表1 展示了第四个CockroachDB 二进制实例的 Node 内存使用情况,该二进制实例绑定在 Node 12 和 Node 13 上,却发现少部分内存被 Node 1 和 Node 2 使用(表格中加粗显示部分),类似的情况也出现在其他二进制实例。

表1 优化前 CockroachDB 第四个二进制实例的内存使用详情

为了深入调查这部分内存的信息,调取该二进制实例的 numa_maps 信息。numa_maps 是一个只读文件,当读取时,内核会扫描对应进程的虚拟地址空间并报告内存的使用情况,二进制实例的每个唯一内存范围显示一行。如表2 所示,展示的是 CockroachDB 第四个二进制实例 numa_maps 的关键信息,两个地址的代码段存在位于 Node 2 的内存。

表2 优化前 CockroachDB 第四个二进制实例 numa_maps 的关键信息

通过对操作系统内核中页缓存管理机制的研究,发现在该四个二进制实例场景中,第一个绑定Node 2 和Node 3 的 CockroachDB 二进制实例运行后,CockroachDB 的代码段进入页缓存(位于NUMA Node 2),从而在 Node 2 对应的内存命中,当接下来第二至第四个二进制实例在其他 NUMA Node 启动的时候,也需要CockroachDB 的代码段,这时命中的依然是 Node 2 的代码段。如图2 所示,以一个搭载双路处理器的服务器为例,CockroachDB 的代码段位于 Node 0,其他三个进程都各自有跨 Node 的代码段内存访问,从而造成效率低下。造成这种现象的原因在于,Kylin 操作系统内核中内存上的页缓存的管理机制是以索引节点(inode,index node)为单位的,索引节点是 UNIX 风格文件系统中的一种数据结构,用于描述文件系统对象,每个 inode存储对象数据的属性和磁盘块位置,且 inode 以二进制名称作为唯一标识,在图2 的情况下,以一个二进制文件名称启动四个进程,则操作系统判定为同一个 inode。一个 inode(比如 CockroachDB 对应的 inode)的页缓存在内存命中的情况下,内核不会为每个 Node 直接复制一份,导致在不同 Node 上启动的 CockroachDB 的页缓存均在一个 Node 上,造成其他 Node 访问二进制文件系统的页缓存出现跨路,出现时延增加和降低数据库运行效率的现象。

图2 跨路访问示意图

所提出的优化方法具体是将默认的一份CockroachDB 的二进制文件拷贝成四份不同名称的文件,这样让每个Node 申请连续内存的时候,可以申请到本Node 的近地址内存,不用到远端为代码段申请内存,从而提高I/O 的性能,示意图如图3 所示。

图3 优化后的代码段访问示意图

通过查看优化后同一个进程的 numastat 和numa_maps 的关键信息,初步确认了所提出方法的有效性。如表3 和表4 所示,内存和代码段均位于绑定的响应 Node 上。对于具体的试验结果,将在下一部分进行讨论。

表3 优化后 CockroachDB 第四个进程的内存使用详情

表4 优化后 CockroachDB 第四个进程numa_maps 的关键信息

3 实验

为了验证所提出方法的有效性,本节主要介绍拆分二进制实例的调优方法在 PKS 体系下进行评估。

3.1 实验环境

本实验采用两台PKS 双路服务器,整机共128 个CPU 核心,运行内存 512 GB,通过万兆光纤直连的方式进行通信。

实验采用一个基于 LuaJIT 的可编写脚本的多线程基准测试工具 sysbench。它最常用于数据库基准测试,sysbench 可以设置测试的线程、脚本等参数。在输出结果方面,主要考察 sysbench 输出的每秒事务数(Transactions Per Second,TPS),TPS 的大小反映数据库的性能高低。测试场景选择读写测试,这样更贴合分布式数据库实际应用中的读写模拟。负载均衡选择haproxy,这是一种流行的开源软件 TCP/HTTP 负载均衡器和代理解决方案,可以在多系统上运行。它最常见的用途是通过将工作负载分布到多个服务器(例如 Web、应用程序、数据库)来提高服务器环境的性能和可靠性。实验采用的软件详细信息如表5 所示。

表5 实验采用的软件一览表

实验环境的拓扑结构如图4 所示,测试需要两台服务器,其中一台装有 sysbench 和 haproxy,作为压力机,另一台装有四个实例的 CockroachDB 集群并创建一个名为 sysbench 的数据库,包含30 个表,每个表有5 000 000条数据,每个实例的数据均位于一个单独的 SSD 硬盘。测试前,确定好绑核策略,测试时,装有sysbench 的服务器通过万兆光纤直连的方式向 CockroachDB 发送压测命令,压力机压测5 次,每次90 s 的读写压力测试。

图4 实验环境拓扑图

3.2 拆分实例实验结果

为了实验公平性,首先对照组 4 个实例使用同一个二进制文件命名为 cockroach-21.1.9,每个用例绑定 16个CPU 核心,即两个 Node,且同时绑定内存。绑定的详细信息可查看表6 和表7。使用 sysbench 对 CockroachDB 进行4 组测试,每组分别并发32、64 和128 线程,观察CPU 占用率和 numa_maps 信息、记录 TPS 与平均时延,并且每轮测试前清除缓存。

表6 优化前实例绑核详情

表7 优化后实例绑核详情

图5 和图6 分别展示了优化前后的 TPS 和 Lat 实验结果图,实验先后进行五轮,记录第二轮至第五轮的数据每秒事务数和延迟(后文均分别用 TPS 和 Lat 表示),并取这四组数据的平均值,这样的预热操作是必要的,因为 CockroachDB 的最佳性能是在其各种缓存中填充了最相关的数据时实现,同时从内存读取通常比磁盘读取要快得多,所以经过预热后记录的数据更加准确。

图6 优化前后 Lat 对比图

实验结果表明,在相同的绑核绑内存策略下,拆分实例相较于不拆分实例,TPS 有显著提升,提高范围在1.7 至 1.8 倍。通过观察监控面板,拆分实例后数据库的 CPU 使用率更为均衡,每个实例 CPU 使用率保持在1 000% 至 1 400%(每个实例绑定的 16 核)之间,相互间差值小于 200。而不拆分实例测得的 CPU 使用率较不均衡,每个实例 CPU 使用率在 800% 到 1 500% 之间,实例相互间差值较大且不稳定。

通过查看 numa_maps 信息分析造成这种现象的原因,在数据库进行优化前,四个实例同名且 inode 相同,实例代码段先会被读入最先执行绑定 Node 对应的内存,其余的三个实例执行需要跨 Node 跨路获取代码段信息,存在频繁跨 Node 进行数据交互的场景,从而CPU 使用率不均衡,性能较低。在进行优化后,将CockroachDB 二进制文件复制成命名不同的四份,虽然内容相同,但名称不同且 inode 不同,实例代码段分别被读入绑定 Node 的对应内存中,从而CPU 使用率相对均衡,使得性能提升。

4 结论

本文提出了基于 PKS 体系拆分 CockroachDB 二进制实例的调优方法,使得每个二进制实例的代码段能够分布在被绑定相应的 Node 上,从而降低跨 Node 访问的性能损失。通过大量对比实验表明该方法能降低时延的同时,显著提升 CockroachDB 的性能。

猜你喜欢
二进制实例内存
用二进制解一道高中数学联赛数论题
外部高速缓存与非易失内存结合的混合内存体系结构特性评测
有趣的进度
二进制在竞赛题中的应用
“春夏秋冬”的内存
完形填空Ⅱ
完形填空Ⅰ
基于内存的地理信息访问技术
一个生成组合的新算法
上网本为什么只有1GB?