Kafka是一个分布式的流平台,有三种关键的功能:
Kafka被用于两大类应用程序:
Kafka的几个概念:
Kafka四个核心API:
Connector API:允许构建和运行可重复使用的生产者或消费者,来将Kafka主题与现有应用程序或数据系统相连接。例如,关系数据库的连接器可能会捕获表的每个更改。
在Kafka中,客户端和服务器之间的通信是用简单,高性能,基于TCP协议完成的。此协议版本化并保持与旧版本的向后兼容性。Kafka提供了Java客户端,但是客户端可以使用多种语言。
主题是发布记录的类别或名称。在Kafka中主题总是多用户的,也就是说,主题可以有零个,一个或多个消费者订阅的数据。
对每一个主题,Kafka集群维护一个分区日志,如下所示:
每个分区是一个有序的、不可变的记录序列,不断有结构化的提交日志附加到其中。每个分区中的记录都被分配一个顺序的id号,称为偏移量,这个唯一数字用来区分分区中每个记录。
Kafka集群保留所有已发布的记录,无论它们是否已被使用 ,可使用可配置的保留期限。例如,如果保留策略设置为两天,则在发布记录后的两天内,它可以消费,之后将被丢弃以释放空间。卡夫卡的性能在数据大小方面是有效的,所以长时间存储数据不是问题。
事实上,在每个消费者基础上保留的唯一元数据是消费者在日志中的偏移或位置。这个偏移由消费者控制:通常消费者会在读取记录时线性地提高其偏移,但实际上,由于位置由消费者控制,它可以以任何顺序消耗记录。例如,消费者可以重置为较旧的偏移量以重新处理来自过去的数据,或者跳过最近的记录,并从“现在”开始消费。
这种特征的组合意味着Kafka消费者非常便宜,他们的来回去对群集或其他消费者没有太大的影响。例如,你可以使用命令行工具来拖任何主题的内容,不会改变任何现有消费者所消耗的内容。
日志分区有几个目的。首先,它们允许日志扩展到适合单个服务器的大小。每个单独的分区必须适合托管它的服务器,但主题可能有很多分区,因此它可以处理任意数量的数据。第二,它们作为并行性的单位,更多的是在这一点上。
日志分区分布在Kafka群集中的服务器上,每个服务器处理数据并请求分区的一部分。每个分区都跨可配置数量的服务器进行复制,以实现容错。
每个分区都有一个服务器作为“领导”,零个或多个服务器充当“追随者”。领导者处理对分区的所有读取和写入请求,而追随者被动地复制领导者。如果领导挂掉,其中一个追随者将自动成为新的领导者。每个服务器充当其分区的一个领导者,另一个服务器作为其他分区的追随者,因此在群集中负载平衡良好。
生产者将数据发布到他们选择的主题。生产者负责选择要分配给主题中哪个分区的记录。这可以通过循环方式简单地平衡负载,或者可以根据某些语义分区功能(例如基于记录中的一些关键字)来完成。更多关于使用分区在一秒钟!
消费者使用消费者组名称标注自己,并将发布到主题的每条记录传递到每个订阅消费者组中的一个消费者实例。消费者实例可以在单独的进程中或单独的机器上。
如果所有的消费者实例具有相同的消费者组,那么这些记录将在消费者实例上实际负载平衡。
如果所有的消费者实例都有不同的消费者群体,那么每个记录将被广播给所有的消费者进程。
两个服务器Kafka集群托管四个分区(P0-P3)与两个消费者组。消费者组A有两个消费者实例,B组有四个。
然而,更常见的是,我们发现主题具有少量的消费者群体,每个“逻辑订户”一个。每个组由许多消费者实例组成,具有可扩展性和容错能力。这只不过是发布订阅语义,用户是一组消费者而不是单个进程。
在Kafka中实现消费的方式是通过将日志分区划分到消费者实例上,以便每个实例都是任何时间点的“公平共享”分区的唯一消费者。维护成员资格的过程由Kafka协议动态处理。如果新的实例加入组,他们将把一些分区分配给从组中的其他成员;如果一个实例消失,其分区会被分发到剩余的实例。
在Kafka提供以下保证:
Kafka的流概念与传统的企业邮件系统相比如何?
消息传统传统上有两种模式:排队和发布订阅。在队列中,消费者池可以从服务器读取,每条记录都转到其中一个;在发布订阅中,记录将广播给所有消费者。这两个模型中的每一个都有实力和弱点。排队的优点是它允许你在多个消费者实例上分配数据处理,从而可以扩展你的处理。不幸的是,队列不是多用户的 , 一旦一个进程读取数据就会消失。发布订阅允许您将数据广播到多个进程,但无法缩放处理,因为每个消息都发送给每个用户。
Kafka消费者组的概念有两个概念。与队列一样,消费者组允许你通过一系列进程(消费者组的成员)来划分处理。与发布订阅一样,Kafka允许你将消息广播到多个消费者组。
Kafka模型的优点是,每个主题都具有这两个属性 -,它可以扩展处理,也是多用户 -,不需要选择一个或另一个。
Kafka也比传统的邮件系统更强大的订阅保证。
传统队列在服务器上保存顺序的记录,如果多个消费者从队列中消费,则服务器按照存储顺序输出记录。然而,虽然服务器按顺序输出记录,但是记录被异步传递给消费者,所以它们可能会在不同的消费者处按顺序到达。这意味着在并行消耗的情况下,记录的排序丢失。消息传递系统通常通过使“唯一消费者”的概念只能让一个进程从队列中消费,但这当然意味着处理中没有并行性。
Kafka做得更好,通过在主题中有一个并行概念(分区),Kafka能够在消费者流程池中提供排序保证和负载平衡。这通过将主题中的分区分配给消费者组中的消费者来实现,使得每个分区被组中的一个消费者消耗。通过这样做,我们确保消费者是该分区的唯一读者,并按顺序消耗数据。由于有许多分区,这仍然平衡了许多消费者实例的负载。但请注意,消费者组中的消费者实例不能超过分区。
任何允许发布消息的消息队列与消费实际上是充当存储系统的动态信息。Kafka的不同之处在于它是一个很好的存储系统。
写入Kafka的数据写入磁盘并进行复制以进行容错。 Kafka允许生产者等待确认,以便在完全复制之前写入不被认为是完整的,并且即使写入服务器失败,也保证持久写入。
Kafka的磁盘结构使用缩放功能,Kafka将执行相同的操作,无论您在服务器上是否有50 KB或50 TB的持久数据。
由于存储并允许客户端控制其读取位置,你可以将Kafka视为专用于高性能,低延迟的提交日志存储,复制和传播的专用分布式文件系统。
不只是读取,写入和存储数据流,目的是实现流的实时处理。
在Kafka,流处理器从输入主题持续的接收数据流,对输入执行一些处理,并生成持续的数据流以输出主题。
例如,零售应用程序可能会输入销售和出货的输入流,并输出根据此数据计算的重新排序和价格调整。
可以直接使用生产者和消费者API进行简单处理。然而对于更复杂的转换,Kafka提供了一个完全集成的Streams API。这允许构建应用程序进行面对较重大处理,以计算流中的聚合或将流连接在一起。
该设施有助于解决这种类型的应用程序面临的困难问题:处理无序数据,重新处理输入作为代码更改,执行有状态计算等。
Streams API基于Kafka提供的核心原语构建:它使用生产者和消费者API进行输入,使用Kafka进行有状态存储,并在流处理器实例之间使用相同的组机制进行容错。
消息,存储和流处理的这种组合似乎是不寻常的,但是Kafka作为流平台的角色至关重要。
像HDFS这样的分布式文件系统允许存储用于批处理的静态文件。这样的系统有效地允许存储和处理来自过去的历史数据。
传统的企业邮件系统允许处理将在你订阅之后到达的未来的消息。应用程序以这种方式处理未来的数据,因为它的到来。
Kafka结合了这两种功能,组合对于Kafka作为流应用程序平台和流式传输数据管道的使用而言至关重要。
通过组合存储和低延迟订阅,流应用程序可以以相同的方式处理过去和未来的数据。这是一个单一的应用程序可以处理历史记录数据,而不是在到达最后一个记录时结束,它可以随着未来数据的到来而继续处理。这是流程处理的一般概念,其中包含批处理以及消息驱动的应用程序。
同样,对于流数据管道,订阅到实时事件的组合使得可以使用Kafka进行非常低延迟的管道;但是可靠性地存储数据的能力使得可以将其用于必须保证数据传送的关键数据,或者与仅负载数据的离线系统进行集成,或者可能会长时间停机进行维护。流处理设备可以在数据到达时转换数据。