官方文档:http://kafka.apache.org/intro.html
kafka是一个分布式流处理平台,通常用于两大类应用程序:
- 构造实时流数据管道,它可以在系统或应用之间可靠地获取数据。 (消息队列)
- 构建转换或响应数据流的实时流应用程序(流处理)
核心概念
-
主题(topic)和日志
topic是发布记录的类别或提要名称。Kafka中的Topics总是多订阅者模式,一个topic可以拥有一个或者多个消费者来订阅它的数据。对于每一个topic, Kafka集群都会维持一个分区日志,如下所示:
每个分区都是一个有序的、不可变的记录序列,这些记录被不断添加到结构化的提交日志(commit log文件)中。分区中的记录被分配一个顺序的id号,称为惟一标识分区中的每个记录的偏移量(offset)。
Kafka集群使用可配置的保留期可以持久地保存所有已发布的记录(不管它们是否已被消耗)。例如,如果保留策略被设置为两天,那么在发布记录后的两天内,记录是可用的,在这两天之后,记录将被丢弃以释放空间。Kafka的性能在数据大小方面实际上是恒定的,所以长时间存储数据不是问题。
事实上,在每一个消费者中唯一保存的元数据是offset(偏移量)即消费在log中的位置.偏移量由消费者所控制:通常在读取记录后,消费者会以线性的方式增加偏移量,但是实际上,由于这个位置由消费者控制,所以消费者可以采用任何顺序来消费记录。例如,一个消费者可以重置到一个旧的偏移量,从而重新处理过去的数据;也可以跳过最近的记录,从"现在"开始消费。
分区(partition)
partition(分区)是topic的组成单元,该topic的partition个数及副本数在创建topic时指定。日志中的 partition(分区)有以下几个用途。首先,它们允许日志扩展到超出单个服务器的大小。每个单独的分区必须适合承载它的服务器,但是topic(主题)可能有许多分区,因此它可以处理任意数量的数据。其次,它们作为并行度的单位。
partition分布在Kafka集群的服务器上。每个服务器在处理数据和请求时,共享这些分区。每一个分区都会在已配置的服务器上进行备份,确保容错性。leader和follwer
每个分区都有一台 server 作为 “leader”,零台或者多台server作为 follwers 。leader选举通过zookeeper来协调管理。leader server 处理一切对 partition (分区)的读写请求,而follwers只需被动的同步leader上的数据。当leader宕机了,followers 中的一台服务器会自动成为新的 leader。每台 server 都会成为某些分区的 leader 和某些分区的 follower,因此集群的负载是平衡的。生产者(producer)
生产者可以将数据发布到所选择的topic(主题)中。生产者负责将记录分配到topic的哪一个 partition(分区)中。可以使用循环的方式来简单地实现负载均衡,也可以根据某些语义分区函数(例如:记录中的key)来完成。-
消费者(consumer)
消费者使用一个 消费组 名称来进行标识,发布到topic中的每条记录被分配给订阅消费组中的一个消费者实例。消费者实例可以分布在多个进程中或者多个机器上。
若所有的消费者实例在同一消费组中,消息记录会负载平衡到每一个消费者实例。若所有的消费者实例在不同的消费组中,每条消息记录会广播到所有的消费者进程。
同一个topic中的相同数据只能被同一个消费组内的消费者消费一次。 -
broker
broker即组成kafka集群的节点,它们之间没有主从关系,依赖zookeeper来协调。broker负责消息的读写及存储,一个broker管理着多个partition。
应用场景
1、作为消息系统
传统的消息传递有两种模式:队列和发布-订阅。在队列模式中,消费者们可以从服务器读取数据,每条记录都被发送到其中一个消费者;在 发布-订阅 模式中,记录被广播给所有消费者。这两种模式各有优缺点。队列模式的优点在于,它允许您将数据处理划分到多个消费者实例上,从而可以扩展处理。不好的是,队列不是多订阅者模式的,一旦一个进程读取了数据,数据就会被丢弃。 而发布-订阅系统允许你广播数据到多个进程,但是无法进行扩展处理,因为每条消息都会发送给所有的订阅者。
消费组在Kafka有两层概念。在队列中,消费组允许你将处理过程分发给一系列进程(消费组中的成员)。 在发布订阅中,Kafka允许你将消息广播给多个消费组。Kafka的优势在于每个topic都有以下特性:可以扩展处理并且允许多订阅者模式;不需要只选择其中一个。Kafka能够为一个消费者池提供顺序保证和负载平衡,是通过将topic中的partition分配给消费者组中的消费者来实现的, 以便每个分区由消费组中的一个消费者消耗。
然而,kafka也只能保证partition内有序,多个partition间不保证有序性。
解决方案:(自定义分区)
为达到根据某个维度保证有序消费,写入kafka时可以根据该维度id或编号去指定写入对应的partition。
2、作为存储系统
Kafka使用磁盘结构,具有很好的扩展性—50kb和50TB的数据在server上表现一致。可以存储大量数据,并且可通过客户端控制它读取数据的位置,您可认为Kafka是一种高性能、低延迟、具备日志存储、备份和传播功能的分布式文件系统。
3、用于流处理
Kafka提供了Streams API。 Stream API 允许应用做一些复杂的处理,比如将流数据聚合或者join。这一功能有助于解决以下这种应用程序所面临的问题:处理无序数据,当消费端代码变更后重新处理输入,执行有状态计算等。Streams API建立在Kafka的核心之上:它使用Producer和Consumer API作为输入,使用Kafka进行有状态的存储, 并在流处理器实例之间使用相同的消费组机制来实现容错。
4、用于批处理
作为流数据管道,能够订阅实时事件使得Kafk具有非常低的延迟; 同时Kafka还具有可靠存储数据的特性,可用来存储重要的支付数据, 或者与离线系统进行交互,系统可间歇性地加载数据,也可在停机维护后再次加载数据。流处理功能使得数据可以在到达时转换数据。
核心 API
- Producer API 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。
- Consumer API 允许一个应用程序订阅一个或多个 topic ,并且对发布给他们的流式数据进行处理。
- Streams API 允许一个应用程序作为一个流处理器,消费一个或者多个topic产生的输入流,然后生产一个输出流到一个或多个topic中去,在输入输出流中进行有效的转换。
- Connector API 允许构建并运行可重用的生产者或者消费者,将Kafka topics连接到已存在的应用程序或者数据系统。比如,连接到一个关系型数据库,捕捉表(table)的所有变更内容。