kafka 消费者-从kafka读取数据

 
消费者和消费者群里
kafka消费者从属于消费者群组。一个群组里的消费者订阅的是同一主题,每个消费者接受主题一部分分区的消息。如果我们往群组里添加更多的消费者,超过主题的分区数量,那么有一部分消费者就会被闲置,不会接受到任何消息。往群组里增加消费者是横向伸缩消费能力的主要方式。简而言之,为每一个需要获取一个或多个主题全部消息的应用程序创建一个消费者群组,然后往群组里添加消费者来伸缩读取能力和处理能力,群组里的每个消费者只处理一部分消息。
 
 

消费者群组和分区再均衡

群组里的消费者共同读取主题的分区。一个新的消费者加入群组时,它读取的原本由其他消费者读取的信息。当一个消费者被关闭或发生崩溃时,它就离开群组,原本由它读取的分区将由群里的其他消费者来读取,在主题发生变化时,比如管理员添加了新的分区,会发生分区重分配,分区的所有权从一个消费者转移到另一个消费者,这样的行为被称为再均衡。
消费者通过向被指派为群组协调器的broker发送心跳来维护它们和群组的从属关系及它们对分区的所有权关系。只要消费者以正常的时间间隔发送心跳,就被认为是活泼的,说明它还在读取分区里的消息。消费者会在轮询消息或提交偏移量时发送心跳。如果消费者停止发送心跳的时间足够长,会话就会过期,群组协调器认为它已经死亡,就会触发一次再均衡。
 
 

创建kafka消费者

在读取消息之前,需要先创建一个kafkaConsumer对象。创建kafkaConsumer对象与创建kafkaProducer相识。需要3个必要的属性:bootstrap.servers,key.deserializer 和value.deserializer
 
bootstrap.servers 指定了kafka集群连接字符串。
key.deserializer和value.deserializer 把使用指定的类把字节数组转成java对象。
group.id 不是必须的,不过我们现在姑且认为它是必须的,它指定了kafkaConsumer属于哪一个消费者群组。
 
 

订阅主题

subscribe()方法接受一个主题列表作为参数,示例:
consumer.subscribe(Collections.singleonList("test"));//主题为test
 
 

轮询

消费轮询是消费者API的核心,通过一个简单的轮询向服务器请求数据。一旦消费者订阅了主题,轮询就会处理所有的细节,包括群组协调,分区再均衡,发送心跳和获取数据,开发者只需要使用一组简单的API来处理从分区返回的数据。并且轮询不只是获取数据那么简单。在第一次调用新消费者的poll()方法时,它会负责查找GroupCoordinator,然后加入群组,接受分配的分区。如果发生了再均衡,整个过程也是在轮询期间进行的。当然,心跳也是从轮询里发送出去的。所以,我们要确保在轮询期间所做的任何处理都应该尽快完成。
 
 

消费者的配置

除了上述说的bootstrap.servers,group.id,key.deserializer 和value.deserializer之外。其他的参数也会影响到消费者的性能和可用性。
1.fetch.min.bytes 该属性指定了消费者从服务器获取记录的最小字节数。
 
2.fetch.max.wait.ms 我们通过fetch.min.bytes告诉kafka,等到有足够的数据是才把它返回给消费者。
 
3.max.partition.fetch.bytes 该属性指定了服务器从每个分区里返回给消费者的最大字节数。默认是1MB
 
4.session.timeoout.ms 该属性指定了消费者在被认为死亡之前可以与服务器断开连接的时间,默认是3s.
 
5.auto.offset.reset 该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该如果处理。它的默认值是latest(从最新的消息记录读取数据),另一个值是earliest (从最早的位置开始读取记录)
 
6.enable.auto.commit 该属性指定了消费者是否自动提交偏移量。默认是true 一般是手动提交
 
7.partition.assignment.strategy 分配策略 决定哪些分区应该被分配给那个消费者
1.range 该策略会把主题的若干个连续的分区分配给消费者。
2.RoundRobin 该策略把主题的所有分区逐个分配给消费者。
默认是range.
 
8.client.id 该属性可以是任意字符串,broker用来标识从客户端发送过来的消息,通常被用在日志度量指标和配额里
 
9.max.poll.records 该属性用于控制单次调用call()方法能够返回的记录数量,可以帮你控制在轮询里需要处理的数据量。
 
10.receive.buffer.bytes 和send.buffer.bytes socket在读写数据时用到的TCP缓冲区也可以设置大小,如果他们被设置为-1,就使用操作系统的默认值。
 

提交和偏移量

 
每次调用poll()方法,它总会返回由生产者写入kafka但还没有被消费者读取过的几率,我们因此可以追踪到那些记录是被群组里的那个消费者读取的。如果提交的偏移量小于客户端处理的最后一个消息的偏移量,那么处于两个偏移量之间的消息就会被重复处理。
 
所以提交偏移量的方式对客户端会有很大的影响。kafkaConsumer API提供了很多种方式来提交偏移量。
1.自动提交,消费者会自动把从poll()方法接受到的最大偏移提交上去。提交时间间隔由auto.commit.interval.ms 默认是5s.
 
2.提交当前偏移量,设置不自动提交,使用commitSync() 提交偏移量最简单也最可靠,提交成功会马上返回,失败就抛异常 记住: commitSync() 将会提交由poll()返回的最新偏移量,所以在处理完所有记录后要确保调用了commitSync,否则还是会有丢失消息的风险。
 
3.异步提交
手动提交有一个不足之处,在broker对提交请求作为回应之前,应用程序会一直阻塞,这样会限制应用程序的吞吐量。
在成功提交或者碰到无法恢复的错误之前,commitSync()会一直重试,但是commitAsync()不会,这也是commitAsync()不好的地方。
 
4.同步和异步组合提交
一般情况下,针对偶尔出现的提交失败,不进行重试不会有太大问题,因为如果提交失败是因为临时问题导致的,那么后续的提交会是成功的。
 
这种组合保证偏移量一定提交成功,先用异步提交,如果发生异常在同步。
 
5.提交特定的偏移量,这个看业务需求
 

在均衡监听器

消费者在退出和进行分区再均衡之前,会做一些清理工作。
在订阅主题调用subscribe()方法的时候传进去一个ConsumerRebalanceListener实例就可以了,有两个需要实现的方法。
1.onpartitionsRevoked() 方法会在再均衡开始之前和消费者停止读取消息之后被调用。
2.onpartitionAssigned() 方法会在重新分配分区之后和消费者开始读取消息之前被调用。
 
 

从特定偏移量处开始处理记录

 
如果你想从起始位置开始读取消息,或者直接跳到分区的末尾开始读取消息。可以使用seektobeg() 和 sendToend() kafka也会为我们提供了用于查找特定偏移量的API。使用ConsumerRebalanceListener 接口实现。
 

如何退出

 
如果确定要退出,需要通过另一个线程调用consumer.wakeup()方法,原理线程抛出异常,线程结束,不处理异常信息。

kafka学习(三)的更多相关文章

  1. kafka学习(三)-kafka集群搭建

    kafka集群搭建 下面简单的介绍一下kafka的集群搭建,单个kafka的安装更简单,下面以集群搭建为例子. 我们设置并部署有三个节点的 kafka 集合体,必须在每个节点上遵循下面的步骤来启动 k ...

  2. kafka学习笔记:知识点整理

    一.为什么需要消息系统 1.解耦: 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余: 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险. ...

  3. kafka学习2:kafka集群安装与配置

    在前一篇:kafka学习1:kafka安装 中,我们安装了单机版的Kafka,而在实际应用中,不可能是单机版的应用,必定是以集群的方式出现.本篇介绍Kafka集群的安装过程: 一.准备工作 1.开通Z ...

  4. [Big Data - Kafka] kafka学习笔记:知识点整理

    一.为什么需要消息系统 1.解耦: 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余: 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险. ...

  5. Kafka学习之(六)搭建kafka集群

    想要搭建kafka集群,必须具备zookeeper集群,关于zookeeper集群的搭建,在Kafka学习之(五)搭建kafka集群之Zookeeper集群搭建博客有说明.需要具备两台以上装有zook ...

  6. kafka学习(二)-------- 什么是Kafka

    通过Kafka的快速入门 https://www.cnblogs.com/tree1123/p/11150927.html 能了解到Kafka的基本部署,使用,但他和其他的消息中间件有什么不同呢? K ...

  7. Docker下kafka学习三部曲之二:本地环境搭建

    在上一章< Docker下kafka学习,三部曲之一:极速体验kafka>中我们快速体验了kafka的消息分发和订阅功能,但是对环境搭建的印象仅仅是执行了几个命令和脚本,本章我们通过实战来 ...

  8. 大数据 -- kafka学习笔记:知识点整理(部分转载)

    一 为什么需要消息系统 1.解耦 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险.许多 ...

  9. kafka学习笔记(一)消息队列和kafka入门

    概述 学习和使用kafka不知不觉已经将近5年了,觉得应该总结整理一下之前的知识更好,所以决定写一系列kafka学习笔记,在总结的基础上希望自己的知识更上一层楼.写的不对的地方请大家不吝指正,感激万分 ...

随机推荐

  1. 费用流 Dijkstra 原始对偶方法(primal-dual method)

    简单叙述用Dijkstra求费用流 Dijkstra不能求有负权边的最短路. 类似于Johnson算法,我们也可以设计一个势函数,以满足在与原图等价的新图中的边权非负. 但是这个算法并不能处理有负圈的 ...

  2. CSS札记(二):级联与继承

    一.级联 概念:级联(The cascade),CSS是Cascading Style Sheet的简写,说明级联是非常重要的.从表层来看,级联表明CSS规则的顺序问题,但是级联远比这个复杂,在所有的 ...

  3. yang学习

    Ø  Yang 是对NETCONF数据模型.操作进行建模,覆盖NETCONF协议的操作层和内容层 Ø  模块和子模块 模块是yang中定义的基本单位. 模块定义单个数据模型,它可以定义完整的聚合模型, ...

  4. C++为什么不可以把一个数组直接赋值给另一个数组

    今天好奇一个问题, int a[3] = {1,2,3]; int b[3]; b=a; 编译器报错, 网上找了一圈, 大概明白: C++就是如此设定的, 数组不能直接赋值, 可以使用std::cop ...

  5. IDEA 2018.1可用License服务(持续更新)

    1. http://idea.congm.in 2.http://idea.toocruel.net

  6. 在Windows 10 操作系统打开Windows Mobile 设备中心,要么双击无反应,要么正在启动后过会就关闭了

    在Windows 10 操作系统打开Windows Mobile 设备中心,要么双击无反应,要么正在启动后过会就关闭了 解决方法: 1.运行:输入services.msc进入服务 2.找到(前提你的P ...

  7. 【leetcode】Valid Triangle Number

    题目: Given an array consists of non-negative integers, your task is to count the number of triplets c ...

  8. mysql 发现 navicat 可以远程连接,代码无法远程连接

    navicat可以远程连接, root账号也可以用代码连接. 其他的用户无法远程连接. 原因: 1.先检查下 mysql数据库里面 的 servers 表是否存在. 2.更新或者创建用户之后 使用:  ...

  9. VMWare虚拟机启动不了有个叉叉的解决办法

    打开VMWare虚拟机提示有: This virtual machine appears to be in use. If this virtual machine is already in use ...

  10. 多线程--future模式初体验

    第一次使用多线程,虽然理解的不是很透彻,但是也值得记录下.用的是future模式. 创建个线程池:private ExecutorService cachedThreadPool = Executor ...