Apache Kafka 是一个凋谢源代码的分布式消息传递平台,高吞吐量和低提早交付数据。在规模上,它每天能够解决数万亿条记录,同时还提供容错、复制和主动劫难复原性能。
只管 Kafka 有许多不同的应用场景,但最常见的是作为应用程序之间的音讯 broker。Kafka 能够从多个上游源头接管、解决和重新分配音讯到多个上游使用者,而无需重新配置应用程序。这就能够流式传输大量数据,同时放弃应用程序的涣散耦合,反对诸如分布式计算、日志记录和监控、网站流动跟踪以及物联网(IoT)设施通信之类的场景。
因为 Kafka 提供了应用程序之间的要害管道,因而可靠性至关重要。咱们须要打算来加重几种可能的故障模式,包含:
- 音讯 broker 中断和其余不失常的群集情况
- Apache ZooKeeper 生效,这是 Kafka 的要害依赖项
- 上游和上游应用程序中的故障
不用期待这些故障在预生产或生产中产生,咱们就能通过混沌工程被动对其进行测试,以便制订适当的策略加重影响。本文,咱们将演示混沌工程如何帮忙进步 Kafka 部署的可靠性。为此,咱们将应用企业 SaaS 混沌工程平台 Gremlin 创立并运行四个混沌试验。通过浏览本文,理解 Kafka 群集可能产生故障的不同形式,如何设计混沌试验来测试这些故障模式,以及如何应用观测后果进步其可靠性。
本文中,咱们将在 Confluent 平台上演示凌乱的试验,该平台是 Kafka 最后的创建者提供的企业事件流平台。Confluent 平台基于 Kafka 构建并增加企业性能(例如基于 Web 的 GUI,全面的安全控制以及轻松部署多区域集群的性能)。然而,本文中的试验将实用于任何 Kafka 集群。
Apache Kafka 架构概述
为了理解 Kafka 如何从混沌工程中受害,咱们应该首先钻研一下 Kafka 的体系架构设计。
Kafka 应用发布者 / 订阅者(或 pub/sub)消息传递模型传输数据。上游应用程序(在 Kafka 中称为发布者或生产者)会生成发送到 Kafka 服务器(称为 broker)的音讯。而后,上游应用程序(在 Kafka 中称为订阅者或使用者)能够从 broker 获取这些音讯。音讯被组织在主题的类别中,消费者能够订阅一个或多个主题以应用其音讯。通过充当生产者和消费者之间的中间人,Kafka 使咱们可能彼此独立地治理上游和上游应用程序。
Kafka 将每个主题细分为多个分区。分区能够跨多个 broker 镜像以提供复制。这还容许多个使用者(更具体地说,是使用者组)同时解决一个主题。为了避免多个生产者写入单个分区,每个分区都有一个充当领导者的 broker,以及没有或多个充当追随者的 broker。新音讯将被写入领导者,而追随者则将其复制。追随者被齐全复制后,称为同步正本(ISR)。
该过程由 Apache ZooKeeper 协调,ZooKeeper 治理无关 Kafka 集群的元数据,例如哪些分区调配给了哪些 broker。ZooKeeper 是 Kafka 的必要依赖项(编者注:2.8 版本就能够不须要 ZooKeeper 了),但在其本人的集群上作为齐全独立的服务运行。改善 Kafka 集群的可靠性必然波及进步其关联的 ZooKeeper 集群的可靠性。
Kafka 和 Confluent 平台还有其余组件,然而在进步可靠性时,这些是最重要的思考因素。当本文介绍其余组件时,咱们会对其进行更具体的阐明。
为何要对 Kafka 进行混沌工程?
混沌工程是一种被动测试系统故障的办法,目标是使它们更具韧性。咱们通过向零碎中注入大量受控故障,察看影响并解决察看到的问题。这使咱们可能在零碎呈现问题之前,为用户找到解决问题的办法,同时还教会了咱们更多对于零碎在各种条件下的行为信息。
因为有数不清的配置选项,灵便的生产者和消费者的部署形式以及许多其余因素,使得像 Kafka 这样的分布式系统难以高效治理和运维。仅仅使咱们的 broker 和 ZooKeeper 节点不生效是不够的,咱们须要思考在应用程序、正本和其余基础架构组件中可能产生的更加轻微和难以预测的问题。这些可能会以意想不到的形式影响整个部署,如果在生产中产生,则可能须要进行大量的排障开销。
应用混沌工程,咱们能够被动测试这些类型的故障,并在部署到生产之前解决这些故障,从而升高停机和紧急事件的危险。
在 Kafka 上运行混沌试验
在本节中,咱们将逐渐介绍在 Confluent 平台上部署执行四个不同的混沌试验。混沌试验是一个有打算的过程,将故障注入零碎以理解其响应形式。在零碎上运行任何试验之前,应充分考虑并开发要运行的试验。
创立试验时:
- 第一步,设定假说要答复的问题以及预期后果是什么。例如,如果试验是测试接受 broker 中断的能力,则假说可能会指出:“如果 broker 节点产生故障,则音讯会主动路由到其余 broker,而不会失落数据。”
- 第二步,定义爆炸半径,受试验影响的基础架构组件。减小爆炸半径限度了试验可能对基础架构造成的潜在危害,同时还能够将精力集中在特定零碎上。咱们强烈建议从尽可能小的爆炸半径开始,而后随着对进行混沌试验的适应性进步,将其增大。另外,还应该定义幅度,即注入攻打的规模或影响力。例如,低幅度的试验可能是在生产者和 broker 之间的网络流量中减少 20 毫秒的提早。大幅度的试验可能是减少 500 毫秒的提早,因为这将对性能和吞吐量产生显着的影响。与爆炸半径一样,从低幅度开始,而后逐步增大。
- 第三步,监控基础架构。确定哪些指标将助力得出无关假说的论断,在测试之前进行观测以建设基线,并在整个测试过程中记录这些指标,以便能够监测预期和意外的变动。借助 Confluent 平台,咱们能够应用 Control Center 从 Web 浏览器实时直观地察看群集的性能。
- 第四步,运行试验。Gremlin 容许以简略、平安和牢靠的形式在应用程序和基础架构上运行试验。咱们通过运行注入攻打来做到这一点,它提供了各种向零碎中注入故障的办法。咱们还要定义停止条件,这是咱们应该进行测试以防止意外损坏的条件。应用 Gremlin,咱们能够将状态查看定义为场景的一部分。通过状态查看,咱们能够在进行注入攻打时验证服务状态。如果基础架构运行不失常,并且状态查看失败,将主动进行试验。另外,咱们能够应用内置的暂停按钮立刻进行试验。
- 第五步,从察看后果得出结论。它是否证实或反驳了原先的假如?应用收集的后果来批改基础架构,而后围绕这些改良设计新的试验。随着工夫的推移,反复此过程将有助于使 Kafka 部署更具韧性。本文中介绍的试验绝不是详尽无遗的,而应将其作为在零碎上进行试验的终点。请记住,只管咱们正在 Confluent 平台上运行这些试验,但它们能够在任何 Kafka 集群上执行。
请留神,咱们应用的是基于 Kafka 2.5.0 构建的 Confluent 平台 5.5.0。屏幕截图和配置详细信息可能会因版本而异。
试验 1: Broker 负载对解决提早的影响
资源利用率可能会对音讯吞吐量产生显着影响。如果 broker 正在经验较高的 CPU、内存或磁盘 I / O 利用率,则解决音讯的能力将受到限制。因为 Kafka 的效率依赖于最慢的组件,因而提早可能会在整个管道中产生级联效应,并导致故障条件,例如生产者备份和复制提早。高负载还会影响集群操作,例如 broker 运行状况查看,分区重新分配和领导者选举,从而使整个集群处于不失常状态。
优化 Kafka 时要思考的两个最重要的指标是网络提早和磁盘 I /O。Broker 一直在本地存储中读写数据,随着音讯速率和群集大小的减少,带宽应用可能成为限度因素。在确定集群大小时,咱们应该确定资源利用率在哪一点上会对性能和稳定性产生不利影响。
为了确定这一点,咱们将进行一个混沌试验,逐步提高 broker 之间的磁盘 I / O 利用率,并察看其对吞吐量的影响。在运行此试验时,咱们将应用 Kafka Music 演示应用程序发送间断的数据流。该应用程序将音讯发送到散布在所有三个 broker 中的多个主题,并应用 Kafka Streams 聚合和解决音讯。
应用 IO Gremlin 生成 Broker 负载
在本试验中,咱们将应用 IO Gremlin 在 broker 节点上生成大量磁盘 I / O 申请。咱们将创立一个计划,并在四个阶段中逐渐减少注入攻打的强度。每次注入攻打将运行三分钟,两头会距离一分钟,因而咱们能够轻松地将 I / O 利用率的变动与吞吐量的变动分割起来。
此外,咱们将创立一个状态查看,该状态查看应用 Kafka Monitoring API 在每个阶段之间查看 broker 的运行状况。状态查看是通过 Gremlin 发送主动 HTTP 申请到咱们选定的端点,在这种状况下,该端点是咱们集群的 REST API 服务器。咱们将应用主题的端点来检索 broker 的状态,并解析 JSON 响应以确定它们以后是否处于同步状态。如果任何 broker 不同步,咱们将立刻进行试验并将其标记为失败。在场景运行期间,咱们还将应用 Confluent Control Center 监督吞吐量和提早。
- 假如:磁盘 I / O 的减少将导致吞吐量的相应降落。
- 论断:即便将磁盘 I / O 减少到 150 MB/ s 以上,技术攻打也不会对吞吐量或提早产生显著影响。两项指标均保持稳定,咱们的 broker 均未失去同步或复制有余,也没有音讯失落或损坏。
目前,这给咱们留下了很多开销,然而随着利用范畴的扩充,对吞吐量的要求可能会减少。咱们应该亲密关注磁盘 I / O 利用率,以确保有足够的扩大空间。如果开始留神到磁盘 I / O 减少和吞吐量缩小,则应思考:
- 应用更快的存储设备,例如更高的 RPM 磁盘或固态存储
- 应用更无效的压缩算法,例如 Snappy 或 LZ4
试验 2: 音讯失落造成数据失落的危险
为了确保胜利传递音讯,生产者和 broker 应用确认机制。当 broker 将音讯提交到其本地日志时,它会与响应生产者进行确认,表明已胜利接管到该音讯,并且生产者能够发送下一条音讯。这样能够缩小生产者和 broker 之间失落音讯的危险,然而不能避免 broker 之间失落音讯。
例如,假如咱们有一个 broker 领导,刚从生产者那里收到音讯并发送了确认。Broker 的每个订阅者当初都应该获取音讯并将其提交到他们本人的本地日志中。然而,broker 在其任何订阅者获取最新消息之前意外失败。跟随者没有一个晓得生产者发送了一条音讯,然而生产者曾经收到了确认,因而它已移至下一条音讯。除非咱们能够复原产生故障的 broker,或者找到其余从新发送音讯的办法,否则音讯实际上曾经失落了。
咱们如何确定在集群上产生这种状况的危险?借助混沌工程,咱们能够模仿 broker 领导的故障并监控音讯流,以确定潜在的数据失落。
应用黑洞 Gremlin 模仿 Broker 领导中断
在此试验中,咱们将应用黑洞 Gremlin 删除往返于 broker 领导的所有网络流量。此试验很大水平上取决于工夫安顿,因为咱们心愿在 broker 收到音讯之后,但在其订阅者能够复制音讯之前,引起 broker 的失败。这可通过两种形式执行此操作:
- 比追随者低的工夫距离,发送间断的音讯流,启动试验,并寻找使用者输入中的空白(replica.fetch.wait.max.ms)。
- 发送音讯后,立刻应用 Gremlin API 从生产者应用程序触发混沌试验。
在本试验中,咱们将应用第一种形式。应用程序每 100 毫秒产生一条新音讯。音讯流的输入记录为 JSON 列表,并对其剖析以查找任何差距或时序上的不统一。咱们将对其注入攻打 30 秒,这将生成 300 条音讯(每 100 毫秒一条音讯)。
- 假如:因为领导者失败,咱们将失落一些音讯,然而 Kafka 将迅速选出新的领导者,并再次胜利复制音讯。
- 后果:只管领导者忽然失败,音讯列表仍显示所有胜利通过的音讯。因为试验前后记录了额定的音讯,因而咱们的管道总共产生了 336 个事件,每个音讯在上一个事件之后大概有 100 毫秒的工夫戳。音讯没有按工夫程序显示,但这很好,因为 Kafka 不保障分区之间音讯的程序。这是输入示例:
如果想保障所有音讯都已保留,则能够在生产者配置中设置 acks = all。这通知生产者在将音讯复制到 broker 领导及其所有订阅者之前,不要发送新音讯。这是最平安的抉择,然而它将吞吐量限度为最慢 broker 的速度,因而可能会对性能和提早产生重大影响。
试验 3: 防止脑裂
Kafka、ZooKeeper 和相似的分布式系统容易受到称为“脑裂”问题的影响。在脑裂中,同一群集内的两个节点失去同步并分区,从而产生群集中两个独自且可能不兼容的视图。这会导致数据不统一,数据损坏,甚至造成第二个群集。
这是怎么产生的?在 Kafka 中,为单个 broker 节点调配了控制器角色。控制器负责检测群集状态的更改,例如失败的 broker、领导者选举和分区调配。每个集群只有一个且只有一个控制器,以保护集群的单个一致性视图。只管这使控制器成为单点故障,但 Kafka 领有解决此类故障的过程。
所有 broker 都会定期向 ZooKeeper 注销,以证实本人的衰弱。如果 broker 的响应工夫超过 zookeeper.session.timeout.ms 设置(默认为 18,000 毫秒),则 ZooKeeper 会将 broker 标记为不失常。如果该 broker 是控制者,则触发控制者选举,正本 ISR 成为新的控制者。这个新的控制器被调配了一个称为控制器纪元的编号,该编号跟踪最新的控制器选举。如果产生故障的控制器从新联机,它将比拟本人的控制器纪元与 ZooKeeper 中存储的纪元,辨认出新选的控制器,而后退回为一般 broker。
这个过程能够避免多数 broker 失败,但如果大部分 broker 都产生了重大故障,那该怎么办呢?咱们能够在不产生脑裂的状况下重新启动它们吗?咱们能够应用混沌工程对此进行验证。
应用关机 Gremlin 重启大多数 broker 节点
此试验中,咱们将应用关机 Gremlin 重新启动集群中的三个 broker 节点中的两个。因为此试验可能会对集群稳定性造成潜在危险(例如,咱们不想意外敞开所有 ZooKeeper 节点),因而想确保在运行该 broker 之前,所有三个 broker 都应处于衰弱状态。咱们将创立一个状态查看,从 Kafka Monitoring API 中获取衰弱 broker 的列表,以验证所有三个 broker 均已启动并正在运行。
这是咱们齐全配置的场景,显示状态检查和关机 Gremlin:
- 假如:Kafka 的吞吐量将临时进行,然而两个 broker 节点都将重新加入群集,而不会呈现问题。
- 后果:控制中心仍列出了三个 broker,但显示其中两个不同步且分区复制有余。这是预料之中的,因为节点曾经失去了与其余 broker 和 ZooKeeper 的分割。
当先前的控制器(broker1)脱机时,ZooKeeper 立刻选举残余的 broker(broker3)为新的控制器。因为这两个 broker 在不超过 ZooKeeper 会话超时的状况下重新启动,因而,从 broker 失常运行工夫的图表,能够看出它们始终处于联机状态。然而,当咱们的音讯管道转移到 broker3 时,查看吞吐量和正本的图表,就会发现这显著地影响了吞吐量和分区运行状况。
尽管如此,broker 毫无意外地重新加入了集群。由此能够得出结论,咱们的集群能够接受临时的少数失败。性能将显着降落,集群将须要选举新的领导者,重新分配分区,并在其余 broker 之间复制数据,然而不会陷入脑裂的场面。如果花更长的工夫来复原 broker,则此后果可能会有所不同,因而,咱们心愿确定在重大生产中断的状况下,已制订了事件响应打算。
试验 4: ZooKeeper 中断
ZooKeeper 是 Kafka 的根本依赖项。它负责诸如辨认 broker、选举领导者以及跟踪 broker 之间的分区散布等流动。ZooKeeper 中断不肯定会导致 Kafka 产生故障,然而如果解决工夫越长,它可能会导致意外问题。
在一个示例中,HubSpot 遇到了 ZooKeeper 故障,起因是短时产生大量备份的申请。ZooKeeper 在几分钟内无奈复原,这又导致 Kafka 节点开始解体。最终导致数据损坏,团队不得不手动将备份数据还原到服务器。尽管这是 HubSpot 解决的一个不寻常的状况,但它强调了将 ZooKeeper 和 Kafka 作为独自服务和整体服务进行测试的重要性。
https://blog.hubspot.com/cust…
应用黑洞 Gremlin 模仿 ZooKeeper 中断
此试验中,咱们要验证 Kafka 集群能够在 ZooKeeper 意外中断时能幸免于难。咱们将应用黑洞 Gremlin 抛弃往返 ZooKeeper 节点的所有流量。咱们将在控制中心中监督群集状态的同时运行注入攻打五分钟。
- 假如:Kafka 能够忍耐短期的 ZooKeeper 中断,而不会解体,失落数据或损坏数据。然而,直到 ZooKeeper 从新联机之前,对群集状态的任何更改都将无奈解决。
- 后果:运行试验对音讯吞吐量或 broker 可用性没有任何后果。正如咱们所假如的,能够持续产生和应用音讯而不会出现意外问题。
如果其中一个 broker 失败,则在 ZooKeeper 从新联机之前,broker 无奈重新加入群集。仅此一项并不太可能导致失败,然而可能导致另一个问题:级联失败。例如,broker 失败将导致生产者将累赘转移到其余 broker 上。如果这些 broker 靠近生产极限,就会顺次解体。即便咱们使失败的 broker 从新联机,也将无奈退出集群,直到 ZooKeeper 再次可用。
该试验表明,咱们能够容忍 ZooKeeper 临时失败,然而依然应该迅速工作以使其复原在线状态。还应该寻找加重齐全中断危险的办法,例如在多个区域之间散布 ZooKeeper 以实现冗余。只管这将减少经营老本并减少提早,但与使整个集群呈现生产故障相比,这是一个很小的老本。
进一步提高 Kafka 的可靠性
Kafka 是一个简单的平台,具备大量相互依赖的组件和流程。要使 Kafka 牢靠地运行,就须要进行打算、继续的监控和被动的故障测试。这不仅实用于咱们的 Kafka 和 ZooKeeper 集群,还实用于应用 Kafka 的应用程序。混沌工程使咱们可能平安无效地发现 Kafka 部署中的可靠性问题。为明天的故障做筹备能够避免或缩小未来产生故障的危险和影响,从而节俭组织的工夫、工作量以及解救客户的信赖。
当初,咱们曾经展现了 Kafka 的四个不同的混沌试验,请尝试注册 Gremlin Free 帐户来运行这些试验。创立试验时,请思考 Kafka 部署中的潜在故障点(例如,broker 与使用者之间的连贯),并察看它们如何应答不同的注入攻打。如果发现问题,请施行修复程序并反复试验以验证它能够解决问题。随着零碎变得更加牢靠,逐步减少幅度(试验的强度)和爆炸半径(受试验影响的零碎数量),以便全面地测试整个部署。
起源:混沌工程实际 作者:李大山
原文作者:Andree Newman 原文起源:Gremlin.com
原文题目:The first 4 chaos experiments to run on Apache Kafka
申明:文章取得作者受权在 IDCF 社区公众号(devopshub)转发。优质内容共享给思否平台的技术伙伴,如原作者有其余思考请分割小编删除,致谢。
7 月每周四晚 8 点,【冬哥有话说】研发效力工具专场,公众号留言“研发效力”可获取地址
- 7 月 8 日,周文洋《微软 DevOps 工具链的 “ 爱恨情仇 ”(Azure DevOps)》
- 7 月 15 日,陈逊《复杂型研发合作模式下的效力晋升实际》
- 7 月 22 日,张扬《基础设施即代码的⾃动化测试摸索》
- 7 月 29 日,胡贤彬《自动化测试,如何做到「攻防兼备」?》