面向初学者的 Apache Kafka

190 阅读5分钟

这是我参与更文挑战的第9天,活动详情查看: 更文挑战

Apache Kafka 背景简介 Apache Kafka 是用 Scala 和 Java 编写的,是前 LinkedIn 数据工程师的创造。早在 2011 年,该技术就作为高度可扩展的消息传递系统移交给了开源社区。今天,Apache Kafka 是 Confluent Stream Platform 的一部分,每天处理数万亿个事件。Apache Kafka 已经在市场上站稳脚跟,许多值得信赖的公司都挥舞着 Kafka 的旗帜。

当今复杂系统中涉及的数据和日志必须进行处理、再处理、分析和处理——通常是实时的。这就是 Apache Kafka 在消息流领域发挥重要作用的原因。Kafka 的关键设计原则是基于对高吞吐量架构日益增长的需求而形成的,这些架构易于扩展并提供存储、处理和重新处理流数据的能力。

Kafka主题分区 Kafka 主题分为多个分区,这些分区包含按不可更改顺序的记录。分区中的每条记录都由其唯一的偏移量分配和标识。一个主题也可以有多个分区日志。这允许多个消费者并行读取一个主题。

分区允许通过将数据拆分为跨多个代理的特定主题来并行化主题。

在 Kafka 中,复制是在分区级别实现的。主题分区的冗余单元称为副本。每个分区通常有一个或多个副本,这意味着分区包含通过集群中的几个 Kafka 代理复制的消息。

每个分区(副本)都有一个服务器作为领导者,其余的作为追随者。领导者副本处理特定分区的所有读写请求,追随者复制领导者。如果领导服务器出现故障,则其中一台跟随服务器默认成为领导服务器。您应该努力在领导者之间取得良好的平衡,因此每个代理都是等量分区的领导者,以分配负载。

当生产者向主题发布记录时,它会发布给其领导者。领导者将记录附加到其提交日志并增加其记录偏移量。Kafka 只有在提交记录后才向消费者公开记录,并且每条传入的数据都将堆叠在集群上。

生产者必须知道要写入哪个分区,这不取决于代理。生产者可以将一个键附加到记录上,指示记录应该转到的分区。具有相同键的所有记录将到达同一个分区。在生产者可以发送任何记录之前,它必须从代理请求有关集群的元数据。元数据包含有关哪个代理是每个分区的领导者的信息,并且生产者始终写入分区领导者。然后生产者使用key来知道写哪个partition,默认实现是使用key的hash来计算partition,也可以跳过这一步,自己指定partition。

发布记录时的一个常见错误是为所有记录设置相同的键或空键,这会导致所有记录都在同一个分区中结束,并且您会得到一个不平衡的主题。

消费者和消费群体 消费者可以从特定偏移量开始读取消息,并允许从他们选择的任何偏移点读取消息。这允许消费者在任何时间点加入集群。

低级消费者 Kafka中有两种类型的消费者。首先,低级消费者,其中主题和分区被指定为读取的偏移量,固定位置,开头或结尾。当然,跟踪消耗了哪些偏移量因此相同的记录不会被多次读取,这可能很麻烦。所以 Kafka 添加了另一种更简单的消费方式:

高级消费者 高级消费者(更多称为消费者组)由一个或多个消费者组成。这里通过向消费者添加属性“group.id”来创建消费者组。将相同的组 ID 提供给另一个消费者意味着它将加入同一个组。

代理将根据哪个消费者应该从哪个分区读取数据进行分配,并且它还跟踪每个分区的组所在的偏移量。它通过让所有消费者提交他们处理过的偏移量来跟踪这一点。

每次从组中添加或删除消费者时,都会在组之间重新平衡消费。每次重新平衡时所有使用者都会停止,因此超时或经常重新启动的客户端会降低吞吐量。使消费者无状态,因为消费者可能会在重新平衡时获得不同的分区。

消费者从主题分区拉取消息。不同的消费者可以负责不同的分区。Kafka 可以支持大量消费者并以很少的开销保留大量数据。通过使用消费者组,消费者可以并行化,以便多个消费者可以从一个主题的多个分区中读取数据,从而实现非常高的消息处理吞吐量。分区的数量会影响消费者的最大并行度,因为消费者的数量不能超过分区。

记录永远不会被推送给消费者,当消费者准备好处理消息时,消费者会请求消息。

由于所有记录都在 Kafka 中排队,因此消费者永远不会因大量数据而使自己过载或丢失任何数据。如果消费者在消息处理过程中落后,它可以选择最终赶上并返回实时处理数据。