一、生产经验 - 分区的分配以及再平衡:
1.1.何时产生分区分配再平衡::
- 当消费者组中的某个消费者挂掉的时候会产分区的分配以及再平衡:
1.2.分区分配再平衡策略有哪些:
- 1.
Kafka有四种主流的分区分配策略:
- Range
- RoundRobin
- Sticky
- CooperativeSticky
- 2.可以通过配置参数partition.assignment.strategy,修改分区的分配策略
- 3.默认策略是Range + CooperativeSticky。Kafka可以同时使用多个分区分配策略
1.3.Range策略及再平衡
a.Range 分区策略原理:
- 说明:Kafka 默认的分区分配策略就是 Range + CooperativeSticky
b.Range 分区分配策略案例
- 1.修改主题 first 为 7 个分区:
bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --alter --topic first --partitions 7
- 2.启动消费者3台:组名都为“test”
- 3.启动 CustomProducer 生产者,发送 500 条消息,随机发送到不同的分区
c.Range 分区分配再平衡案例
1.4.RoundRobin 以及再平衡:
a.RoundRobin 分区策略原理
b.RoundRobin 分区分配策略案例
- 1.依次在 CustomConsumer、CustomConsumer1、CustomConsumer2 三个消费者代码中修改分区分配策略为 RoundRobin
properties.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG, "org.apache.kafka.clients.consumer.RoundRobinAssignor");
c.RoundRobin 分区分配再平衡案例
1.5.Sticky 以及再平衡
a.粘性分区定义
- 粘性分区定义可以理解为分配的结果带有“粘性的”。即在执行一次新的分配之前,考虑上一次分配的结果,尽量少的调整分配的变动,可以节省大量的开销。
- 粘性分区是 Kafka 从 0.11.x 版本开始引入这种分配策略,首先会尽量均衡的放置分区到消费者上面,在出现同一消费者组内消费者出现问题的时候,会尽量保持原有分配的分区不变化
b.编码测试:
- 需求:设置主题为 first,7 个分区;准备 3 个消费者,采用粘性分区策略,并进行消费,观察消费分配情况。然后再停止其中一个消费者,再次观察消费分配情况
- 步骤:修改分区分配策略为粘性
// 修改分区分配策略
ArrayList<String> startegys = new ArrayList<>();
startegys.add("org.apache.kafka.clients.consumer.StickyAssignor");
properties.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,startegys);
- 注意: 3 个消费者都应该注释掉,之后重启 3 个消费者,如果出现报错,全部停止。等会再重启或者修改为全新的消费者组
c.Sticky 分区分配再平衡案例
二、消费者重要参数
三、offset 位移
3.1.offset 的默认维护位置:
a.存储位置说明:
- 1.
__consumer_offsets
主题里面采用 key 和 value 的方式存储数据。- key 是 group.id+topic+分区号
- value 就是当前 offset 的值
- 2.每隔一段时间,kafka 内部会对这个 topic 进行压缩,也就是每个group.id+topic+分区号就保留最新数据
b.消费offset案例:
第1步:更改配置文件:
- 在配置文件 config/consumer.properties 中添加配置
exclude.internal.topics=false
,默认是 true,表示不能消费系统主题 为了查看该系统主题数据,所以该参数修改为 false
第2步:创建 topic
- 采用命令行方式,创建一个新的 topic
第3步:生产者发数据
- 启动生产者往 atguigu 生产数据
第4步:消费 数据
- 启动消费者消费 atguigu 数据,在启动消费者时,指定消费者组名称,更好观察数据存储位置(key 是 group.id+topic+分区号)
第5步:查看消费者消费主题
- 查看消费者消费主题__consumer_offsets
第6步:结论分析:
3.2.自动提交 offset
a.自动提交offset
- 为了使我们能够专注于自己的业务逻辑,Kafka提供了自动提交offset的功能
- 2.自动提交offset的相关参数:
- enable.auto.commit:是否开启自动提交offset功能,默认是true
- auto.commit.interval.ms:自动提交offset的时间间隔,默认是5s
b.参数设置:
- 1.参数解释:
参数名称 | 描述 |
---|---|
enable.auto.commit | 默认值为 true,消费者会自动周期性地向服务器提交偏移量 |
auto.commit.interval.ms | 如果设置了 enable.auto.commit 的值为 true, 则该值定义了消费者偏移量向 Kafka 提交的频率,默认 5s |
- 2.编码实现:
3.3.手动提交 offset
a.手动提交offset
- 虽然自动提交offset十分简单便利,但由于其是基于时间提交的,开发人员难以把握offset提交的时机。因此Kafka还提供了手动提交offset的API
b.手动提交offset的方法
- 1.手动提交offset的方法有两种:
- commitSync(同步提交) : 必须等待offset提交完毕,再去消费下一批数据。
- commitAsync(异步提交):发送完提交offset请求后,就开始消费下一批数据了
- 2.两者的相同点是:
- 都会将本次提交的一批数据最高的偏移量提交
- 3.两者的不同点是:
- 同步提交阻塞当前线程,一直到提交成功,并且会自动失败重试(由不可控因素导致,也会出现提交失败)
- 异步提交则没有失败重试机制,故有可能提交失败
- 4.编码实现:
3.4 指定 Offset 消费:
a.配置说明:
- auto.offset.reset = earliest | latest | none 默认是 latest
- 当 Kafka 中没有初始偏移量(消费者组第一次消费)或服务器上不再存在当前偏移量时(例如该数据已被删除),该怎么办?
- earliest:自动将偏移量重置为最早的偏移量,
--from-beginning
- latest(默认值):自动将偏移量重置为最新偏移量
- earliest:自动将偏移量重置为最早的偏移量,
b.编码实现指定Offset 消费:
- 编码实现:
3.5.指定时间消费
a.需求介绍:
- 需求:在生产环境中,会遇到最近消费的几个小时数据异常,想重新按照时间消费,例如要求按照时间消费前一天的数据,怎么处理?
b.编码实现:
3.6 漏消费和重复消费
- 重复消费:已经消费了数据,但是 offset 没提交
- 漏消费:先提交 offset 后消费,有可能会造成数据的漏消费
要实现既不漏消费也不重复消费的方式是使用消费者事务
四、生产经验-消费者事务
- 如果想完成Consumer端的精准一次性消费,那么需要Kafka消费端将消费过程和提交offset过程做原子绑定
- 此时我们需要将Kafka的offset保存到支持事务的自定义介质(比 如MySQL)。这部分知识会在后续项目部分涉及
五、生产经验 - 数据积压(消费者如何提高吞吐量)
5.1.Kafka消费能力
- 如果是Kafka消费能力不足,则可以考虑增加Topic的分区数,并且同时提升消费组的消费者数量,消费者数 = 分区数(两者缺一不可)
5.2.下游的数据处理不及时
- 如果是下游的数据处理不及时:提高每批次拉取的数量。批次拉取数据过少(拉取数据/处理时间 < 生产速度),使处理的数据小于生产的数据,也会造成数据积压
5.3.参数说明:
参数名称 | 描述 |
---|---|
fetch.max.bytes | 默认 Default: 52428800(50 m)。消费者获取服务器端一批消息最大的字节数。如果服务器端一批次的数据大于该值(50m)仍然可以拉取回来这批数据,因此,这不是一个绝对最大值。一批次的大小受 message.max.bytes (brokerconfig)or max.message.bytes (topic config)影响。 |
max.poll.records | 一次 poll 拉取数据返回消息的最大条数,默认是 500 条 |