kafka生产者和消费者流程
前言
根据源码分析kafka java客户端的生产者和消费者的流程。
基于zookeeper的旧消费者
kafka消费者从消费数据到关闭经历的流程。
由于3个核心线程
- 基于zookeeper的连接器监听该消费者是否触发重平衡,并获取该消费者客户端消费的topic下group对应的partition以及offset。参考` ZookeeperConsumerConnector`
- 寻找partition leader线程循环寻找partition的leader,原理是基于zk的watch,并判断哪些partition的leader发生改变,如果有发生改变,那么创建新的线程来消费这些partition,并把检查之前的线程,如果有消费不是最新的leader那么就shutdown,参考`ConsumerFetcherManager`
- 数据拉取线程通过消费partition的leader,循环拉取数据
解放zookeeper的新消费者
总体思路
- 解放了消费者对zookeeper的依赖,现在只需要和broker交互就可以获取所有需要的元数据。因此,和zk相关的线程都被解放了,取而代之的是基于事件触发思想的流程。
- 减少了不必要的线程,将所有操作lazy化处理,也就是说整个消费流程是基于事件的。比如之前有专门维护心跳的线程,现在改为将心跳任务加入队列,只有在某些事件达到时才会执行。由于在拉取数据时,频繁去检验分区相关元数据会导致拉取性能下降,因此消费者每次在拉取完一批record后,会自动异步去拉取下一批的数据,并更新最新的元数据到内存,而此时使用者正在处理上一批的record,这样处理就保证了基于事件思路下的元数据更新和拉取数据的性能。
拉取数据的两种方式
- 手动分配topic和partition,也就是assign,分配之后,消费者客户端不会感知到其他事件的触发。
- 订阅topic,自动分配到topic的partition,以及该groupid之前消费到的offset,当然也可以自动感知到kafka的rebalance,并获取到相关事件。
拉取流程
- 确保kafka协调者认可了此次消费,并初始化和协调者的连接。认可很多层次的含义,包括kafka集群是否正常,安全认证是否通过之类。
- 确保分区被分配,除了手动assgin的topic,partition和offset,自动subscribe需要从kafka协调者获取相关元数据,也是发生重平衡事件的来源。
- 确保已经获取拉取的offset,否则为从协调者那重新获取对应groupid的offset,如果获取失败(比如这是一个新的groupid),那么会重置offset,根据配置用最旧或者最新来代替。参考`ConsumerCoordinator`
- 拉取数据,通过拉取每个partition的leader,基于NIO思路拉取数据缓存在内存中;参考`Fetcher`。
- 提交offset,如果开启自动提交offset的功能,那么消费者会在两个情况同步提交offset,(1)重平衡或者和broker心跳超时,参考流程2;(2)消费者关闭。如果是手动提交的话可以采用异步或者同步两种提交方式
重平衡触发原因
- 消费的topic的partition数量发生了变化
- topic被创建或者删除
- 有其他消费者客户端使用相同的group来消费或者停止消费同一个topic
数据拉取线程分为两类
kafka集群在同步副本数据的过程,也是基于客户端拉取数据,和消费者稍有不同
- 基于消费者的数据拉取线程
这也就是我们常用的消费者,数据拉取后缓存在内存中给客户端获取
- 基于副本备份的数据拉取线程
kafka集群的副本通过此类线程拉取数据,并写到本地日志中
kafka生产者
相对消费者,生产者的流程简单很多。
生产者采用双线程的方式,主线程也就是用户线程,将数据交给kafka的生产者;另外一个是生产者自己的子线程,将数据源源不断的发送到kafka。
生产流程
- 找到数据发送的partition;
- 将数据按照topic partition分类,每类采用一个双向队列存储数据;检查队列最后一个批是否正在处理,尝试加入到该批,否则创建一个新的批并加入到队列末尾。如果最后一个批已经满了(容量满了或者数据超过1)或者有新的批被创建了,那么触发生产者将数据发送到kafka
- 另外生产者的子线程也会不断的自我循环,判断内存中缓存的数据是否可以被发送到kafka,有5种情况,只要满足其一就把数据发送到broker,full || expired || exhausted || closed || flushInProgress();(1) full参考流程2;(2) expired 距离上一次数据发送的时间超过了一个阈值;(3) exhausted 生产者内部维护了内存队列,记录了当前使用的内存大小,exhausted表示申请的总数>1的情况;(4) closed 生产者被关闭了;(5) 使用者显示的调用了flush()
kafka生产者和消费者流程的更多相关文章
- [Spark][kafka]kafka 生产者,消费者 互动例子
[Spark][kafka]kafka 生产者,消费者 互动例子 # pwd/usr/local/kafka_2.11-0.10.0.1/bin 创建topic:# ./kafka-topics.sh ...
- kafka生产者和消费者api的简单使用
kafka生产者和消费者api的简单使用 一.背景 二.需要实现的功能 1.生产者实现功能 1.KafkaProducer线程安全的,可以在多线程中使用. 2.消息发送的key和value的序列化 3 ...
- Kafka 生产者和消费者入门代码基础
这篇博文讲解Kafka 的生产者和消费者实例. 基础版本一 生产者 ProducerFastStart.java package com.xingyun.tutorial_1; import org. ...
- kafka-python开发kafka生产者和消费者
1.安装kafka-python 执行命令 pip install kafka-python kafka-python 1.4.6 2.编写python kafka 生产者消费者代码 # ...
- Kafka 生产者、消费者与分区的关系
背景 最近和海康整数据对接, 需要将海康产生的结构化数据拿过来做二次识别. 基本的流程: 海康大数据 --> kafka server --> 平台 Kafka 的 topic 正常过车 ...
- kafka学习(三)kafka生产者,消费者详解
文章更新时间:2020/06/14 一.生产者 当我们发送消息之前,先问几个问题:每条消息都是很关键且不能容忍丢失么?偶尔重复消息可以么?我们关注的是消息延迟还是写入消息的吞吐量? 举个例子,有一个信 ...
- kafka生产者和消费者
在使用kafka时,有时候为验证应用程序,需要手动读取消息或者手动生成消息.这个时候可以借助kafka-console-consumer.sh和kafka-console-producer.sh 这两 ...
- springboot配置kafka生产者和消费者详解
在原有pom.xml依赖下新添加一下kafka依赖ar包 <!--kafka--> <dependency> <groupId>org.springframewor ...
- kafka生产者、消费者java示例
1. 生产者 import java.util.Properties; import kafka.javaapi.producer.Producer; import kafka.producer.Ke ...
随机推荐
- python epoll实现异步socket
一.同步和异步: 在程序执行中,同步运行意味着等待调用的函数.线程.子进程等的返回结果后继续处理:异步指不等待当下的返回结果,直接运行主进程下面的程序,等到有返回结果时,通知主进程处理.有点高效. 二 ...
- Service简介 demos
extends:http://blog.csdn.net/ithomer/article/details/7364024 一. Service简介 Service是android 系统中的四大组件之一 ...
- shell脚本备份日志
#!/bin/sh # back tomcat catalina.out cd /home/log_bak #the file DATE=`date '+%Y%m%d-%H%M'` ARCHIVE=$ ...
- java合并两个升序数组为一个新的有序数组
转自:http://blog.csdn.net/laozhaokun/article/details/37531247 题目:有两个有序数组a,b,现需要将其合并成一个新的有序数组. 简单的思路就是先 ...
- Python - 字符串的方法及注释
%r非常有用,他的含义是不管是整形还是字符串,都将打印出来
- web站点检查简易shell脚本
1.web样式 <h4>THE STATUS OF RS:</h4> <meta http-equiv="> <table border=" ...
- ThinkPHP简单结构介绍!
thinkPHP简单结构介绍: application : 应用 extend:扩展 扩展内库 public:入口文件 index.php 在里面 runtime:缓存文件(里面的文件可以随便删除) ...
- Oracle性能优化之表压缩及并行提高效率的测试
1.制作测试表 create table t1 as select * from FW_T_GTXLOG insert into t1 select * from t1; create table t ...
- 白话陈述之——从python脚本变化解析由路径引起的GP服务运行失败问题
补充一下未完待续的利用Python分析GP服务运行结果的输出路径 & 实现服务输出路径的本地化,这篇博客中主要介绍了如何实现将GP服务生成的结果输出至本地及输入输出路径导致GP服务运行失败的问 ...
- JDK安装(linux系统)
安装好centos6.8以后,输入命令: 如果显示如下: 证明系统自带了JDK,需要手动删除. 然后搜索: 备注: 查询一个包是否被安装 # rpm -q < rpm package name& ...