(一)消费者和消费者组
1、消费者:订阅并消费kafka消息,从属于消费者组
2、消费者组:一个群组里的消费者订阅的是同一个主题,每个消费者接受主题一部分分区的消息。
注:同一个消费者可以消费不同的partition,但是同一个partition不能被不同消费者消费。
(二)消费者群组和分区再均衡
1、再均衡:分区的消费所有权从一个消费者转移到另一个消费者称为再均衡,为消费者组带来了高可用性和可伸缩性。
注:分区何时重新分配:加入消费者或者消费者崩溃等
2、如何判断消费者崩溃:消费者通过向群组协调器(某broker,不同群组可以有不同的群组协调器)发送心跳(一般在拉取消息或者提交偏移量的时候)表示自己仍旧存活,如果长时间不发送心跳则协调器认为期死亡并进行再均衡。
注:在0.10.1版本中,心跳行为不再和获取消息和提交偏移量绑定在一起,有一个单独的心跳线程。
3、分配分区:消费者加入消费者组是,会像群组协调器发送请求,第一个加入的成为“群主”。群主从协调器那里获取成员列表,并负责给每一个消费者分配分区。完毕之后,将分配结果发送给协调器,协调器再将消息发送给所有的消费者,每个消费者只能看到自己的分配信息。只有群主知道所有的消费信息。
(三)参数配置
1、bootstrap.server:host:port
2、key.serializer:键序列化器
3、value.serializer:值序列化器
注:以上为必须设置的
4、group.id:从属的消费者组
5、fetch.min.bytes:消费者从服务器获取记录的最小字节数。
6、fetch.max.wait.ms:消费者等待消费消息的最大时间
7、max.partition.fetch.bytes:服务器从每个分区返回给消费者的最大字节数(需要比broker的设置max.message.size属性配置大,否则有些消息无法消费)
8、session.timeout.ms:指定该消费者在被认为死亡之前可以与服务器断开连接的时间,默认3秒
9、heartbeat.interval.ms:制定了poll方法向协调器发送心跳的频率。
注:一般9是8的三分之一
10、auto.offset.reset:消费者在读取一个没有偏移量分区或者无效偏移量分区的情况下如何处理(latest:从最新记录开始读取,earliest:从最早的记录开始读取)
11.、enable.auth.commit:消费者是否自动提交偏移量,默认为true
12、auto.commit.interval.ms:自动提交偏移量的时间间隔
13、partition.assignment.strategy:分区分配给消费者的策略:
(1)range:会把主题若干个连续分区分配给消费者
(2)roundRobin:会把主题的所有分区逐个分配给消费者
14、client.id:任意字符串,broker用来区分客户端发来的消息
15:max.poll.records:控制poll方法返回的最大记录数
16:receive.buffer.bytes/send.buffer.bytes:tcp缓冲池读写大小
(四)订阅主题
consumer.subscribe(list)
(五)轮训(消费者API的核心)
1、轮训作用: 只要消费者订阅了主题,轮训就会处理所有的细节(群组协调、分区再均衡、发送心跳、获取数据)
(1)获取数据
(2)第一次执行poll时,负责查找协调器,然后加入群组,接受分配的分区
(3)心跳的发送
(4)再均衡也是在轮训期间进行的
2、方法:poll(),消费者缓冲区没有数据时会发生阻塞,可以传一个阻塞时间,避免无限等待。0表示立即返回。
3、关闭:close(),网络连接随之关闭,立即触发再均衡。
4、线程安全:无法让一个线程运行多个消费者,也无法让多个线程公用一个消费者。
(六)提交和偏移量
1、提交:更新分区当前位置的操作
2、如何提交:消费者往一个特殊主题(_consumer_offset)发送消息,消息中包含每个分区中的偏移量。
3、偏移量:分区数据被消费的位置。
4、偏移量作用:当发生再均衡时,消费者可能会分配到不一样的分区,为了继续工作,消费者需要读取到每个分区最后一次提交的偏移量,然后从偏移量的地方继续处理。
5、提交偏移量的方式
(1)自动提交:经过一个时间间隔,提交上一次poll方法返回的偏移量。每次轮训都会检测是否应该提交偏移量。缺陷:可能导致重复消费
(2)手动提交:commitSysn()提交迁移量,最简单也最可靠,提交由poll方法返回的最新偏移量。缺点:忘了提交可能会丢数据,再均衡可能会重复消费
(3)异步提交:同步提交在提交过程中必须阻塞
(4)同步异步提交组合
(5)提交特定的偏移量
(七)再均衡监听器
(八)从特定偏移量读取数据(seek)
1、从分区开始:seekToBegining
2、从分区结束:seekToEnd
3、ConsumerRebalanceListener和seek结合使用
(九)如何退出
1、前言:wakeup方法是唯一安全退出轮训的方法,从poll方法中退出并抛出wakeupException异常。如果没有碰上轮训,则在下一次poll调用时抛出。
2、退出轮训
(1)另一个线程调用consumer.wakeup方法
(2)如果循环在主线程里可以在ShutdownHook里面调用该方法
3、退出之前调用close方法:告知协调器自己要离开,出发再均衡,不必等到超时。
(十)独立消费者(assign为自己分配分区)