基于 Chaos Mesh® 和 Argo 打造分布式测试平台

2024-04-08 02:38

本文主要是介绍基于 Chaos Mesh® 和 Argo 打造分布式测试平台,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者: 叶奔 殷成文

不久前我们开源了基于 Kubernetes 的混沌测试工具 Chaos Mesh®,Chaos Mesh 提供了模拟系统异常状况的能力,但这只是混沌工程中的一环,完整混沌工程核心原则包含了系统稳定状态的定义、提出假设、运行实验以及验证和改进。

本篇文章主要介绍我们是如何在 Chaos Mesh 和 Argo 的基础上打造自己的自动化测试平台 TiPocket,实现完全自动化的混沌测试,构成混沌测试完整闭环。

为什么需要 TiPocket?

为了确保用户的数据安全,我们需要确保给用户提供的每一个 TiDB 版本都已经经过了严格的测试,所以我们为 TiDB 设计了各种异常场景,并实现了数十个测试 Case,所以在我们的 Kubernetes 集群中,可能同时运行着十几个甚至几十个混沌实验,即使我们拥有了 Chaos Mesh 来帮助我们管理错误注入,但这还远不够,我们还需要去管理 TiDB 集群,需要去收集指标,需要去分析结果,同时进行如此多的混沌实验,另一方面,我们还需要对 TiDB 生态中的其他工具进行混沌测试,这是无法想象的,因此,我们开发了 TiPocket 来解放自己。

TiPocket 是一个基于 Kubernetes 和 Chaos Mesh 的完全自动化测试框架,目前我们主要使用它用来测试 TiDB 集群,不过由于它 All-in-K8s 的特性以及可扩展的接口,它目前也支持测试 TiDB 生态中的其他组件,只要简单的添加应用在 Kubernetes 中 Create/Delete 的逻辑,就可以很轻松的添加对各种应用的支持。

Chaos Mesh 提供故障模拟的能力

故障注入可以说是混沌测试中重要的一环,并且在分布式数据库领域,可能遇到的故障又非常的多,不仅仅是节点故障、各种网络故障、文件系统故障,更甚至可能遇到内核故障。如果 TiDB 不能正确的处理这些异常,那么后果是无法想象的,这也是最开始我们开发 Chaos Mesh 的主要原因之一。而 TiPocket 中很好的结合了 Chaos Mesh,将 Chaos Mesh 作为最基本的依赖之一,以达到混沌测试中故障注入的目的。

目前我们已经在 TiPocket 提供了多种类型的故障注入:

  • Network:基于 Chaos Mesh 的 NetworkChaos,提供模拟的网络分区,或者链路随机的丢包、乱序、重复、时延等。

  • Time Skew:基于 TimeChaos,模拟待测试容器发生时间偏移。TimeChaos 的实现也是非常有趣,感兴趣的话可以参考我们以前的 文章。

  • Kill:通过 PodChaos 来 kill 对应的 pod。细分下来我们也实现了多种 kill 类型,最简单的就是随机删除集群内的任意pod;如果针对各个组件,也有专门的 Chaos 随机 kill 一个或两个 TiKV 节点,或者是专门 kill PD 的 leader 节点。

  • IO:基于 IOChaos,我们用的比较多的是给 TiKV 注入 IO Delay,再去看写入的情况。

解决了故障注入的问题,那么接下来我们就需要判断我们的系统在 TiDB 注入了故障后,是否符合预期呢?

如何判断 TiDB 是否正常?

为了高效的达成这目标,TiPocket 中实现了数十个测试 Case 并结合不同的检查工具来验证 TiDB 是正常。下面会用几个测试 Case 为例,简要介绍 TiPocket 是如何验证 TiDB 的。

Fuzz 测试:SQLsmith

SQLsmith 是一个生成随机 SQL 的工具,TiPocket 分别创建一个 TiDB 集群和一个 MySQL 实例,使用 go-sqlsmith 生成的随机 SQL 分别在 TiDB 和 MySQL 上执行,并对 TiDB 集群注入各种故障,最后对比执行的结果,如果出现结果不一致的情况,那么我们可以判断我们的系统存在问题。

事务一致性测试:Bank/Porcupine

1. Bank

银行测试是模拟一个银行系统中的转账流程。在这个测试中,我们创建一系列模拟银行账户,并随时选择两个账户使用事务进行相互转账,一个账户减去一定的金额,另一个账户增加对应的金额,这样的交易不断的并发执行着。在快照隔离下,所有的转账都必须保证每一个时刻所有的账户的总金额是相同的。TiDB 即使在注入各种故障的情况下,依然需要保证这样的约束是成立的,一旦约束被破坏,那么就可以判断此时的系统是不符合预期的。

2. Porcupine

Porcupine 一个用 Go 实现的线性一致性验证工具。是基于 P-compositionality 算法,P-compositionality 算法利用了线性一致性的 Locality 原理,即如果一个调用历史的所有子历史都满足线性一致性,那么这个历史本身也满足线性一致性。因此,可以将一些不相关的历史划分开来,形成多个规模更小的子历史,转而验证这些子历史的线性一致性。在 TiPocket 有许多 Case 中使用了 Pocupine 检查器 去检查生成的历史,从而判断 TiDB 是否满足线性一致性的约束。

事务隔离级别测试:Elle

Elle 是用来验证数据库事务隔离级别的检查工具。Elle 是一个纯黑盒的测试工具,巧妙的构造了一个测试场景,通过客户端生成的历史构造出依赖关系图,通过判断依赖图中是否有环以及分析环来确定事务的出现的异常类型,来确定事务的隔离级别。在 TiPocket 中,我们参考 Elle 项目,实现了 Go 版本的 Elle 检查工具 go-elle,并结合 go-elle 工具来验证 TiDB 的隔离级别。

这些只是 TiPocket 中用来验证 TiDB 正确性的一小部分,如果读者有兴趣可以自行阅读相关 源码,查看更多的验证方法。现在我们有了故障注入,有了待测的 TiDB 集群,有了检验 TiDB 的方式,那么我们该如让这些混沌实验自动化的运行起来呢?如何最大化的利用资源呢?在下一小节我们会介绍 TiPocket 中是如何解决这个问题的。

Argo 让流程自动化起来

和大多数的工程师一样,我们第一个想法是自己开发,造轮子,让 TiPocket 具备调度的功能和管理的功能,但是考虑到我们目前的人力和时间,并且我们知道目前已经有很多开源的工具可以提供类似的功能,所以最后我们选择让 TiPocket 更加纯粹,将调度和管理交给更加合适的工具去负责。在考虑到我们 All-in-K8s 的特性,Argo 就成为我们不二的选择。

Argo 是一个为 Kubernetes 而设计的工作流引擎,很早就在社区中开源,并且马上得到了广泛的关注和应用。像在知名的 kubeflow 项目中,就大量使用了 Argo。下面我们首先来介绍下 Argo 的基本概念,再来讲讲如何结合 TiPocket 和 Argo。

Argo 为工作流抽象出了几种 CRD。最主要的包括了 Workflow Template、Workflow 以及 Cron Workflow。

  • Workflow Template 可以理解成工作流的模版,我们可以为每个不同的测试任务预先定义好模版,实际运行测试时传入不同的参数。

  • Workflow 将多个工作流模版进行编排,以不同的顺序组合起来进行执行,即实际运行的任务。基于 Argo 本身提供的能力,我们还可以在 pipeline 中实现条件判断、循环、DAG 等多种复杂的能力。

  • Cron Workflow 顾名思义,以 cron 的方式运行 Workflow,非常适合我们想要长期运行某些测试任务的情况。

下面我们看一个简单示例:

spec:entrypoint: call-tipocket-bankarguments:parameters:- name: nsvalue: tipocket-bank- name: nemesisvalue: random_kill,kill_pd_leader_5min,partition_one,subcritical_skews,big_skews,shuffle-leader-scheduler,shuffle-region-scheduler,random-merge-schedulertemplates:- name: call-tipocket-banksteps:- - name: call-wait-clustertemplateRef:name: wait-clustertemplate: wait-cluster- - name: call-tipocket-banktemplateRef:name: tipocket-banktemplate: tipocket-bank

上面的示例中是我们定义的 Bank 测试的 Workflow。示例中我们用到了 Workflow template 以及使用参数定义我们需要的故障注入,这样我们就可以重复使用模版,根据不同的测试场景来同时运行多个 Workflow。在 TiPocket 中我们的故障注入是使用 nemesis 参数定义,也就是说我们提供了大量的故障注入,当用户想要使用的时候,只需要设置对应的参数即可,当然用户可以自己拓展 TiPocket 去增加更多的故障注入。更多的 Workflow 以及模版的示例,可以在 TiPocket 的仓库中找到。使用 Argo 可以很好的处理各种复杂的逻辑,可以做到以写代码的方式去定义我们 Workflow,这对于开发者来说十分友好, 这也是我们选择 Argo 的重要原因之一。

现在我们的混沌实验自动化跑起来了,这时候如果我们的结果不符合预期,我们该如何去定位我们的问题呢?幸运的是 TiDB 中会保存丰富的监控信息,但是 Log 也是必不可少的。因此我们需要一个更好的日志收集手段,让我们的系统具有更好的可观测性。

Loki 提高实验的可观测性

可观测性,在云原生中系统中是非常重要的一环。通常来说可观测性主要包含 Metrics(指标),Logging(日志)和 Tracing(追踪)。由于 TiPocket 中主要运行的 test case,都是针对于测试 TiDB 集群,常依靠 metrics 和日志就能够定位问题。

Metrics 不用多说,Prometheus 已经成为了在 Kubernetes 监控的事实标准。然而对于日志,却没有一个统一的答案。比如 elasticsearch,fluent-bit 以及 Kibana 的解决方案,尽管这一套系统运行良好,但是却会消耗比较多的资源,并且维护成本太高。最终我们放弃了 EFK 的方案,而是采用了 Grafana 开源的 Loki 项目来作为日志的解决方案。

Loki 采用了跟 Prometheus 一样的 label 系统,我们可以很轻松的将 Prometheus 的监控指标与对应 pod 的日志结合起来,并且使用类似的查询语言去查询。另外 Grafana 目前也已经支持了 Loki dashboard,所以只需要使用 Grafana 就同时展示监控指标和日志了,非常方便。另一方面,TiDB 自带的监控系统中也含有 Grafana 组件,这样我就可以直接复用此 Grafana。

看一下效果

上面介绍了这么多,最后让我们看一下在 TiPocket 中一个完整的混沌实验到底是什么样子的呢?

  1. 创建 Argo Cron Workflow 任务,在这个 Cron Workflow 中定义待测试的集群,注入的故障,用来检查 TiDB 集群正确性的测试 Case,以及任务的执行时间等。在 Cron Workflow 在运行过程中有需要的话还支持实时查看 Case 的日志。
    在这里插入图片描述

  2. 集群内部通过 Prometheus-operator 运行了 Prometheus。在 Prometheus 中配置了针对 Argo workflow 的告警规则。如果任务失败,则会发送到 Alertmanager,再由 Alertmanager 发送到 Slack channel 通知结果。

  3. 警报中包含了对应 Argo Workflow 的地址,在 Workflow 页面中我们可以直接点击链接跳转到 Grafana 查找集群监控及日志。此时就可以进入下图的日志 Dashboard 进行查询了。

    不过这个时候也由不太方便的地方。目前在 Grafana logs dashboard 中,没有办法设置日志查询的 step 参数。这个参数用来控制日志查询时的采样,并且为了控制查询的数量,它会随着你查询的总时间而自动调整。比如查询 1 分钟的日志,step 会自动配置成 1s;查询1天的日志,step 可能变成了 30s,在这个时候就会有部分日志展示不出来。所以一般推荐尽量加入多的过滤条件进行搜索,或者使用 Loki 的命令行工具 logcli 将所有日志下载下来再查询。

  4. 如果测试 Case 正常结束,那么集群会正常清理,等待 Argo 调度下一次测试的执行。

以上就是我们如何利用 Chaos Mesh 和一些开源项目打造自动化混沌测试平台的完整流程。如果你也对混沌工程感兴趣的话,欢迎一起参与 TiPocket 和 Chaos Mesh !

这篇关于基于 Chaos Mesh® 和 Argo 打造分布式测试平台的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/884350

相关文章

Nginx设置连接超时并进行测试的方法步骤

《Nginx设置连接超时并进行测试的方法步骤》在高并发场景下,如果客户端与服务器的连接长时间未响应,会占用大量的系统资源,影响其他正常请求的处理效率,为了解决这个问题,可以通过设置Nginx的连接... 目录设置连接超时目的操作步骤测试连接超时测试方法:总结:设置连接超时目的设置客户端与服务器之间的连接

用Java打造简易计算器的实现步骤

《用Java打造简易计算器的实现步骤》:本文主要介绍如何设计和实现一个简单的Java命令行计算器程序,该程序能够执行基本的数学运算(加、减、乘、除),文中通过代码介绍的非常详细,需要的朋友可以参考... 目录目标:一、项目概述与功能规划二、代码实现步骤三、测试与优化四、总结与收获总结目标:简单计算器,设计

java如何分布式锁实现和选型

《java如何分布式锁实现和选型》文章介绍了分布式锁的重要性以及在分布式系统中常见的问题和需求,它详细阐述了如何使用分布式锁来确保数据的一致性和系统的高可用性,文章还提供了基于数据库、Redis和Zo... 目录引言:分布式锁的重要性与分布式系统中的常见问题和需求分布式锁的重要性分布式系统中常见的问题和需求

Golang使用etcd构建分布式锁的示例分享

《Golang使用etcd构建分布式锁的示例分享》在本教程中,我们将学习如何使用Go和etcd构建分布式锁系统,分布式锁系统对于管理对分布式系统中共享资源的并发访问至关重要,它有助于维护一致性,防止竞... 目录引言环境准备新建Go项目实现加锁和解锁功能测试分布式锁重构实现失败重试总结引言我们将使用Go作

Redis分布式锁使用及说明

《Redis分布式锁使用及说明》本文总结了Redis和Zookeeper在高可用性和高一致性场景下的应用,并详细介绍了Redis的分布式锁实现方式,包括使用Lua脚本和续期机制,最后,提到了RedLo... 目录Redis分布式锁加锁方式怎么会解错锁?举个小案例吧解锁方式续期总结Redis分布式锁如果追求

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖