关于apache:Apache-Kafka的4个混沌工程实验-IDCF
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,则此后果可能会有所不同,因而,咱们心愿确定在重大生产中断的状况下,已制订了事件响应打算。 ...