前言

根据源码分析kafka java客户端的生产者和消费者的流程。

基于zookeeper的旧消费者

kafka消费者从消费数据到关闭经历的流程。

由于3个核心线程

  1. 基于zookeeper的连接器监听该消费者是否触发重平衡,并获取该消费者客户端消费的topic下group对应的partition以及offset。参考` ZookeeperConsumerConnector`
  2. 寻找partition leader线程循环寻找partition的leader,原理是基于zk的watch,并判断哪些partition的leader发生改变,如果有发生改变,那么创建新的线程来消费这些partition,并把检查之前的线程,如果有消费不是最新的leader那么就shutdown,参考`ConsumerFetcherManager`
  3. 数据拉取线程通过消费partition的leader,循环拉取数据

解放zookeeper的新消费者

总体思路

  1. 解放了消费者对zookeeper的依赖,现在只需要和broker交互就可以获取所有需要的元数据。因此,和zk相关的线程都被解放了,取而代之的是基于事件触发思想的流程。
  2. 减少了不必要的线程,将所有操作lazy化处理,也就是说整个消费流程是基于事件的。比如之前有专门维护心跳的线程,现在改为将心跳任务加入队列,只有在某些事件达到时才会执行。由于在拉取数据时,频繁去检验分区相关元数据会导致拉取性能下降,因此消费者每次在拉取完一批record后,会自动异步去拉取下一批的数据,并更新最新的元数据到内存,而此时使用者正在处理上一批的record,这样处理就保证了基于事件思路下的元数据更新和拉取数据的性能。

拉取数据的两种方式

  1. 手动分配topic和partition,也就是assign,分配之后,消费者客户端不会感知到其他事件的触发。
  2. 订阅topic,自动分配到topic的partition,以及该groupid之前消费到的offset,当然也可以自动感知到kafka的rebalance,并获取到相关事件。

拉取流程

  1. 确保kafka协调者认可了此次消费,并初始化和协调者的连接。认可很多层次的含义,包括kafka集群是否正常,安全认证是否通过之类。
  2. 确保分区被分配,除了手动assgin的topic,partition和offset,自动subscribe需要从kafka协调者获取相关元数据,也是发生重平衡事件的来源。
  3. 确保已经获取拉取的offset,否则为从协调者那重新获取对应groupid的offset,如果获取失败(比如这是一个新的groupid),那么会重置offset,根据配置用最旧或者最新来代替。参考`ConsumerCoordinator`
  4. 拉取数据,通过拉取每个partition的leader,基于NIO思路拉取数据缓存在内存中;参考`Fetcher`。
  5. 提交offset,如果开启自动提交offset的功能,那么消费者会在两个情况同步提交offset,(1)重平衡或者和broker心跳超时,参考流程2;(2)消费者关闭。如果是手动提交的话可以采用异步或者同步两种提交方式

重平衡触发原因

  1. 消费的topic的partition数量发生了变化
  2. topic被创建或者删除
  3. 有其他消费者客户端使用相同的group来消费或者停止消费同一个topic

数据拉取线程分为两类

kafka集群在同步副本数据的过程,也是基于客户端拉取数据,和消费者稍有不同

  1. 基于消费者的数据拉取线程

这也就是我们常用的消费者,数据拉取后缓存在内存中给客户端获取

  1. 基于副本备份的数据拉取线程

kafka集群的副本通过此类线程拉取数据,并写到本地日志中

kafka生产者

相对消费者,生产者的流程简单很多。

生产者采用双线程的方式,主线程也就是用户线程,将数据交给kafka的生产者;另外一个是生产者自己的子线程,将数据源源不断的发送到kafka。

生产流程

  1. 找到数据发送的partition;
  2. 将数据按照topic partition分类,每类采用一个双向队列存储数据;检查队列最后一个批是否正在处理,尝试加入到该批,否则创建一个新的批并加入到队列末尾。如果最后一个批已经满了(容量满了或者数据超过1)或者有新的批被创建了,那么触发生产者将数据发送到kafka
  3. 另外生产者的子线程也会不断的自我循环,判断内存中缓存的数据是否可以被发送到kafka,有5种情况,只要满足其一就把数据发送到broker,full || expired || exhausted || closed || flushInProgress();(1) full参考流程2;(2) expired 距离上一次数据发送的时间超过了一个阈值;(3) exhausted 生产者内部维护了内存队列,记录了当前使用的内存大小,exhausted表示申请的总数>1的情况;(4) closed 生产者被关闭了;(5) 使用者显示的调用了flush()

kafka生产者和消费者流程的更多相关文章

  1. [Spark][kafka]kafka 生产者,消费者 互动例子

    [Spark][kafka]kafka 生产者,消费者 互动例子 # pwd/usr/local/kafka_2.11-0.10.0.1/bin 创建topic:# ./kafka-topics.sh ...

  2. kafka生产者和消费者api的简单使用

    kafka生产者和消费者api的简单使用 一.背景 二.需要实现的功能 1.生产者实现功能 1.KafkaProducer线程安全的,可以在多线程中使用. 2.消息发送的key和value的序列化 3 ...

  3. Kafka 生产者和消费者入门代码基础

    这篇博文讲解Kafka 的生产者和消费者实例. 基础版本一 生产者 ProducerFastStart.java package com.xingyun.tutorial_1; import org. ...

  4. kafka-python开发kafka生产者和消费者

    1.安装kafka-python 执行命令 pip install kafka-python kafka-python        1.4.6 2.编写python kafka 生产者消费者代码 # ...

  5. Kafka 生产者、消费者与分区的关系

    背景 最近和海康整数据对接, 需要将海康产生的结构化数据拿过来做二次识别. 基本的流程: 海康大数据 --> kafka server --> 平台 Kafka 的 topic 正常过车 ...

  6. kafka学习(三)kafka生产者,消费者详解

    文章更新时间:2020/06/14 一.生产者 当我们发送消息之前,先问几个问题:每条消息都是很关键且不能容忍丢失么?偶尔重复消息可以么?我们关注的是消息延迟还是写入消息的吞吐量? 举个例子,有一个信 ...

  7. kafka生产者和消费者

    在使用kafka时,有时候为验证应用程序,需要手动读取消息或者手动生成消息.这个时候可以借助kafka-console-consumer.sh和kafka-console-producer.sh 这两 ...

  8. springboot配置kafka生产者和消费者详解

    在原有pom.xml依赖下新添加一下kafka依赖ar包 <!--kafka--> <dependency> <groupId>org.springframewor ...

  9. kafka生产者、消费者java示例

    1. 生产者 import java.util.Properties; import kafka.javaapi.producer.Producer; import kafka.producer.Ke ...

随机推荐

  1. nginx负载均衡模块

    1.upstream 模块 upstream backend { server backend1.example.com weight=5 max_fails=10 fail_timeout=10s; ...

  2. tpcc-mysql安装、使用、结果解读

    请点击:http://www.aikaiyuan.com/8687.html 错误处理: ln -s /usr/local/mysql/lib/libmysqlclient.so. /usr/lib6 ...

  3. oracle 日期常用函数(转载)

      日期运算函數     ADD_MONTHS(d,n)    --时间点d再加上n个月      ex.     select sysdate, add_months(sysdate,2) aa f ...

  4. Jenkins可持续集成

    Jenkins 平台安装部署 基于Java开发的持续集成工具,需要安装Java JDK软件 (1).Jenkins稳定版下载地址:wget  http://updates.jenkins-ci.org ...

  5. poj1039 Pipe【计算几何】

    含[求直线交点].[判断直线与线段相交]模板   Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions:11940   Ac ...

  6. tomcat的server.xml中的Context节配置

    Tomcat的默认网站目录是:C:\Tomcat 9.0\webapps\ROOT,里面的index.jsp,就是tomcat官方提供的默认页,如果按照默认配置,访问链接应当是http://local ...

  7. [3D]1.绘制三角形

    作为一个.Net程序员学习3D开发好尴尬啊,因为不论是OpenGL还是Direct3D都是用C/C++开发的比较多.虽然有计划使用C++进行开发,但是平时还是C#使用的多.很少用C++做东西,如果仅仅 ...

  8. Spring Boot+CXF搭建WebService

    Spring Boot WebService开发 需要依赖Maven的Pom清单 <?xml version="1.0" encoding="UTF-8" ...

  9. POJ1236:Network of Schools(tarjan+缩点)?

    题目: http://poj.org/problem?id=1236 [题意] N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1 ...

  10. 站点默认访问https

    需求简介 现在网站都是https访问了,再用http会显得很low,所以我要把网站设置为默认的https访问. 1nginx的rewrite方法 这应该是大家最容易想到的方法,将所有的http请求通过 ...