Kafka的三种客户端线程模型和一个小惊喜

Kafka 作为一个流式数据平台,对开发者提供了三种客户端:生产者 / 消费者、连接器、流处理。本文着重分析这三种客户端的线程模型。看到最后的通常都有惊喜。

消费者的线程模型

0.8 版本以前的消费者客户端会创建一个基于 ZK 的消费者连接器,一个消费者客户端是一个 Java 进程,消费者可以订阅多个主题,每个主题也可以多个线程。为了让消息在多个节点被分布式地消费,提高消息处理的吞吐量,Kafka 允许多个消费者订阅同一个主题,这些消费者需要满足“一个分区只能被一个消费者中的一个线程处理”的限制条件。通常,我们会将同一份相同业务处理逻辑的应用程序部署在不同机器上,并且指定一个消费组编号。当不同机器上的消费者进程启动后,所有这些消费者进程就组成了一个逻辑意义上的消费组。

消费组中的消费者数量是动态变化的,当有新消费者加入消费组,或者旧消费者离开消费组,都会触发基于 ZK 的消费组“再平衡”操作。当“再平衡”操作发生时,每个消费者都会在客户端执行分区分配算法,然后从全局的分配结果中获取属于自己的分区。它的缺点是消费者会和 ZK 产生频繁的交互,造成 ZK 集群的压力过大,并且容易产生羊群效应和脑裂等问题。

在 0.8 版本以后,Kafka 重新设计了客户端,并且引入了“协调者”和“消费组管理协议”。新的消费者将“消费组管理协议”和“分区分配策略”进行了分离。协调者负责消费组的管理,而分区分配则会在消费组的一个主消费者中完成。采用这种方式,每个消费者都需要发送下面两种请求给协调者。

  • 加入组请求:协调者收集消费组的所有消费者,并选举一个主消费者执行分区分配工作。

  • 同步组请求:主消费者完成分区分配,由协调者将分区的分配结果传播给每个消费者。

新版本的消费者客户端引入了一个客户端协调者的抽象类,它的实现除了消费者的协调者,还有一个连接器的实现。

连接器的线程模型

Kafka 连接器的出现标准化了 Kafka 与各种外部存储系统的数据同步。用户开发和使用连接器就变得非常简单,只需要在配置文件中定义连接器,就可以将外部系统的数据导入 Kafka 或将 Kafka 数据导出到外部系统。如图 1 所示,中间部分都是 Kafka 连接器的内部组件,包括源连接器(Source Connector)和目标连接器(Sink Connector)。

Kafka的三种客户端线程模型和一个小惊喜

图 1 Kafka 连接器的源连接器与目标连接器

Kafka 连接器的单机模式会在一个进程内启动一个 Worker 以及所有的连接器和任务。分布式模式的每个进程都有一个 Worker,而连接器和任务则分别运行在各个节点上。图 2 列举了连接器和任务在不同 Worker 上的四种分布方式:

  1. 一个 Worker,一个源任务、一个目标任务

  2. 一个 Worker,两个源任务、两个目标任务

  3. 两个 Worker,两个源任务、两个目标任务

  4. 三个 Worker,两个源任务、两个目标任务

Kafka的三种客户端线程模型和一个小惊喜

图 2 分布式模式的 Kafka 连接器集群

分布式模式下,不同 Worker 进程之间的协调工作类似于消费者的协调。消费者通过协调者获取分配的分区,Worker 也会通过协调者获取分配的连接器与任务。如图 3 所示,消费者客户端和 Worker 客户端为了加入到组管理中,分别通过客户端的协调者对象来和服务端的消费组协调(GroupCoordinator)通信。

Kafka的三种客户端线程模型和一个小惊喜

图 3 消费者和 Worker 的工作都是通过协调者分配的

流处理的线程模型

Kafka 流处理的工作流程简单来看分成三个步骤:消费者读取输入分区的数据、流式地处理每条数据、生产者将处理结果写入输出分区,这里面步骤 1 也充分利用了“消费组管理协议”。Kafka 流处理的输入数据源基于具有分布式分区模型的 Kafka 主题,它的线程模型主要由下面三个类组成:

  • 流实例(KafkaStreams):通常一个节点(一台机器)只运行一个流实例。

  • 流线程(StreamThread):一个流实例可以配置多个流线程。

  • 流任务(StreamTask):一个流线程可以运行多个流任务,根据输入主题的分区数确定任务数。

如图 4 所示,输入主题有六个分区,Kafka 流处理总共就会产生六个流任务。流实例可以动态扩展,流线程的个数也可以动态配置。图中一共有三个流线程,则每个流线程会有两个流任务,每个流任务都对应输入主题的一个分区。

Kafka的三种客户端线程模型和一个小惊喜

图 4 Kafka 流处理的线程模型

Kafka 的流处理框架使用并行的线程模型处理输入主题的数据集,这种设计思路和 Kafka 的消费者线程模型非常类似。消费者分配到订阅主题的不同分区,流处理框架的流任务也分配到输入主题的不同分区。如图 5 所示,输入主题 1 的分区 P1 和输入主题 2 的分区 P1 分配给流线程 1 的流任务,输入主题 1 的分区 P2 和输入主题 2 的分区 P2 分配给流线程 2 的流任务。流处理相比消费者,还会将拓扑的计算结果写到输出主题。

Kafka的三种客户端线程模型和一个小惊喜

图 5 消费者模型与流处理的线程模型

消费者和流处理的故障容错机制也是类似的。如图 6 所示,假设消费者 2 进程挂掉,它所持有的分区会被分配给同一个消费组中的消费者 1,这样消费者 1 会分配到订阅主题的所有分区。对于流处理而言,如果流线程 2 挂掉了,流线程 2 中的流任务会分配给流线程 1。即流线程 1 会运行两个流任务,每个流任务分配的分区仍然保持不变。

Kafka的三种客户端线程模型和一个小惊喜

图 6 消费者与流处理的故障容错机制

小 结

Kafka 客户端抽象出来的的“组管理协议”充分运用在消费者、连接器、流处理三个使用场景中。客户端中的消费者、连接器中的工作者、流处理中的流进程都可以看做“组”的一个成员。当增加或减少组成员时,在这个协议的约束下,每个组成员都可以获取到最新的任务,从而做到无缝的任务迁移。一旦理解了“组管理协议”,对于理解 Kafka 的架构设计是很有帮助的。

更多关于 Kafka 的技术内幕,欢迎参考郑奇煌的《Kafka 技术内幕》一书。

Kafka的三种客户端线程模型和一个小惊喜
作者:郑奇煌 定价:119.00 元 图文详解 Kafka 的内部原理、设计与实现 全面分析以 Kafka 为中心的分布式流平台 Kafka 新特性详解,包括连接器、流处理 阿里巴巴高级技术专家、Aliware MQ 总架构师、Apache RocketMQ 联合创始人、Linux OpenMessaging 规范发起人冯嘉(Von Gosling),华为云主任工程师时金魁,过往记忆技术博客博主、Qunar 数据架构师吴阳平倾力推荐

Kafka 自 LinkedIn 开源以来就以高性能、高吞吐量、分布式的特性著称,本书以 0.10 版本的源码为基础,深入分析了 Kafka 的设计与实现,包括生产者和消费者的消息处理流程,新旧消费者不同的设计方式,存储层的实现,协调者和控制器如何确保 Kafka 集群的分布式和容错特性,两种同步集群工具 MirrorMaker 和 uReplicator ,流处理的两种 API 以及 Kafka 的一些高级特性等。

抽个奖吧

本次抽奖采用小程序开奖,开奖时间为 2018 年 1 月 4 日上午 12 点整。开奖之后,中奖的同学只要根据指引在小程序里填上收件信息就可以了。感谢无码科技开发的抽奖助手小程序!

本次一共送出 10 本《Kafka 技术内幕》, 没能中奖的同学可以戳 阅读原文 购买!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1/kafka一个分布式的消息缓存系统 2/kafka集群中的服务器都叫做broker 3/kafka有两类客户端,一类叫producer(消息生产者),一类叫做consumer(消息消费者),客户端和broker服务器之间采用tcp协议连接 4/kafka中不同业务系统的消息可以通过topic进行区分,而且每一个消息topic都会被分区,以分担消息读写的负载 5/每一个分区都可以有多个副本,以防止数据的丢失 6/某一个分区中的数据如果需要更新,都必须通过该分区所有副本中的leader来更新 7/消费者可以分组,比如有两个消费者组A和B,共同消费一个topic:order_info,A和B所消费的消息不会重复 比如 order_info 中有100个消息,每个消息有一个id,编号从0-99,那么,如果A组消费0-49号,B组就消费50-99号 8/消费者在具体消费某个topic中的消息时,可以指定起始偏移量 每个partition只能同一个group中的同一个consumer消费,但多个Consumer Group可同时消费同一个partition。 n个topic可以被n个Consumer Group消费,每个Consumer Group有多个Consumer消费同一个topic Topic在逻辑上可以被认为是一个queue,每条消费都必须指定它的Topic,可以简单理解为必须指明把这条消息放进哪个queue里。为了使得Kafka的吞吐率可以线性提高,物理上把Topic分成一个或多个Partition,每个Partition在物理上对应一个文件夹,该文件夹下存储这个Partition的所有消息和索引文件。若创建topic1和topic2两个topic,且分别有13个和19个分区 Kafka的设计理念之一就是同时提供离线处理和实时处理。根据这一特性,可以使用Storm这种实时流处理系统对消息进行实时在线处理,同时使用Hadoop这种批处理系统进行离线处理,还可以同时将数据实时备份到另一个数据中心,只需要保证这三个操作所使用的Consumer属于不同的Consumer Group即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值