大数据技术分享

kafka Consumer — offset的控制

2019-12-10  本文已影响0人  code_solve

前言

在N久之前,曾写过kafka 生产者使用详解
今天补上关于 offset 相关的内容。
那么本文主要涉及:

  1. Kafka 消费者的两个大版本
  2. 消费者的基本使用流程
  3. 重点:offset 的控制

消費者版本

  1. 开源之初使用Scala 语言编写的客户端,
    我们可以称之为旧消费者客户端(Old Consumer)
    或 Scala 消费者客户端;

  2. 第二个是从Kafka 0.9. x 版本开始推出的使用Java 编写的客户端,
    我们可以称之为新消费者客户端( New Consumer )
    或Java 消费者客户端,
    它弥补了旧客户端中存在的诸多设计缺陷,
    不过我不建议你在0.9.x 使用该客户端,
    该新客户端再 0.10.0 才算比较稳定了

这里额外提一句就是,客户端从scala 语言转向 java,
并不是 java 比 scala 要怎么怎么样,
仅仅只是因为社区的开发者换人了~~~~

开发一个消费者的正常流程

一个正常的消费逻辑需要具备以下几个步骤:

  1. 配置消费者客户端参数及创建相应的消费者实例。
  2. 订阅主题。
  3. 拉取消息并消费。
  4. 提交消费位移。
  5. 关闭消费者实例。

消费者可以订阅多个Topic,
consumer.subscribe(Arrays.asList("t1","t2"))),
如果订阅多次,后面的会覆盖前面的,
所以取消订阅其实也可以去订阅一个空集合。

订阅支持正则表达式:
consumer.subscribe(Pattern.compile("topic .*"));
这样订阅后,如果kafka后面新增了满足该正则的 Topic也会被该消费者消费

消费者也可以直接订阅某个分区的数据,
这里我们贴下代码,如下:

List<TopicPartition> partitions = new ArrayList<>();
// 查询kafka分区信息
List<Partitioninfo> partitioninfos = consumer.partitionsFor( topic );
if (partitioninfos != null) {
for (Partitioninfo tpinfo : partitioninfos) {
partitions.add(new TopicPartition( tpinfo.topic(), tpinfo.partition() )) ;
consumer.assign( partitions ) ;

值得注意的是:
subscribe订阅是具有分区在均衡能力的,
而 assign 是没有的

这里我们只是简单的过了一下 消费者,
因为不是本文的重点,
如果要详细了解的话,
还是去看看这篇 kafka 生产者使用详解

Offset 提交

这里指的是消费者消费的位移,
而不是Kafka端储存的消息的 offset,
这其中的区别希望读者清楚,不要混淆了。
对于offset 的提交,
我们要清楚一点
如果我们消费到了 offset=x 的消息
那么提交的应该是 offset=x+1,
而不是 offset=x

kafka的提交方式分为两种:

自动提交

在Kafka 中默认的消费位移的提交方式是自动提交,
这个由消费者客户端参数enable.auto.commit 配置,
默认值为true。
当然这个默认的自动提交不是每消费一条消息就提交一次,
而是定期提交,
这个定期的周期时间由客户端参数auto.commit.interval.ms配置,
默认值为5 秒,
此参数生效的前提是enable.auto.commit 参数为true。
自动位移提交的动作是在poll()方法的逻辑里完成的,
在每次真正向服务端发起拉取请求之前会检查是否可以进行位移提交,
如果可以,那么就会提交上一轮消费的位移。

手动提交

最后,我们来总结下:

  1. 一般来说,我们不会使用自动提交的方式管理 offset,
    虽然简单,但是缺乏很好的控制,
    不过如果能满足业务要求,
    那么还是果断的使用起来吧

  2. 对于手动提交,
    一般我们都是使用异步提交的方式,
    在考虑准确的消费的情况下,兼顾的效率。

  3. 同步提交一般用来辅助异步提交,
    对于一些特殊情况,保证offset的正确提交。

  4. 我们考虑到了再均衡的影响,并做了相关的处理

  5. 对于消费者异常退出 和 崩溃:
    很遗憾的是如果出现异常和崩溃,
    我们的消费还是很难做到精准的一次消费,
    不过一般来说,
    以上这些方法是绝对满足大部分企业大部分的业务的需求。
    如果你实在要保证精准的一次消费,
    你可能还需要一些其他的辅助,
    比如:消费和提交 当做一次事务,
    或者 重复消费是幂等 等等方式。

    要精准一次消费,
    还得依靠开发人员来自己保证,
    当然,如果你使用 Kafka 的stream 方式消费,
    是可以做到精准一次消费的,
    不过这不在本文的讨论范围了...

最后,感谢你的阅读,如果可以,留个赞支持下作者!!!嘿嘿嘿~~~

上一篇下一篇

猜你喜欢

热点阅读