APP下载

云数据库运行环境的动态模拟

2022-09-26游舒泓

关键词:磁盘消耗内存

游舒泓 ,苏 仟 ,张 蓉

(1.华东师范大学 数据科学与工程学院,上海 200062;2.国家工业信息安全发展研究中心,北京 100040)

0 引 言

云计算平台的应用在近20 年内空前增长,根据统计报告的预测[1],到 2025 年,公共云计算市场价值将达到 8 000 亿美元,越来越多的企业选择将工作负载运行在公有云环境中.截至2020 年,61% 的企业已将工作负载迁移到云端,其中有46% 的公司报告说有了更好的财务状况.因此,这一趋势可能会在未来几年持续下去.容器化[2]的云环境逐渐流行起来,因为比起常规服务器,用云容器部署应用更加高效.容器编排引擎 (如 Kubernetes[3]) 可以提供跨不同云管理应用程序的必要运行环境,使容器化云环境更容易被用户广泛使用.

数据库是一种被广泛应用的数据管理技术,给物流数据提供了方便、高效的管理方式.云平台的成熟与普及推动了云原生软件系统的发展,其中也包括云原生数据库,如Amazon Aurora[4-5]、阿里的PolarDB[6]、Socrates[7]和 Taurus[8].数据库系统作为一个基础支撑软件运行于系统环境,在运行期间会遇到系统环境中的其他应用程序抢占资源,包括硬件资源、软件资源,进而导致用户执行负载的性能变化.另外,在生产环境中,环境负载类型、负载强度都可能进行动态变化,运行环境的变化对数据库负载运行性能的情况甚至正确性都会造成影响.

云平台的资源池化能力、灵活的调度能力及面向需求的无感弹性扩展能力,在带来便利的同时,也引入了新的挑战.在云平台,一台物理机可以托管多个应用实例[9],系统中可能同时运行大量操作类型不同、密集、高度动态的工作负载[10].虽然不同应用所部署的容器之间可能通过软件相互隔离,但由于这些容器共享云环境中的资源,容器间还是存在对环境资源的竞争.此外,为了充分利用云资源,云服务提供商通常会出售更多的资源以获取更大的利润.这些因素使得云原生应用程序之间的资源抢夺更加严重,从而加剧了数据库运行环境的不可控性和不稳定性.图1 展示了一个容器中的MySQL 数据库性能受另一个容器中的应用负载影响的现象.数据库在运行的是事务型负载,对CPU 资源的需求大.当其他容器中的应用程序也开始密集消耗CPU 时 (约55 s),数据库的平均时延明显大幅增加.因此,模拟动态的运行环境对评测云环境中数据库的服务性能以及服务可用性、可靠性而言至关重要.

图1 容器间资源竞争导致数据库性能下降现象Fig.1 Resource competition between containers causes database performance degration

模拟云数据库运行环境的难点在于需实现较高的准确性、高效性、全面性、通用性.准确性意味着实际生成的环境要贴近目标环境,即实现对目标资源的精确消耗,并且环境模拟负载对其余系统资源影响微小;高效性意味着生成目标环境的速度快;全面性意味着可模拟的资源类型较广泛;通用性意味着可以模拟给定时刻数据库运行环境中涉及的环境资源的故障及非故障状态.本文设计了轻量化的环境负载,通过敏捷的算法控制环境负载的动态变化,可实现对目标环境准确、高效的模拟.为了更全面地模拟运行环境,本文的资源模拟范围涵盖了硬件资源以及与数据库相关的软件资源.为了更细致地刻画数据库运行环境,实现更好的通用性,本文将数据库运行环境划分为以下两类.

(1) 常规运行环境: 在无故障情况下,运行环境中其他容器的应用程序对系统资源消耗的状态.

(2) 极端运行环境: 运行环境中数据库所在容器的资源被占满,甚至是被破坏的极端情况.

基于上述设计点,本文在Woodpecker 测试框架[11]的基础上实现了一个全面、通用的数据库运行环境动态的模拟工具.该工具可生成针对硬件资源 (如CPU、内存、磁盘、网络) 和进程、文件系统等软件资源指定强度的环境负载,达成对常规及极端运行环境准确、高效的模拟,可帮助评测数据库系统服务的可靠性、稳定性.在环境模拟结束后,本工具会自动恢复环境模拟中被消耗、破坏的资源.

1 相关工作

运行环境模拟是一项通过生成、运行和控制一组环境资源工作负载,模拟实际业务场景中应用程序运行环境的工作.目前,数据库测试人员在用标准评测基准测试数据库性能时,为了获得最佳的测试结果,通常在封闭环境下完成评测,即不会同时在系统中运行其他应用负载.但是在实际业务场景中,部署云和集群环境下的数据库系统,其运行效果会受到复杂多变的生产环境影响,即数据库的负载性能会受到其他应用的资源争夺或者资源损坏带来的影响.

随着云环境的成熟,越来越多的数据库部署到开放的云平台,提供DBaaS (数据库服务),数据库运行环境变得更加复杂.目前已有相关工作通过故障注入、模拟环境资源消耗等方式来制造复杂的运行环境.不过这些工具在通用性、全面性、动态性和模拟效果的准确性上各有欠缺,这些相关工作的总结见表1.

表1 运行环境模拟相关工作总结Tab.1 Summary of work related to runtime environment simulation

混沌测试工具,如ChaosBlade[12]、Chaos-Mesh[13],通过故障注入的方式,模拟多种系统资源被破坏时的情况.文献[14-16]通过对运行环境施加压力测试来评测虚拟机的性能.这些工作模拟的是极端情况下的运行环境,虽然可以测试数据库的容错、恢复能力,但不能反映常规部署环境下的运行情况,缺乏环境模拟的通用性,且工具运行后,负载对资源的影响强度是稳定的,不能模拟动态变化的场景.

在模拟环境资源消耗的工作中,很多工作提出了对单一资源的模拟方法.ProWGen[17]是一种Web 代理工作负载生成器,用来评估Web 代理的缓存替换策略.GISMO[18]可以生成贴近现实的、可扩展的互联网请求流,用于对互联网流媒体传输技术进行基准测试.文献[19]使用真实的工作负载特征来模拟用户的文件访问行为.文献[20]通过模拟计算密集型工作负载以评估高性能计算架构的性能.文献[21-24]设计了高并行应用模拟器,用于探索大规模的众核处理器的设计空间.但是这些工作是为了评测特定应用的性能而设计的,生成的是特定应用程序的工作负载,不适合用于模拟实际业务场景中的运行环境.在模拟真实的应用环境的资源消耗工作中,比较完整的只有Jeong 等[25]研发的系统测试负载生成器和华东师范大学数据科学与工程学院研发的动态工作负载生成器.

Jeong 等[25]通过生成特征负载来模拟应用的真实运行环境.但是这个工作只能摸拟CPU、内存和磁盘资源的消耗情况,没有考虑网络资源的消耗,也未模拟软件资源的变化,全面性不佳,而且该工具无法模拟环境负载的动态变化.此外,该工作使用的负载较笨重,实现目标场景的速度较慢,且模拟某类资源消耗的负载运行时,会对其余硬件资源造成明显的消耗,导致模拟出的场景不够准确.

华东师范大学数据学院的Zhang 等[26]自主研发了一个数据库环境模拟的动态工作负载生成器,可以模拟CPU、内存、磁盘、网络资源的消耗情况.该工作提出了一种动态环境生成算法,可以模拟出较复杂的应用运行环境,但是全面性不佳,比如对于磁盘,只模拟了占用容量和产生顺序写I/O 的场景,对于网络资源只考虑了模拟网络带宽的占用情况,且未考虑软件资源方面的影响,能制造的场景有限.该工作在负载设计时未规避对其余资源的明显消耗,造成模拟资源消耗场景的准确性欠佳.

2 环境模拟设计

本文假定在常规运行环境下,数据库实例所在平台系统的硬件资源 (CPU、内存、磁盘、网络) 充足,数据库内部无异常问题.在这个前提条件下,如果数据库负载的执行效率变低,则有可能与负载可使用资源变少有关.常规的运行环境是指存在应用程序间争抢资源行为的系统环境.常规的运行环境变化会对数据库的性能稳定性和数据库服务的可用性造成考验.本工具可模拟的常规运行场景如表2所示.一般情况下,密集消耗某种资源负载的同时也可能消耗其他资源,模拟负载之间的相互作用会给环境资源模拟造成困难.因此,本文提出在设计每种资源的消耗负载上要尽量避免或者降低对其余资源的影响,从而实现准确模拟出各类数据库运行的场景.

表2 常规运行环境模拟负载总结Tab.2 Summary of regular runtime environment simulation workload

在极端情况下,系统中可能发生某种硬件资源被占满,甚至被破坏的情况,这对数据库运行会是很大的阻碍.极端情况包含对资源的彻底性破坏和非彻底性破坏.彻底性破坏是对资源造成完全损坏,包括切断网络链接、破坏进程、主机宕机、破坏文件等;非彻底性破坏是对资源造成部分损坏,如网络发生部分丢包、网络包损坏等情况.本工具可模拟的极端运行场景如表3 所示.对于数据库评测而言,这些极端环境可以帮助测试数据库的容错性、高可用性.

表3 极端运行环境模拟负载总结Tab.3 Summary of extreme runtime environment simulation workload

2.1 模拟CPU 占用

如果数据库可用的CPU 资源不足,包含连接、排序等计算复杂度高的负载性能就会被拖慢.CPU 负载的模拟需要考虑两个问题: CPU 占用的速度、其他资源的相关影响.

本工具模拟CPU 占用的方法是分配一定数量的单线程进程,在 while(true) 条件下无限次地执行赋值操作,从而占用相应核数的CPU.由于每个进程都在执行无限循环操作,进程占用的CPU 使用率会迅速升至100%.对CPU 消耗大的负载通常会涉及算术计算,但执行计算的过程中难免会涉及对计算中间结果的缓存,进而使得内存资源被明显消耗,这样就无法准确模拟出只大量占用CPU 资源的场景.因此,本工具的CPU 占用模拟负载中只设计了赋值这样简单的操作,从而避免了计算中间结果的缓存,几乎不会引起对内存的消耗.

2.2 模拟内存占用

如果内存资源不足,数据库可能会频繁地对磁盘进行读写操作,而对基于LSM Tree 设计的缓存管理会造成更严重的频繁数据合并,导致读写操作密集型数据库的负载性能受到影响.为了模拟对内存资源的占用,需要解决如下问题: 一是内存环境的迅速构造,二是对其他资源的无感生成方法.

本工具模拟内存占用的方法是创建tmpfs 文件系统,再往里写入指定大小的$data_size数据,以达到占据内存的目的,模拟内存占用执行的命令如下所示.tmpfs 是一种虚拟内存文件系统,使用内存来存储数据.本工具采用Linux 自带的 dd 命令对tmpfs 文件系统填充数据,方法是从/dev/zero读取数据,再写入tmpfs,以达到占用内存的效果.

由于/dev/zero是一个伪设备,它只产生空字符流,读取不会产生I/O.将读取的数据写入内存的速度与每次操作的数据块大小bs 有关,当bs 被设为磁盘扇区大小的较大倍数 (如512 K) 时,可大幅减少系统调用带来的额外消耗,从而提高占据内存的速度.写入过程中自然不会产生对磁盘的写I/O,只会对CPU 消耗造成少量影响,而保持占据内存的过程几乎不会消耗磁盘I/O 和CPU.

2.3 模拟磁盘占用

数据库可用的磁盘资源如果不足,数据库的读写速度也会因此受限.已有的工作大多关注对磁盘容量的模拟,忽视了对指定强度的IOPS (Input/output Operations Per Second)的仿真,但是IOPS 会影响即时的写入和读入性能,对数据库处理磁盘操作密集型负载的性能会有明显影响.

2.3.1 磁盘容量

系统中可用的磁盘容量如果不足,数据库写入的数据无法落盘,便会被迫终止对负载的处理.本工具设计的占用磁盘容量的负载使用了Linux 自带的dd 命令来实现,具体命令如下.

该负载会复制一定大小的数据,写入文件系统中,达到占用磁盘容量的目的.用户可以指定需要占用的磁盘容量 ($data_size).执行过程中虽然包含对数据文件的多次读、写,但是本工具在负载中指定了控制读、写方式的参数“flags=direct”,在对磁盘进行操作时便可以规避文件系统的缓存,所以执行负载期间对CPU 有轻微影响,几乎不消耗内存.为了减少写入数据期间对磁盘I/O 的影响,本负载会从/dev/zero(一个只产生空字符流的伪设备) 中读取数据,这样可以避免产生读I/O.

2.3.2 磁盘IOPS

磁盘IOPS 是磁盘每秒产生I/O 的次数.系统硬盘每秒产生I/O 的能力是有上限的,如果被其他负载占用过多IOPS,数据库对磁盘的读写速度会减慢,进而影响数据库负载处理的效率.产生指定强度磁盘IOPS 环境的难点在于如下两点: ①必须保证负载每次对数据块的操作可以在单次I/O 操作中完成,才能准确模拟出IOPS;② 磁盘每次I/O 操作的时长可能会波动变化,难以估计指定数量的I/O 操作能否在预期时长内完成.故目前没有资源模拟工具可以准确产生指定强度的磁盘IOPS.

本工具用于模拟占用磁盘IOPS 的负载类型有6 种: 顺序写、读、读写以及随机写、读、读写,可制造多样化的I/O 场景.

(1) 顺序操作的IOPS

对顺序IOPS 占用的模拟如算法1 所示.该负载每秒执行一次 dd 命令对磁盘执行顺序读/写操作,负载执行期间操作磁盘块的数量近似是对磁盘进行I/O 操作次数,即磁盘IOPS.为了更精确地模拟产生指定强度的磁盘IOPS,本负载将每次I/O 操作的数据块大小 (bs 参数) 设置为dd 命令允许的最小值 (512 B),这个数值远小于磁盘的block 大小 (通常只有4 096 B 左右),保证负载每次对数据块的I/O 操作都能一次性完成,并且每次I/O 操作的时延微小,这样可以尽可能地保证需要模拟的I/O 操作可以在1 s 内完成.

制造顺序写的I/O 时,该负载会模拟写入数据到文件系统中.其中,读取的数据源 (fileread) 为/dev/zero,它是一个伪设备,只产生空字符流,读取它并不会产生读磁盘的I/O.执行顺序写的负载期间,产生的I/O 都集中在输出文件的过程中.

顺序读的负载会从文件系统的一个物理分区中复制一定大小的文件,输出到/dev/null(filewrite) ./dev/null也是个伪设备,相当于黑洞,对该设备写入数据不会产生写磁盘的I/O.执行顺序读的负载期间,产生的I/O 都集中在读取文件系统的过程中.

顺序读写的负载会从文件系统的一个物理分区中复制一定大小的文件,输出到另一个物理分区的文件中.所以执行这个负载时,读写文件的过程都会产生I/O.

本负载在模拟产生高强度磁盘IOPS 场景时,对磁盘余量不会有明显影响,这是由于每次I/O 只操作512 B 数据;普通HDD 硬盘的IOPS 上限只有几千次,即使是SSD 硬盘的IOPS 上限也只有几万次,就算用户需要模拟高强度的IOPS,该负载每秒需要操作的数据量也只有几MB,对磁盘容量的影响小于万分之一.

一般来说,对磁盘进行操作的负载需要频繁使用内存,故而不可避免地会占用CPU 和内存.和占用磁盘容量的负载相似,本工具中占用磁盘IOPS 的负载指定了对磁盘进行操作时规避使用文件缓存,执行负载期间对CPU 和内存消耗都只有轻微影响,并且尽可能地保证了磁盘I/O 强度的准确性.

(2) 随机操作的IOPS

模拟随机操作的算法与顺序操作的大致相同,其中,由于dd 命令只支持对磁盘的顺序操作,本工具通过调用轻量级的磁盘测试工具fio[27]来实现对磁盘的随机操作.系统测试中,fio 常被用于生成混合随机读写的密集 I/O 工作负载.fio 运行时会引起更多的系统调用,所以对于CPU、内存的影响会更大一点.

2.4 模拟网络限制和破坏

如果网络质量不佳,数据传输的速度会大大减慢,这对于分布式数据库的负载处理速度会有不小影响.本工具可以模拟特殊的网络环境,使网络发生带宽受限、传输产生时延等情况,也可以模拟网络发生丢包、包损坏等非彻底性破坏.本工具通过直接对网卡施加流量限制来模拟特殊的网络环境.负载中调用了Linux 的tc 工具来实现对网络资源消耗和网络故障的模拟.tc 在网络输出端口处建立一个队列,以实现对Linux 内核的流量控制.tc 可以针对特定网卡来制造流量限制,达成效果的速度快,并且运行期间几乎不会引起对CPU、内存的消耗.

本工具还可以模拟断开机器间的网络连接.负载可以实现断开特定端口的网络,为软件的可靠性测试而服务,如果用户需要测试数据库的运行容错性,可以用本负载来切断数据库端口的网络.本负载的实现方法是调用tcpkill 命令,终止对应的tcp 连接.

2.5 模拟文件损坏

当数据文件被损坏时,数据库需要执行备份恢复或者启用备库来保证业务的开展,实现高可用.对于单点式数据库,这种情况可以考验数据库的备份恢复能力;对于分布式数据库,特别是主备架构,这种情况还可以测试各节点间数据的同步能力.

本工具通过强制执行系统的删除命令来删除用户指定的文件或文件夹,以此模拟数据文件丢失的情况.除此之外,还可以模拟数据文件被恶意篡改的场景,通过输出随机字符改写数据文件来实现.

2.6 模拟创建进程和破坏进程

应用程序连续创建进程的行为会拖慢系统开启新进程的速度,进而影响数据库 (尤其是多进程数据库) 对负载的处理效率.本工具通过循环创建多个子进程来模拟占用进程资源空间.

数据库进程如果被意外终止,数据库对负载的执行会被强行结束,并且可能发生大量事务回滚,数据库的容错能力是不小的考验.本工具通过调用系统命令来终止进程,以此模拟应用程序的进程被意外结束的情况.

除此之外,本工具还可以通过执行进程炸弹 (fork bomb),即不停创建新进程来耗尽系统资源,执行命令如下所示.

在这个负载运行期间,有进程数量限制的系统无法开起新的进程,不限制进程数量的系统则会停止响应,对数据库运行会是很大的打击.

2.7 模拟主机宕机

如果数据库所在的主机发生宕机,数据库处理负载的过程会被强行终止.这种情况可以考验数据库运行负载的正确性和数据库的高可用性.

本工具可模拟以下多种数据库所在的机器意外宕机的情况:

(1) 通过强制执行关闭电源的命令,模拟机器的电源被破坏,机器内所有进程被迫终止运行的情况;

(2) 通过执行正常关机的命令,模拟机器被正常关机的情况;

(3) 通过切断该机器的所有网络连接,模拟机器失联的情况.

3 动态变化环境模拟

在云环境中,密集的工作负载及新容器的建立可能会更频繁地发生,即云数据库的运行环境可能随时会动态变化.因此,为了模拟出更真实的环境,需要建模环境负载在不同时段的资源消耗情况.

本工具模拟负载动态变化的方法如算法2 所示,动态性主要由控制环境模拟负载执行的变量targetList和timeList来实现.算法2 中,Workloadtype表示用户当前要执行的环境负载,targetList和timeList是两个长度相等的数组,timeList中的每个值表示不同的时间段,targetList中对应位置的值是这个时间段内负载需模拟的目标环境状态.本工具通过timeList来控制负载强度发生变化的时间点,通过targetList中相邻目标环境状态的差值(Δadjust)来控制负载强度变化的幅度,比如WordloadCP U(3 2 4,60 30 50)中,targetList是 (3 2 4) ,timeList是 (60 30 50),该负载一共要执行140 s(60+30+50),模拟出的场景是: 在前60 s 占用3 核CPU,60~ 90 s 只占用2 核CPU,最后50 s 占用4 核CPU.

4 运行环境模拟总体设计

应用环境模拟框架如图2 所示.客户端组件包括控制器、解析器、负载生成器和测试报告生成器.服务器端包括动态变化控制器、负载执行器、指标收集器和目标服务器,其中,动态变化控制器用于控制负载强度变化,负载执行器中的常规负载执行器会对目标服务器执行环境资源消耗模拟,极端负载执行器会对目标服务器的资源执行资源破坏.指标收集器会在每次测试结束后将细粒度的测试指标反馈给测试报告生成器,用于输出详尽的测试报告.

图2 运行环境模拟总体框架Fig.2 General framework for runtime environment simulation

环境仿真模拟的流程如下.

(1) 控制器从系统配置文件中识别出当前的环境模拟任务,并启动解析器;

(2) 解析器根据词法规则解析当前的模拟任务,并发送负载生成器;

(3) 负载生成器收到环境模拟任务,生成环境负载,发送给服务端的动态变化控制器;

(4) 动态变化控制器调用负载执行器对目标服务器,即数据库所在的机器,执行环境负载,并控制环境负载的强度和执行时长;

(5) 运行环境模拟负载期间,指标收集器会收集监控器返回的数据库性能指标及数据库所在机器的资源消耗情况,并发送客户端;

(6) 每轮测试结束后,测试报告生成器会自动输出详尽的测试报告,包括环境因素和数据库系统性能.

5 实 验

5.1 实验环境

实验共用了4 台服务器,均安装CentOS 7.9 操作系统,并配备8 核CPU,32 GB 内存,磁盘转数15 000 r/min、容量130 GB 的硬盘和千兆网.

图3 展示了实验集群部署情况.其中一台服务器 (Machine A) 专用于评测环境模拟负载的性能.另外3 台服务器同属于另一个局域网并搭建分布式Kubernetes 集群,用于评测环境模拟负载对数据库测试的有效性,分布式TiDB 数据库[28]搭建在Kubernetes 集群上.该TiDB 数据库包含1 个PD 节点,1 个TiDB 计算节点,3 个TiKV 节点,每个数据库节点安装在不同的Kubernetes 容器中.PD 节点和TiDB 计算节点分别部署在不同的Kubernetes Follower 节点上,避免被Kubernetes 的主控组件抢占资源;3 个TiKV 节点各部署在不同的Kubernetes 节点上.

图3 实验集群部署Fig.3 Deployment of experimental cluster

5.2 模拟占用硬件资源

实验分别模拟占用CPU、内存、磁盘和网络资源,展示本文设计的环境模拟负载对模拟资源占用的准确性,并与目前环境模拟方向最先进的工作 (华东师范大学数据学院研发的数据库环境模拟工具,下文用作者名Chunxi 来代指该工具) 在达成模拟目标的速度、对其余环境资源的占用程度等方面进行对比.

为了准确展示环境模拟的效果,运行环境模拟负载期间除了资源监控工具nmon[29]以外,未在实验服务器中运行与实验无关的软件、程序.每次实验开始前,本工具会自动启动nmon,并等待nmon 工具开始记录指标后再执行资源模拟负载,防止nmon 因为启动缓慢而采集不到实验前几秒的资源消耗变化.nmon 是一个轻量级的资源监控工具,运行期间几乎不影响CPU 和内存使用率.但nmon 需要每秒统计各类资源的消耗情况,并输出性能指标到监控结果文件中,这个过程本身会消耗少量磁盘I/O.为了消除nmon 对磁盘I/O 的影响,本工具在每次实验前,将虚拟文件系统tmpfs 挂载到指定目录中,限制该文件目录大小为1 MB.由于tmpfs 使用内存来存储数据,nmon 每次输出指标数据都相当于直接写入内存中,避免了对磁盘资源的使用,并且分配给nmon 使用的这1 MB 内存大小只占于实验服务器内存总量的十万分之三,影响微小.

5.2.1 模拟占用CPU

本实验分别将模拟占用CPU 的目标设置为系统CPU 总量的25%、50%、75%、87.5%.从图4 可以看出,本工具可以快速实现对指定核数CPU 的稳定消耗,即使对87.5% CPU 的占用也可以在2 s 内实现.而Chunxi 的工具在占用CPU 期间,CPU 占用率先超过了目标占用率,几秒后再回落到目标占用率,并且在模拟期间的前半段中CPU 占用率有小幅波动,这是因为该工具以Java 程序的形式运行,运行过程会带来少量额外的CPU 消耗.

图4 模拟占用CPUFig.4 Simulation of CPU usage

图5 展示了模拟CPU 的负载运行期间对内存的影响情况.本工作的负载对内存的平均消耗只在0.4%以内,这是因为本文设计的负载以Shell 脚本的形式运行,通过调用指定数量的单线程进程做无限死循环的操作来快速占用CPU,这个方法几乎不消耗内存.而Chunxi 的程序以Java 程序的形式运行,该负载执行期间不停地进行pai 计算,计算过程会使用缓存来记录中间计算结果.所以当需要占用的CPU 核数越多,该负载对内存的占用也明显增加,在占用87.5% CPU 期间甚至消耗了约50%内存.两个工具运行过程中对磁盘I/O 几乎无影响.

图5 占用CPU 的负载对内存的平均影响Fig.5 Average impact of CPU workload on memory

5.2.2 模拟占用内存

本实验分别模拟了占用25%、50%、75%、87.5%内存的场景.如图6 所示,本工具的负载实现内存占用时,将参数bs 设为512 K,实现目标的效率很高,即使占用87.5%的内存也只需要8 s,比Chunxi的工作负载 (花费11 s) 实现得略快一些.图7 反映了模拟内存占用的负载运行期间对CPU 的平均影响.本工作负载因为在向内存填充数据时使用了系统命令,这段时间内会对系统内核CPU 造成少量消耗;但填充内存之后只保持着不释放内存的状态,在此期间不消耗CPU.所以本负载运行期间对CPU 的平均消耗率很低,即使占用了87.5%内存,对CPU 的平均消耗也不到3%.而Chunxi 的内存占用工具是以C 语言程序的形式运行的,在填充内存期间对用户态CPU 和系统内核CPU 都造成了一定消耗;并且在占用内存期间,该负载保持活跃地操作内存,导致该程序对CPU 的消耗明显,即使只占用25%内存也消耗了超过10% CPU.两个工具都采用直接对内存写入数据的方式来占据内存,所以在工具运行期间几乎没有消耗磁盘资源.

图6 模拟占用内存Fig.6 Simulation of memory usage

图7 占用内存的负载对CPU 的平均影响Fig.7 Average impact of memory workload on CPU

5.2.3 模拟占用磁盘

本实验分别模拟了占用20%、40%、60%、90%磁盘IOPS 的场景.如图8 所示,本工具的负载基本可以准确地模拟出20%、40%、60%磁盘IOPS;在模拟产生90%磁盘IOPS 时,也许因为太密集的磁盘操作本身会给磁盘带来压力,使得每次I/O 操作的时间发生波动,所以负载刚开始运行时的模拟效果不太准确,到中、后期模拟的IOPS 变为平稳,并符合模拟目标.由于本工作负载直接对磁盘进行操作,工具运行期间对内存几乎无消耗.Chunxi 的负载运行时会占用一定程度的IOPS,但是由于该工作无法保证对每个数据块的操作都在一次I/O 中完成,并且在负载设计中未规避对内存的使用,导致该负载对指定强度的IOPS 的占用完全不准确,所以该工具不适合用于模拟磁盘IOPS.

图8 模拟占用磁盘IOPSFig.8 Simulation of disk IOPS usage

图9 和图10 分别展示了占用IOPS 期间系统中CPU 平均使用率、内存使用率.本工具运行期间避免使用文件系统缓存,所以运行期间对CPU 消耗微小,并且几乎不使用内存.而Chunxi 的工具在运行过程中大量使用了内存,这会触发大量的系统调用,进而导致CPU 的使用率也较高.

图9 占用磁盘IOPS 对CPU 的平均影响Fig.9 Average impact of disk IOPS workload on CPU

图10 占用磁盘IOPS 对内存的平均影响Fig.10 Average impact of disk IOPS workload on memory

5.2.4 模拟网络环境

本工作和Chunxi 的工作都能模拟网络环境,但实现的方式不同: 本工作通过直接控制机器网卡,实现对网络带宽的限制;而对比工作通过使用Java 程序在两台服务器间保持传输数据以达成占用网络带宽.为了更直观地比较两个工具对网络带宽的影响效果,在运行本工具前先在实验服务器与另一台服务器之间保持传输数据,方便监控工具记录工具启动后系统中网络带宽的变化;而在用Chunxi的工具做实验时,直接用监控工具记录系统中网络带宽的变化情况.

实验比较了两个工具运行期间网络带宽的变化情况,以此来反映两个工具对网络带宽占用的效果.图11 展示了影响20%、40%、60%、90%网络带宽时,系统中网络带宽的变化情况.本工具通过直接对系统网卡施加限制,达成目标环境的效率快,在2 s 内都能实现需要模拟的目标值,并且模拟出了稳定的网络环境.Chunxi 的工具通过不停在两台服务器间传输数据来实现对网络带宽的占用.该程序调用了Netty 技术,需要花费一点时间等待两台服务器间建立通信.该工具执行期间,占用的网络带宽大小发生明显波动.这也许是因为该工具在服务器间传输数据过程中遭遇了通道阻塞,导致部分数据无法被及时传输.

图11 模拟影响网络带宽Fig.11 Simulation of network bandwidth usage

图12 反映了运行环境负载期间系统中CPU 的变化情况.本工具直接对系统网卡施加限制,这个方法几乎不会影响其他硬件资源的使用.由于测试本负载期间在两台服务器间保持传输数据,这本身会带来轻微的CPU 消耗,所以单独运行本工具时的CPU 使用率会比图中记录的使用率更低一些.而Chunxi 的工具通过执行调用了Netty 技术的Java 程序来实现对网络资源的占用.该负载在运行期间需要密集地计算要传输数据的大小,因此,网络模拟的工作负载对 CPU 有较明显影响.两个工具运行过程中对磁盘I/O 几乎无影响.

图12 模拟网络环境的负载对CPU 的平均影响Fig.12 Average impact of network bandwidth workload on CPU

5.3 动态变化的环境模拟

实验模拟了自定义的环境场景,展示了本工具对动态变化环境的模拟效果,模拟场景包含常规运行环境和极端运行环境,模拟资源包含硬件资源、软件资源.

本实验在部署于Kubernetes 集群的分布式TiDB 数据库中执行,数据库节点部署在Kubernetes集群的容器内,部署情况如图2 所示.其中PD-0 是调度节点,负责数据库集群的资源调度;3 个TiKV 节点都是数据存储节点;TiDB-0 是计算节点,负责向调度节点请求数据的存储位置,再向存储节点请求数据,最后将处理结果返回给客户端.

本实验检验了TiDB 数据库在运行TPC-C[30]负载期间遭遇各类环境模拟负载时发生的性能变化.实验使用SF=90 的TPC-C 负载,每次实验执行TPC-C 负载400 s,共有90 个线程并发执行TPC-C负载,每个线程每秒发送10 000 个事务处理请求.在TPC-C 负载运行120 s 后开始执行环境模拟负载.实验一共进行了30 次,最终结果取平均值.

5.3.1 动态环境模拟负载

为配合环境模拟工具的使用,本工作设计了一套环境负载描述语言,让用户更加方便、灵活地实现自定义环境场景的模拟.

由于TPC-C 的各类事务中包含密集的读、写操作,执行TPC-C 负载时TiDB 需要频繁地与PD和TiKV 进行网络通信来请求数据,TiKV 上会有较大的磁盘操作压力.本实验针对这些负载行为特征,使用环境负载描述语言书写了一份动态环境模拟的案例,内容见表4.该负载包含2 个并发子块的并发执行负载,包含2 个并发子块的并发执行负载.不同并发子块间的负载会并发执行,并发子块内的负载内容会按行顺序执行.表4 的行2 到行4 是第一个并发子块的内容,分别执行占用tikv-0 所在容器的CPU、tikv-1 所在容器的磁盘读I/O、终止tikv-1 的进程;行6 到行8 是第二个并发子块的内容,分别要执行限制tidb-0 所在容器的网络带宽、占用tikv-2 所在容器的磁盘读I/O,终止tikv-2 进程.

表4 动态环境模拟负载Tab.4 Dynamic environment simulation workload

5.3.2 数据库性能变化

本实验将注入环境模拟负载前数据库吞吐量的峰值视为100%.注入环境负载期间,数据库的性能变化如图13 所示.

图13 TiDB 数据库的性能变化Fig.13 Performance changes of TiDB database

运行环境模拟负载的前30 s (图13 的120~ 150 s),由于环境负载占用了7 核CPU (系统CPU 总核数的87.5%),同时限制网络带宽为原始大小的80%,在此期间数据库的平均吞吐量下降到约10%;之后的30 s,环境负载对CPU 的占用减少到4 核,对网络带宽的限制放宽到原始带宽大小的90%,期间数据库的平均吞吐量回升到50%左右;后30 s,环境负载对CPU 的占用减少到2 核,但是限制网络带宽大小为原始大小的10%,数据库的吞吐量骤降到10%.这验证了本工具可以模拟无故障情况下的常规运行环境,可帮助测试数据库服务性能的稳定性,即数据库系统服务质量受部署环境动态变化的影响情况.

对CPU 和网络带宽的消耗结束后,环境模拟负载开始占用磁盘的读I/O (图13 的210~ 240 s),首先占用3 000 IOPS (约是磁盘IOPS 上限的60%),期间数据库的性能只有40%左右,后30 s 内,环境模拟负载只占用1 000 IOPS (约是磁盘IOPS 上限的20%),期间数据库的性能恢复到原吞吐峰值的65%左右.这说明当可使用的磁盘资源不足时,数据库处理磁盘操作密集型负载的速度会被限制.

占用磁盘的读I/O 结束后,环境模拟负载将tikv-1 和tikv-2 的进程终止.TiDB 数据库花费约30 s(图13 的270~ 300 s) 将被终止的tikv 自动重启,在进程恢复期间数据库的吞吐量为0,说明对事务的处理被迫中止;tikv 进程恢复后,数据库的性能逐渐回升,在70 s 后大致恢复到环境模拟负载执行前的性能水平.这验证了本工具可以实现对数据库进程等软件资源的破坏,可模拟极端的运行场景,可以帮助测试数据库运行的高可用性和容错性.

6 结 论

本文分析了数据库在开放环境下运行可能会遇到的关键问题,提出并定义了模拟环境状态的有效负载,完成对环境状态的建模,并基于Woodpecker 测试框架设计且实现了一个全面、通用的数据库运行环境动态模拟工具,可用于评测数据库系统服务的可靠性、稳定性.该工具可生成对硬件资源以及针对数据库软件资源的指定强度的环境负载,达成对各类资源消耗场景的准确模拟.本工具可以方便用户高效地实现自定义环境负载,降低数据库测试工作难度,实验验证了其优越性.

本文针对数据库外部的运行环境设计了这个环境模拟工具,但数据库内部的运行环境也是高度复杂,有研究、模拟的价值.今后会将数据库内部的运行环境模拟作为未来工作,进一步扩展该环境模拟工具.

猜你喜欢

磁盘消耗内存
玉钢烧结降低固体燃料消耗实践
转炉炼钢降低钢铁料消耗的生产实践
降低钢铁料消耗的生产实践
它的好 它的坏 详解动态磁盘
创建虚拟机磁盘方式的选择
解决Windows磁盘签名冲突
笔记本内存已经在涨价了,但幅度不大,升级扩容无须等待
“春夏秋冬”的内存
Windows系统下动态磁盘卷的分析与研究
If We Burne d All the Fossil Fuel in the World