Kafka文档&教程(一)

1、入门指南

1.1 介绍

什么是事件流?

事件流是人体中枢神经系统的数字等效物。它是构建“永远在线”世界的技术基础,在这个“永远在线”的世界中,企业越来越多地被软件定义和自动化,软件的用户更多地是软件本身。

从技术角度来说,事件流是实时从事件源(如数据库、传感器、移动设备、云服务和软件应用程序)捕获数据的做法,以事件流的形式存储这些事件流以供后续检索,实时以及回顾性地操作、处理和响应事件流,以及根据需要将事件流路由到不同的目标技术。事件流确保了数据的连续流动和解释,以便正确的信息在正确的地点、正确的时间可用。

事件流可以用于什么?

事件流被应用于各行各业和组织的广泛用例。它的许多例子包括:

  • 实时处理支付和金融交易,如在股票交易所、银行和保险公司。
  • 实时跟踪和监控汽车、卡车、车队和货运,如在物流和汽车行业。
  • 持续捕获和分析来自物联网设备或其他设备的传感器数据,如在工厂和风电场。
  • 收集并立即响应客户互动和订单,如在零售、酒店和旅游行业以及移动应用程序。
  • 监控医院护理中的患者并预测病情变化,以确保在紧急情况下及时治疗。
  • 连接、存储并使公司不同部门产生的数据可用。
  • 作为数据平台、事件驱动架构和微服务的基础。

Apache Kafka® 是一个事件流平台。这意味着什么?
Kafka 结合了三个关键能力,使您可以使用单一的经过实战测试的解决方案端到端实现事件流的用例:

  • 发布(写入)和订阅(读取)事件流,包括从其他系统连续导入/导出数据。
  • 持久可靠地存储事件流,时间长短由您决定。
  • 实时或回顾性地处理事件流。

所有这些功能都以分布式、高度可扩展、弹性、容错和安全的方式提供。Kafka 可以部署在裸机硬件、虚拟机和容器上,也可以在本地和云中部署。您可以选择自己管理 Kafka 环境,也可以使用各种供应商提供的全托管服务。

Kafka 究竟如何工作?

Kafka 是一个由服务器和客户端组成的分布式系统,通过高性能的 TCP 网络协议进行通信。它可以在本地以及云环境中的裸机硬件、虚拟机和容器上部署。

服务器:

Kafka 作为一个由一个或多个服务器组成的集群运行,可以跨越多个数据中心或云区域。其中一些服务器形成存储层,称为 broker(brokers)其他服务器运行 Kafka Connect 以持续导入和导出数据,将 Kafka 与您现有的系统(如关系数据库以及其他 Kafka 集群)集成为事件流。为了让您实现关键任务用例,Kafka 集群具有高度可扩展性和容错性:如果任何服务器失败,其他服务器将接管它们的工作,以确保没有任何数据丢失的连续操作。

客户端:

它们允许您编写分布式应用程序和微服务,以并行、大规模和容错的方式读取、写入和处理事件流,即使在网络问题或机器故障的情况下也是如此。Kafka 附带了一些这样的客户端,这些客户端得到了 Kafka 社区提供的数十个客户端的增强:客户端可用于 Java 和 Scala,包括更高级别的 Kafka Streams 库,以及 Go、Python、C/C++ 和许多其他编程语言以及 REST API。

主要概念和术语

事件记录了“发生了某些事情”的事实。在文档中,它也被称为记录或消息。当您读取或写入 Kafka 数据时,您是以事件的形式进行的。从概念上讲,一个事件具有键、值、时间戳和可选的元数据头。这是一个示例事件:

  • 事件键:"Alice"
  • 事件值:"向 Bob 支付了 200 美元"
  • 事件时间戳:"2020 年 6 月 25 日下午 2:06"


Producer是发布(写入)事件到 Kafka 的客户端应用程序,Consumer是订阅(读取和处理)这些事件的客户端。在 Kafka 中,Producer和Consumer是完全解耦和相互不知情的,这是 Kafka 著名的高可扩展性的关键设计元素之一。例如,Producer从不需要等待Consumer。Kafka 提供了各种保证,例如能够精确一次处理事件的能力。

事件被组织并持久存储在topic中。非常简化地说,topic类似于文件系统中的文件夹,事件是该文件夹中的文件。一个示例topic名称可能是“支付”。Kafka 中的topic始终是多Producer和多订阅者:一个topic可以有零、一个或多个Producer向其写入事件,以及零、一个或多个订阅这些事件的Consumer。topic中的事件可以根据需要多次读取 - 与传统的消息系统不同,事件在消费后不会被删除。相反,您可以通过每个topic的配置设置定义 Kafka 应保留您的事件多长时间,之后旧事件将被丢弃。Kafka 的性能实际上与数据大小无关,因此长时间存储数据是完全可以接受的。

topic被分区,意味着一个topic分布在多个“桶”上,这些“桶”位于不同的 Kafka brokers上。

  • 数据的这种分布式放置对于可扩展性非常重要,因为它允许客户端应用程序同时从多个broker读取和写入数据。
  • 当一个新的事件发布到一个topic时,它实际上被追加到该topic的一个分区中。
  • 具有相同事件键的事件(例如,客户或车辆 ID)被写入到同一个分区,并且 Kafka 保证任何给定topic分区的Consumer将始终按照它们被写入的完全相同顺序读取该分区的事件

图示:这个topic有四个分区 P1–P4。两个不同的Producer客户端正在独立地通过网络向topic的分区写入新事件。在图示中用颜色表示的具有相同键的事件被写入同一个分区。请注意,如果适当,两个Producer都可以写入同一个分区。

为了使您的数据具有容错性和高可用性,每个topic都可以被复制,甚至可以跨地理区域或数据中心,以便总是有多个broker拥有数据的副本,以防万一出现问题,您想要对broker进行维护等。一个常见的生产设置是复制因子为 3,即,您的数据总会有三份副本。这种复制是在topic分区级别进行的。

这个入门介绍应该足够了。如果您感兴趣,文档的设计部分详细解释了 Kafka 的各种概念。

Kafka API

除了用于管理和管理任务的命令行工具外,Kafka 还为 Java 和 Scala 提供了五个核心 API:

  • Admin API,用于管理和检查topic、brokers和其他 Kafka 对象。
  • Producer API,用于将事件流发布(写入)到一个或多个 Kafka topic。
  • Consumer API,用于订阅(读取)一个或多个topic,并处理产生到它们的topic的事件流。
  • Kafka Streams API,用于实现流处理应用程序和微服务。它提供了更高级别的函数来处理事件流,包括转换、有状态操作(如聚合和连接)、基于事件时间的窗口处理等。输入从一个或多个topic读取,以生成输出到一个或多个topic,有效地将输入流转换为输出流。
  • Kafka Connect API,用于构建和运行可重用的导入/导出连接器,从外部系统和应用程序消费(读取)或产生(写入)事件流,以便它们可以与 Kafka 集成。例如,一个连接到关系数据库(如 PostgreSQL)的连接器可能会捕获一组表的每个更改。然而,在实践中,您通常不需要实现自己的连接器,因为 Kafka 社区已经提供了数百个现成的连接器可用。

接下来去哪里

要获得 Kafka 的实践经验,请遵循快速入门指南。
要更详细地了解 Kafka,请阅读文档。您还可以选择阅读 Kafka 书籍和学术论文。
浏览用例,了解我们全球社区中的其他用户如何从 Kafka 中获得价值。
加入本地 Kafka 聚会小组,并观看 Kafka Summit 的演讲,这是 Kafka 社区的主要会议。

1.2 用例

这里是 Apache Kafka® 的一些流行用例的描述。要查看这些领域的一些概述,请参见此博客文章。

消息传递

Kafka 作为更传统的消息broker的替代品效果很好。消息broker用于多种原因(例如,将处理与数据Producer解耦,缓冲未处理的消息等)。与大多数消息系统相比,Kafka 具有更好的吞吐量、内置的分区、复制和容错性,这使其成为大规模消息处理应用程序的良好解决方案。
根据我们的经验,消息传递用例通常是相对较低的吞吐量,但可能需要低端到端延迟并且通常依赖于 Kafka 提供的强大持久性保证。

在这个领域,Kafka 与 ActiveMQ 或 RabbitMQ 等传统消息系统相当。

网站活动跟踪

Kafka 最初的用例是能够将用户活动跟踪管道重建为一组实时发布-订阅 feed。这意味着站点活动(页面浏览、搜索或用户可能采取的其他操作)被发布到中心topic,每个活动类型都有一个topic。这些 feed 可用于订阅,包括实时处理、实时监控和加载到 Hadoop 或离线数据仓库系统中进行离线处理和报告。
活动跟踪通常是非常高容量的,因为每个用户页面浏览会生成许多活动消息。

指标

Kafka 通常用于操作监控数据。这涉及从分布式应用程序聚合统计信息,以产生操作数据的集中 feed。

日志聚合

许多人使用 Kafka 作为日志聚合解决方案的替代品。日志聚合通常从服务器上收集物理日志文件,并将它们放在一个中心位置(可能是文件服务器或 HDFS)进行处理。Kafka 抽象了文件的细节,并提供了更清晰的日志或事件数据的抽象,将其作为消息流。这允许更低延迟的处理,并更容易支持多个数据源和分布式数据消费。与以日志为中心的系统(如 Scribe 或 Flume)相比,Kafka 提供了同样好的性能,由于复制而更强的持久性保证,以及更低的端到端延迟。

流处理

许多 Kafka 用户在由多个阶段组成的处理管道中处理数据,其中原始输入数据从 Kafka topic中消费,然后聚合、丰富或以其他方式转换为新topic,以供进一步消费或后续处理。例如,推荐新闻文章的处理管道可能会从 RSS feed 中爬取文章内容并将其发布到“文章”topic;进一步的处理可能会规范化或去重这些内容,并将清理过的文章内容发布到一个新topic;最后一个处理阶段可能会尝试向用户推荐这些内容。这种处理管道创建了基于各个topic的实时数据流图。从 0.10.0.0 版本开始,Apache Kafka 中提供了一个轻量级但功能强大的流处理库,称为 Kafka Streams,用于执行上述数据处理。除了 Kafka Streams 之外,其他替代的开源流处理工具包括 Apache Storm 和 Apache Samza。

事件源

事件源是一种应用程序设计风格,其中状态更改被记录为按时间顺序排列的记录序列。Kafka 对非常大的存储日志数据的支持使其成为构建这种风格的应用程序的优秀后端。

提交日志

Kafka 可以作为分布式系统的外部提交日志。该日志有助于在节点之间复制数据,并作为失败节点恢复其数据的重新同步机制。Kafka 中的日志压缩功能有助于支持此用途。在此用途中,Kafka 与 Apache BookKeeper 项目类似。

1.3 快速入门

本教程假设您是从头开始,没有现有的 Kafka 或 ZooKeeper 数据。由于 Kafka 控制台脚本在基于 Unix 和 Windows 平台上有所不同,在 Windows 平台上,请使用 bin\windows\ 而不是 bin/,并更改脚本扩展名为 .bat

步骤 1:下载代码

下载 2.6.3 版本并解压。

> tar -xzf kafka_2.13-2.6.3.tgz
> cd kafka_2.13-2.6.3

步骤 2:启动服务器

Kafka 使用 ZooKeeper,所以如果您还没有一个,您需要首先启动一个 ZooKeeper 服务器。您可以使用随 kafka 打包的便捷脚本快速启动一个单节点 ZooKeeper 实例。

> bin/zookeeper-server-start.sh config/zookeeper.properties
[2013-04-22 15:01:37,495] INFO Reading configuration from: config/zookeeper.properties (org.apache.zookeeper.server.quorum.QuorumPeerConfig)
...

现在启动 Kafka 服务器:

> bin/kafka-server-start.sh config/server.properties
[2013-04-22 15:01:47,028] INFO Verifying properties (kafka.utils.VerifiableProperties)
[2013-04-22 15:01:47,051] INFO Property socket.send.buffer.bytes is overridden to 1048576 (kafka.utils.VerifiableProperties)
...

步骤 3:创建topic

让我们创建一个名为“test”的topic,它具有单个分区和只有一个副本:

> bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test

我们现在可以通过运行列出topic命令来查看topic:

> bin/kafka-topics.sh --list --bootstrap-server localhost:9092
test

或者,您可以配置broker在发布到不存在的topic时自动创建topic,而不是手动创建topic。

步骤 4:发送一些消息

Kafka 附带了一个命令行客户端,它将从文件或标准输入中获取输入,并将其作为消息发送到 Kafka 集群。默认情况下,每行将作为单独的消息发送。

运行Producer,然后在控制台输入一些消息以发送到服务器。

> bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test
This is a message
This is another message

步骤 5:启动Consumer

Kafka 还有一个命令行Consumer,它将把消息转储到标准输出。

> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
This is a message
This is another message

如果您在不同的终端中运行上述每个命令,那么您现在应该能够在Producer终端中输入消息,并在Consumer终端中看到它们。

步骤 6:设置多broker集群

到目前为止,我们一直在对单个broker进行操作,但这并不有趣。对于 Kafka,单个broker只是一个大小为一的集群,所以除了启动更多的broker实例之外,没有什么太大的变化。但是,为了感受一下,让我们将我们的集群扩展到三个节点(仍然都在我们的本地机器上)。

首先,我们为每个broker制作一个配置文件(在 Windows 上使用复制命令):

> cp config/server.properties config/server-1.properties
> cp config/server.properties config/server-2.properties

现在编辑这些新文件并设置以下属性:

config/server-1.properties:

broker.id=1
listeners=PLAINTEXT://:9093
log.dirs=/tmp/kafka-logs-1

config/server-2.properties:

broker.id=2
listeners=PLAINTEXT://:9094
log.dirs=/tmp/kafka-logs-2

broker.id 属性是集群中每个节点的唯一且永久名称。我们不得不覆盖端口和日志目录,只是因为我们在同一台机器上运行所有这些,我们希望防止broker都试图在同一个端口上注册或覆盖彼此的数据。

我们已经启动了 Zookeeper 和单节点,所以我们只需要启动两个新节点:

> bin/kafka-server-start.sh config/server-1.properties &
...
> bin/kafka-server-start.sh config/server-2.properties &
...

现在创建一个新的topic,复制因子为三:

> bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 3 --partitions 1 --topic my-replicated-topic

好的,但现在我们有了一个集群,我们怎么知道哪个broker在做什么?要查看这一点,请运行“describe topics”命令:

> bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic my-replicated-topic
Topic:my-replicated-topic	PartitionCount:1	ReplicationFactor:3	Configs:
	Topic: my-replicated-topic	Partition: 0	Leader: 1	Replicas: 1,2,0	Isr: 1,2,0

这是输出的解释。第一行给出了所有分区的摘要,每行额外给出了一个分区的信息。由于我们的topic只有一个分区,所以只有一行。

“leader” 是负责给定分区的所有读写的节点。每个节点将是随机选择的分区的一部分的 leader。
“replicas” 是复制此分区日志的节点列表,无论它们是否是 leader,甚至不管它们当前是否存活。
“isr” 是“同步”副本的集合。这是副本列表的子集,当前存活并赶上了 leader。
请注意,在我的示例中,节点 1 是topic唯一分区的 leader。

这个命令是用来描述一个名为 my-replicated-topic 的 Kafka 主题的详细信息。下面是命令的组成部分和输出结果的解释:

  • bin/kafka-topics.sh:这是 Kafka 提供的一个 shell 脚本工具,用于执行与主题相关的操作。
  • --describe:这个选项告诉脚本工具我们要获取主题的描述信息。
  • --bootstrap-server localhost:9092:这个参数指定了 Kafka 集群的引导服务器地址和端口。客户端使用这个地址来连接到 Kafka 集群,并由此发现集群中的其他服务器。
  • --topic my-replicated-topic:这个参数指定了我们要描述的目标主题名称。

输出结果解释:

  • Topic:my-replicated-topic:这是正在描述的主题名称。
  • PartitionCount:1:这表示主题 my-replicated-topic 只有一个分区。
  • ReplicationFactor:3:这表示主题的复制因子为 3,意味着每个分区都有三个副本,这有助于提高数据的可靠性和可用性。
  • Configs::这是主题配置的开始,但在输出中没有显示具体的配置信息。

分区详细信息:

  • Topic: my-replicated-topic:再次确认这是正在描述的主题名称。
  • Partition: 0:这表示分区的 ID 为 0。
  • Leader: 1:这是分区 0 的领导者副本所在的代理(broker)的 ID。所有的读写请求都会通过这个领导者副本进行。
  • Replicas: 1,2,0:这是分区 0 的所有副本列表。每个副本都有一个唯一的 ID。在这个例子中,代理 1 是领导者,代理 2 和代理 0 是追随者副本。
  • Isr: 1,2,0:这是分区 0 的同步副本列表(In-Sync Replicas,简称 ISR)。这些副本与领导者副本保持同步,可以作为领导者的候选者。在这个例子中,所有的副本(1, 2, 0)都在同步列表中,这意味着它们都与领导者保持同步。

总结来说,这个输出告诉我们 my-replicated-topic 主题有一个分区,复制因子为 3,意味着有三个副本。分区 0 的领导者副本在代理 1 上,同时代理 1、代理 2 和代理 0 都是同步副本,它们都与领导者保持同步。这样的设置确保了数据的高可用性和容错性。

我们可以在原始topic上运行相同的命令,看看它在哪里:

> bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic test
Topic:test	PartitionCount:1	ReplicationFactor:1	Configs:
	Topic: test	Partition: 0	Leader: 0	Replicas: 0	Isr: 0

那里没有什么惊喜 - 原始topic没有副本,并且在我们的集群创建时位于服务器 0 上,这是我们集群中唯一的服务器。

让我们发布一些消息到我们的新topic:

> bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic my-replicated-topic
...
my test message 1
my test message 2
^C

现在让我们消费这些消息:

> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
...
my test message 1
my test message 2
^C

现在让我们测试容错性。broker 1 充当 leader,让我们杀死它:

> ps aux | grep server-1.properties
7564 ttys002    0:15.91 /System/Library/Frameworks/JavaVM.framework/Versions/1.8/Home/bin/java...
> kill -9 7564

在 Windows 上使用:

> wmic process where "caption = 'java.exe' and commandline like '%server-1.properties%'" get processid
ProcessId
6016
> taskkill /pid 6016 /f

领导权已切换到其中一个 follower,节点 1 不再在同步副本集中:

> bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic my-replicated-topic
Topic:my-replicated-topic	PartitionCount:1	ReplicationFactor:3	Configs:
	Topic: my-replicated-topic	Partition: 0	Leader: 2	Replicas: 1,2,0	Isr: 2,0

但是,尽管最初接受写入的 leader 下线了,消息仍然可以消费:

> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
...
my test message 1
my test message 2
^C

步骤 7:使用 Kafka Connect 导入/导出数据

从控制台读取数据并将其写回控制台是一个方便的起点,但您可能希望使用来自其他来源的数据,或将数据从Kafka导出到其他系统。对于许多系统而言,您可以使用Kafka Connect来导入或导出数据,而不是编写自定义集成代码。

Kafka Connect是Kafka附带的一个工具,用于将数据导入和导出到Kafka。它是一个可扩展的工具,运行连接器(connectors),这些连接器实现了与外部系统交互的自定义逻辑。在这个快速入门中,我们将看到如何使用简单的连接器运行Kafka Connect,将数据从文件导入到Kafka主题,并将数据从Kafka主题导出到文件。

首先,我们将从创建一些用于测试的初始数据开始:

echo -e "foo\nbar" > test.txt


或者在 Windows 上:

echo foo > test.txt
echo bar >> test.txt


接下来,我们将启动两个以独立模式运行的连接器,这意味着它们在一个单独的、本地的、专用进程中运行。我们提供三个配置文件作为参数。第一个始终是 Kafka Connect 进程的配置,包含常见的配置,如要连接的 Kafka broker和数据的序列化格式。其余的配置文件每个都指定要创建的连接器。这些文件包括唯一的连接器名称、要实例化的连接器类以及连接器所需的任何其他配置。

bin/connect-standalone.sh config/connect-standalone.properties config/connect-file-source.properties config/connect-file-sink.properties


这些随 Kafka 附带的示例配置文件使用您早期启动的默认本地集群配置,并创建两个连接器:第一个是源连接器,它从输入文件中读取行并将其产生到 Kafka topic,第二个是接收器连接器,它从 Kafka topic读取消息并将其产生为输出文件中的一行。

在启动过程中,您将看到许多日志消息,包括一些指示连接器正在实例化的消息。一旦 Kafka Connect 进程启动,源连接器应该开始从 test.txt 读取行并将其产生到topic connect-test,接收器连接器应该开始从topic connect-test 读取消息并将其写入到文件 test.sink.txt。我们可以通过检查输出文件的内容来验证数据已经通过整个管道传递:

more test.sink.txt
foo
bar


请注意,数据存储在 Kafka topic connect-test 中,因此我们也可以运行控制台Consumer来查看topic中的数据(或使用自定义Consumer代码来处理它):

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic connect-test --from-beginning
{"schema":{"type":"string","optional":false},"payload":"foo"}
{"schema":{"type":"string","optional":false},"payload":"bar"}
...


连接器继续处理数据,所以我们可以向文件中添加数据并看到它通过管道移动:

echo Another line >> test.txt

您应该在控制台Consumer输出和接收器文件中看到该行。

步骤 8:使用 Kafka Streams 处理数据

一旦您的数据以事件的形式存储在Kafka中,您就可以使用Java/Scala的Kafka Streams客户端库处理数据。它允许您实现关键任务的实时应用程序和微服务,其中输入和/或输出数据存储在Kafka主题中。Kafka Streams将在客户端上编写和部署标准Java和Scala应用程序的简单性与Kafka服务器端集群技术的优势相结合,使这些应用程序具有高度可扩展性、弹性、容错性和分布式性。该库支持恰好一次的处理、有状态操作和聚合、窗口化、连接、基于事件时间的处理等功能。

为了让您初尝甜头,以下是如何实现流行的WordCount算法的示例:

KStream<String, String> textLines = builder.stream("quickstart-events");

KTable<String, Long> wordCounts = textLines
            .flatMapValues(line -> Arrays.asList(line.toLowerCase().split(" ")))
            .groupBy((keyIgnored, word) -> word)
            .count();

wordCounts.toStream().to("output-topic", Produced.with(Serdes.String(), Serdes.Long()));

Kafka Streams演示应用程序开发教程演示了如何从头到尾编码和运行这样一个流式应用程序。

1.4 生态系统

有许多工具与 Kafka 的主要分发集成。由于篇幅,在以下文章中​​​​​​​列出了许多这些工具,包括流处理系统、Hadoop 集成、监控和部署工具。

kafka生态系统​​​​​​​

1.5 从旧版本升级

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值