有关Kafka的介绍(Introduntion of Kafka)

翻译自:http://kafka.apache.org/intro
译者:喝酒不骑马
邮箱:[email protected]


介绍

Apache Kafka®是一个分布式流处理平台。那么,如何正确理解它呢?

一个流处理平台应该有三个核心能力:

  • 发布和订阅数据流,类似于一个消息队列或者是企业消息系统。
  • 以可容错并持久的方式储存数据流。
  • 加工生成的数据流。

Kafka通常被用于两大类应用:

  • 建立实时的、能可靠地从系统或应用中获取数据的数据流管道。
  • 建立实时的、能转化数据流或对数据流做出反应的应用流。

为了弄清楚Kafka是如何完成这些操作,让我们从基础开始挖掘和探索Kafka的各项功能。

首先,让我们来了解几个概念:

  • Kafka作为集群运行在单个或多个可跨多数据中心的服务器上。
  • Kafka集群将数据流存储在叫做主题(topics)的分组中。
  • 每条记录由一个键(key)、一个值(value)和一个时间戳(timestamp)构成。

Kafka的四个核心API:

  • 生产者API(Producer API)允许应用向一个或多个主题发布数据。
  • 消费者API(Consumer API)允许应用订阅一个或多个主题,并加工处理生产给它们的数据流。
  • 流API(Streams API)允许应用作为流处理器(stream processor),从一个或多个主题中消费输入流并输出流生产到一个或多个主题上,有效地将输入流转化为输出流。
  • 连接器API(Connector API)允许构建或运行将Kafka主题与现有应用或数据系统连接起来的可复用的生产者或消费者。例如,一个关系型数据的连接器可能会捕获表的所有变更。

在Kafka中,客户端和服务器之间的通讯是由简单、高效、无关语言的TCP协议来完成的。该协议是一个版本化的并保持对旧版本向后兼容的协议。我们提供了一个Java版的Kafka客户端,不过这个客户端可以被多种语言使用。

image

主题和日志

让我先来深入研究下有关Kafka数据流的一个核心抽象概念——主题(topic)。

对于发布的记录来说,“主题”是一个分组。Kafka中的主题通常有多个订阅者,这意味着一个主题可以有0个、1个或许多个订阅写入了的数据的消费者。

对于每个主题来说,Kafka集群维护着一个分区式记录。如下图所示:
image

每个分区都是有序的、不可变的记录序列,并不断地添加到结构化的提交日志中。在分区中的记录都被分配了一个叫做偏移量(offset)的连续数,这将在分区里的每条记录都做了唯一标识。

Kafka集群会通过一个可配置的保存周期持续保存所有发布的数据——不论它们是否被消费。例如,如果存储方案设置为2天,那么记录在被发布的2天之内,都可以被消费,之后便被清除以释放空间。Kafka的性能不论数量的大小都是稳定的,所以长时间储存数据不成问题。
image

实际上,在每个消费者保留的基础元素就是日志中消费者所处的偏移量。偏移量受消费者控制:通常地,消费则在读取记录时会线性推移偏移量,但实际上,当自从消费者可以控制偏移量后,消费者可以用任何它喜欢的顺序消费记录。例如,消费者可以重置偏移量到过去的位置上重新对数据进行处理或者向前跳到最近的记录并从当下开始消费。

这样一种产品特点使得Kafka的消费者很廉价——它们的进进出出对集群和其它消费者们没什么太大影响。例如,你可以用我们的命令行工具去“跟踪”任意主题上的内容,而不改变现有消费者所消费的内容。

日志中的分区有很多用途。首先,它们允许日志扩充到适合单个服务器的大小。每个独立的分区必须要适合它所在的服务器,但是一个主题可以有多个分区,所以它能处理任意多的数据。其次,它们是并行化单元——稍后会详细介绍。

分布式

日志中的分区分布在Kafka集群的各个服务器上,每个服务器都通过共享分区操作数据和发送请求。为了容错,每个分区都被复制到多个可配置数量的服务器上。

每个分区都有一个服务器作为“领导者”和0到多个服务器作为“跟随者”。领导者接管所有读写请求,而其它跟随者作为领导者服务器的备份。如果领导者宕掉了,其中一个跟随者会自动成为新的领导者。每个服务器都充当它的一些分区的领导者和其他分区的跟随者,因此整个集群是负载均衡的。

地理复制(Geo-Replication)

Kafka MirrorMaker为您的集群提供地理复制支持。使用MirrorMaker,消息就可以被复制到多个数据中心或云上。你可以在主动/被动场景中使用它进行备份和恢复;或者在被动/主动场景中使用它来将数据放置得离用户更近,或者支持数据局部性这样的需求。

生产者

生产者将数据发布到它们所选的主题中。生产者负责选择将哪条记录指派到主题中的哪个分区。如果仅仅是为了负载均衡的话可以通过简单循环的方式,或者可以通过语义分区的方法来完成(比如通过记录中的某些关键字)。稍后会介绍更多有关分区的用法。

消费者

消费者用消费者群组名标记自己,每个被发布到主题的记录都被传递到订阅的消费者群组中的一个消费实例上。消费者实例可以在不同的进程中或者不同的机器上。

如果所有的消费者实例都在同一个消费者群组中,那么记录将在实例中有效地负载均衡。

如果所有的消费者实例拥有不同的消费组,那么每条记录都会被广播到所有的消费进程中去。
image

要给拥有2个服务器的Kafka集群托管着4个拥有着2个消费者群组的分区(P0-P3)。消费者群组A有2个消费者实例,消费者群组B有4个。

然而大多数情况,我们发现主题拥有少量的消费者群组,每个群组都是逻辑上的订阅者。每个群组为了可伸缩性和容错性会由许多个消费者实例组成。这就是个有关发布-订阅模式的说明——订阅者是一个消费者集群而不是单个进程。

Kafka中实现消费的方法是用日志中的分区数量除以消费者实例数量,这样每个实例在任何时间点都是“平均分享”分区的独立消费者。组内保持各个成员关系的过程由Kafka的动态协议操控。如果有新的实例加入到组内则会从其它成员手中拿走部分分区;如果某个实例挂掉,其它成员则会分配掉这个实例的分区。

Kafka仅提供一个分区内的记录的总顺序,而非一个主题内不同分区间的顺序。对于绝大多数的应用来说,每个分区的排序加上根据关键字区分数据的功能就足够了。不过如果你需要数据的总顺序,那么用只有一个分区的主题可以实现,不过这意味着每个消费组只有一个消费进程。

多租户

你可以用多租户解决方案部署Kafka。可以通过配置哪些主题能生产或消费数据实现多租户。同时还支持对配额的操作。管理员对请求强制指定配额,以用于控制客户端的代理资源。有关更多相关信息,请参见安全文档

承诺

高水准的Kafka提供了如下承诺:
- 生产者向主题分区发送的数据将在被发送的时候顺延排序。也就是说,如果记录M1和记录M2被同一个生产者发送,M1先被发送,那么M1比M2的偏移量小,同时也会比M2先出现在日志中。
- 消费者实例将按照记录储存在日志里的顺序查看记录。
- 对于一个复制N份的主题,最多可以允许 N-1个服务宕掉而不丢失任何已提交的数据。

更多有关以上承诺的细节在文档的设计部分给出。

作为消息系统的Kafka

Kafka的流概念与传统企业信息系统相比如何呢?

传统消息有两种模式:队列发布-订阅。在队列模式中,一个消费者池可能从一个服务器中读取数据,每条记录将流向它们中的一个;在发布-订阅模式中,记录将广播给所有消费者。这两种模式都有各自的优点和缺点。队列的优点是它允许将数据进程分割给多个消费者实例,这能让你监控你的进程。然而缺点是,队列模式不支持多个订阅者——一旦有一个进程读取了数据,这条数据就不在队列中了。发布-订阅模式允许你将数据广播给多个进程,但是当每个订阅者都收到数据时你没办法监控这些进程。

Kafka中消费者群组包括以下两个概念。与队列模式一样,消费者群组允许你将一个进程进行分配(消费者群组的成员),与发布-订阅模式一样,Kafka允许你将消息广播到多个消费者群组。

Kafka模式的优势在于每个主题都同时拥有两个特性——可以监控进程并且支持多订阅者,而不必只选择其中一种模式。

同时,Kafka相比于传统消息系统拥有更可靠的排序。

传统队列在服务器上保持数据的顺序,当多个消费者从队列中消费数据时,服务器按照数据存储的顺序提供。然而,尽管服务器按照顺序提供数据,但是数据被异步发送到消费者手上,所以到了不同的消费者手上时顺序是可能是乱的。这意味着在并行消费的情况下,记录的顺序会丢失。消息系统通常这样的问题采取“独立消费者”的概念,即只允许一个进程去消费一个队列,当然这也就不能并行消费了。

Kafka在这方面做得更为出色。通过主题中并行分区的概念,Kafka能够在消费者进程池上提供排序保证和负载均衡。这是通过对消费者群组中的消费者指派主题中的分区实现的,这样每个分区只被群组中的一个消费者消费。这样做我们就能保证某个分区只有一个消费者并按顺序消费数据。就算有多个分区,也能保证多个消费者实例间的负载均衡。但是要注意的是,消费者群组中的消费者实例数量不能多于分区数量。

作为储存系统的Kafka

对于正在发布的消息,任何允许发布消息并与消费解耦的消息队列都可有效地作为存储系统。而Kafka的不同之处在于它是一个非常出色的存储系统。

写入Kafka的数据都写在了磁盘上,同时为了容错而备份。Kafka允许生产者等待确认,这样只有数据完全被备份才认为写入完毕,即时是写入失败也保证数据不丢失。

在磁盘结构基础上,Kafka对数据规模处理出色——对于服务器上50KB和100TB的持久数据,kafka的表现都是一样的。

由于对存储的苛求并允许用户端控制读取位置,可以将Kafka看作是一种专用的分布式文件系统,专门用于高性能、低延迟提交日志的存储、复制和传播。

有关Kafka提交日志存储和可复制设计的相关细节,点击此页查看。

用于流处理的Kafka

我们的目的不仅仅是满足读写并存储数据流,而是要能够实时处理数据流。

例如,一款零售应用可能要接收有关销售和发货数据,然后通过计算得到再订购和价格调整数据。

用生产者和消费者API可以快速简单计算得出结果。但是对于复杂的运算,kafka提供了一套完整的流API。这使得不需要开发繁琐的数据处理就能构建一款可以计算流的聚合或与流连接到一起的应用程序。

此功能有助于解决此类应用程序所面临的难题:处理无序数据、在代码更改时重新处理数据、执行有状态的计算等等。

流API构建在Kafka提供的核心基础之上:它使用生产者和消费者API进行输入,使用Kafka进行有状态的存储,并使用相同的服务器集群用于流处理器实例间的容错。

碎片整合

消息传递、存储和流处理的这种组合可能不太常见,但是对作为流媒体平台的Kafka至关重要。

像HDFS这样的分布式文件系统允许批处理存储静态文件。这样的系统可以有效地存储和计算历史数据。

一个传统企业消息系统允许处理订阅后即将收到的数据。用这种方式构建的应用在之后产生的数据收到时进行处理。

Kafka将这两种能力都结合起来,这对于Kafka作为流应用和流数据管道平台来说非常重要。

通过对存储和低延迟订阅的整合,流应用可以用同样的方式处理过去和未来的数据。这意味着一个应用可以处理历史存储的数据并在未来数据到来时继续处理,而不是在达到最后一条记录的时候停止工作。这是流处理的广义概念,它包含批处理和消息驱动的应用。

同样地,对于流数据管道来说,整合对实时事件的订阅可以使极低延迟的管道使用Kafka;而这种可靠存储数据的能力使得对重要数据的交付,或者是线下系统定期加载集成数据,再或者是长时间停机维护成为可能。这种流处理工具可以在数据到来时对其进行转换。

对于有关保障、API和Kafka所提供的能力的更多信息,请参见剩余的文档

猜你喜欢

转载自blog.csdn.net/Colton_Null/article/details/82696357