Kafka深入学习(三)——消费者Consumer

190 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情

前言

本文将介绍Kafka消费者相关的以下内容:

  1. 消费者与消费组的关系与区别,以及消息队列的两种模式点对点与发布/订阅模式
  2. Kafka消费者客户端的实现。

消费者与消费组

要了解Kafka消费者,我们先了解下消费组与消费者的概念,在kafka中,消费者consumer负责订阅主题,并从订阅的主题中拉取消息,与其他消息组件的不同在于,kafka存在一个消费组的逻辑概念,kafka中每个消费者归属于某个消费组,发布到主题中的消息,只会被投递给订阅该主题的每个消费组的中的一个消费者,消息、主题以及分区与消费组的之间的消费关系可以表述为以下两句话:

  1. 每个主题的所有分区的消息会被订阅该主题的每个消费组进行消费,消费组之间互不影响。
  2. 每个主题中每个分区的消息只会被分配给消费组中某个具体的消费者所消费。 可以把每个消费者理解为物理应用的某个线程或进程,而消费组是个逻辑概念,消费组中的消费者既可以部署在同一台机器也可以部署在不同的机器上,根据上述总结可以支持到,消费能力与消费者以及分区数也有关,当消费者数量大于分区数时,由于分区中的消息只会分配个统一个消费者消费,某些消费者会分配不到任何分区,无法消费人任何消息。 那么这么设计的好处在哪呢?好处在于横向伸缩性很好,可以看到,当增加或删除某个消费者实例时,只需将某些分区的消息分配给新增的消费者或将删除的消费者实例的消息分配到原先的消费者进行消费即可,可以简单的实现对消费能力的控制。

消息投递的模式

  1. 点对点(P2P):消息生产者发送消息到队列,消息消费者从队列中接受消息。
  2. 发布/订阅(Pub/Sub):消息生产者向一个内容节点也就是主题发送消息,主题是消息传递的中介,消息订阅者从主题中订阅消息,主题使得订阅者和消息发布者互相独立没不需要接触即可保证消息的传递,通常用于1对多广播场景。

而Kafka同时支持上述两种消息投递模式,通过消费者与消费组的关系即可实现,当所有的消费者属于同一个消费组时,主题中的消息会分散分配给所有的消费组,发送的每条消息都被1个消费者处理,相当于点对点模式。 而当每个消费组只有1个消费者时,消息会广播到所有的消费组也就是所有的消费者,相当于发布/订阅的模式。

消费客户端开发

与生产逻辑向对应,一个正常的消费逻辑须要具备以下的逻辑:

  1. 配置消费者客户端参数并创建对应的消费者实例。
  2. 订阅主题。
  3. 从主题拉取消息并消费。
  4. 提交消费位移。
  5. 关闭消费者实例。

Kafka订阅消息支持以下几种方式:

  1. 订阅1个或多个主题集合:subscribe(Collection)
  2. 通过正则表达式订阅主题:subscribe(Pattern)
  3. 指定定于主题的某些分区:assign(partitions); 通过正则表达式订阅时,如果消费过程中新增了某个主题,同时也满足消费者订阅的正则表达式,该消费者也会消费订阅该主题的消息。还有一点值得注意,通过集合或正则表达式订阅的主题集subscribe方式订阅主题的方式具有消费者自动再均衡的功能,在多个消费者的情况下,可以通过分区分配策略来自动分配消费者和分区的关系,当消费组内的消费者增加或减少是,分区分配关系会自动调整,实现消费负载均衡和故障自动转移。

消息消费

消息消费一般有两种模式:推模式与拉模式。推模式值服务端主动推动消息个消费者,拉模式则指消费者主动发起请求来拉取消息。kafka正式拉模式,消费者会重复的调用poll方法,将订阅的主题(分区)上的一组消息拉取进行消费,该方法也可以设置超时时间,用来控制pill方法的阻塞时间,用来控制应用程序对响应速度的要求。该方法可以简单的理解为拉取了一组消费,但器内部实现实则十分复杂,设计消费位移、消费者协调器、消费者的选举、分区分配分发、再均衡逻辑、心跳等内容。