提交和偏移量

每次调用poll 方法,总是返回生产者写入Kafka但还没有被消费者读取过的记录我们因此可以追踪到哪些记录时被群组里的哪个消费者读取过的。

我们把更新分区当前位置的操作叫做提交。

那么消费者时如何提交偏移量的呢?消费者往一个叫做_consumer_offset的特殊主题发送消息,消息里包含每个分区的偏移量。如果消费者一直处于运行状态,那么偏移量没有什么用处。不过如果消费者发生崩溃或者有新的消费者加入群组,就会触发在均衡,完成再均衡之后,每个消费者可能分配到新的分区,而不是之前那一个,为了能够继续之前的工作,消费者需要读取每个分区最后一次提交的偏移量,然后从偏移量指定的地方继续处理。

如果提交的偏移量小于客户端处理的最后一个消息的偏移量,那么处于两个偏移量之间的消息就会被重复处理。

如果提交的偏移量大于客户端处理的最后一个消息的偏移量,那么处于两个偏移量之间的消息将会丢失。

KafkaConsumer API提供了很多方式来提交偏移量。

自动提交

最简单的方式时让消费者自己提交偏移量,如果enable.auto.commit被设为true,那么每过5s,消费者自动把从poll方法接收到的最大偏移量提交上去。提交间隔时间由auto.commit.interval.ms控制,默认值时5s,如果这个5s内发生了再均衡,那么就会有消息被重复处理。自动提交虽然方便,但是并没有为开发者留有余地来避免重复处理消息。

手动提交

开发者可以在必要的时候提交当前偏移量,而不是基于时间间隔。把enable.auto.commit设为false,让应用程序决定何时提交偏移量。使用commitSync方法提交偏移量最简单也最可靠。这个API会提交由poll方法返回的最新偏移量,提交成功后马上返回,如果提交失败就会抛出异常。

commitSync方法将会提交由poll方法返回的最新偏移量,所以处理完所有记录后要确保调用了commitSync,否则还是会有丢失消息的风险。如果发生了再均衡,从最近一批消息到发生在均衡之间的所有消息都将会被重复处理。

异步提交

手动提交有一个不足之处,在broker对提交请求作出回应之前,应用程序会一直阻塞,这会影响应用程序的吞吐量,我们可以通过降低提交频率来提升吞吐量,但如果发生了再均衡,会增加重复消息的数量。

这个时候可以考虑使用异步提交API,我们只管发送提交请求,无需等待broker的响应。

在成功提交或碰到无法恢复的错误之前,commitSync方法会一直重试,但是commitAsync不会,他之所以不进行重试,是因为它在收到服务器响应的时候,可能有一个更大的偏移量已经提交成功。

我们之所以提到这个问题的复杂性和提交顺序的重要性,是因为commitAsync方法支持回调,在broker作出响应时会执行回调。回调经常被用于记录提交错误或者生成度量指标,不过如果用于重试,一定注意提交的顺序。

我们可以使用一个单调递增的序列号来维护异步提交的顺序,在每次提交偏移量之后或在回调里提交偏移量时递增序列号。在进行重试前,先检查回调的序列号和即将提交的偏移量是否相等,如果相等,说明没有新的提交,那么可以安全地进行重试,如果序列号比较大,说明有一个新的提交意见发送,应该停止重试。

提交特定的偏移量

提交偏移量的频率和处理消息的频率时一样的,但如果向频繁提交怎么办?

消费者API允许在调用commitSync和commitAsync方法时传进去希望提交的分区和偏移量map。

再均衡监听器

在为消费者分配新分区或者移除旧分区时,可以通过消费者API执行一些应用程序代码,在调用subscribe方法时传进去一个ConsumerRebalanceListener实例就可以了,它有两个需要实现的方法:

onPartitionRevoked方法会在再均衡开始之前和消费者停止读取消息之后被调用。如果在这里提交偏移量,下一个接管分区的消费者就知道该从哪里开始读取。

onPartitionAssigned方法会在重新分配分区之后和消费者开始读取消息之前被调用。

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

有时候需要从特定的偏移量开始读取消息。如果想从分区的起始位置开始读取消息,或者直接跳到分区的末尾开始读取消息,可以使用seekToBeginning方法和seekToEnd方法。

如果保存记录和偏移量可以在一个原子操作里完成,就可以避免重复处理。如果在同一个事务里把记录和偏移量都写到数据库里,那么我们就会知道记录和偏移量要么都成功,要么都失败,然后重新处理记录。

现在的问题时:如果偏移量时保存在数据库里而不是Kafka里,那么消费者在得到新分区时怎么知道该从哪里开始读取?这个时候可以使用seek方法,在消费者启动或分配到新分区时,可以使用seek方法查找保存到数据库里的偏移量。如何退出

如果确定要退出循环,需要通过另外一个线程调用consumer.wakeup方法。

kafka笔记4(2)的更多相关文章

  1. Kafka笔记整理(三):消费形式验证与性能测试

    Kafka消费形式验证 前面的<Kafka笔记整理(一)>中有提到消费者的消费形式,说明如下: .每个consumer属于一个consumer group,可以指定组id.group.id ...

  2. Kafka笔记整理(一)

    Kafka简介 消息队列(Message Queue) 消息 Message 网络中的两台计算机或者两个通讯设备之间传递的数据.例如说:文本.音乐.视频等内容. 队列 Queue 一种特殊的线性表(数 ...

  3. Kafka笔记—可靠性、幂等性和事务

    这几天很忙,但是我现在给我的要求是一周至少要出一篇文章,所以先拿这篇笔记来做开胃菜,源码分析估计明后两天应该能写一篇.给自己加油~,即使没什么人看. 可靠性 如何保证消息不丢失 Kafka只对&quo ...

  4. Kafka笔记

    最近做的一个项目需要跟Kafka打交道,学习了很多相关知识,就到这里来汇总一下. kafka是一个传递消息的系统,原本是用来快速记录海量log的,现在也经常用作消息队列.它主要由三个部分组成,prod ...

  5. kafka笔记-Kafka在zookeeper中的存储结构【转】

    参考链接:apache kafka系列之在zookeeper中存储结构  http://blog.csdn.net/lizhitao/article/details/23744675 1.topic注 ...

  6. Kafka笔记--指定消息的partition规则

    参数的设定:参考资料 不错的资料:http://blog.csdn.net/honglei915/article/details/37697655 http://developer.51cto.com ...

  7. Kafka笔记--监控系统KafkaOffsetMonitor

    KafkaOffsetMonitor下载链接: http://download.csdn.net/detail/changong28/7930337github官方:https://github.co ...

  8. Kafka笔记--使用ubuntu为bocker(服务器)windows做producer和comsumer(客户端)

    原文连接:http://www.cnblogs.com/davidwang456/p/4201875.html 程序仍然使用之前的一篇博文中的例子 :http://www.cnblogs.com/gn ...

  9. Kafka笔记--参数说明及Demo

    参考资料:http://blog.csdn.net/honglei915/article/details/37563647参数说明:http://ju.outofmemory.cn/entry/119 ...

  10. Kafka笔记--分布式环境搭建

    部署: http://www.cnblogs.com/likehua/p/3999538.html http://blog.csdn.net/kimmking/article/details/8263 ...

随机推荐

  1. IIS执行原理

    IIS执行原理   服务器的监听(IIS6.0+版本) 当请求到达服务器时,请求最终会到达TCPIP.SYS驱动程序,TCPIP.SYS将请求转发给HTTP.SYS网络驱动程序的请求队列中(可以理解为 ...

  2. Method and apparatus for training a memory signal via an error signal of a memory

    Described herein is a method and an apparatus for training a memory signal via an error signal of a ...

  3. python 简单的Socket编程

    python 编写server的步骤: 1第一步是创建socket对象.调用socket构造函数.如: socket = socket.socket(family, type ) family参数代表 ...

  4. Python 爬虫 —— scrapy

    0. 创建网络爬虫的常规方法 进入命令行(操作系统的命令行,不是 python 的命令行) windows:cmd ⇒ c:\Uses\Adminstrator> Linux:$ 执行:scra ...

  5. WPF中桌面屏保的制作(主要代码)

    原文:WPF中桌面屏保的制作(主要代码) 制作要点:(1) 使用System.Windows.Threading.DispatcherTimer;(2) 将Window属性设置为:      this ...

  6. python之强大的日志模块

    1.简单的将日志打印到屏幕   import logging logging.debug('This is debug message')logging.info('This is info mess ...

  7. Win32 键盘事件 - 击键消息、字符消息、插入符号(光标)

    注:以下内容为学习笔记,多数是从书本.资料中得来,只为加深印象,及日后参考.然而本人表达能力较差,写的不好.因非翻译.非转载,只好选原创,但多数乃摘抄,实为惭愧.但若能帮助一二访客,幸甚! 以下内容主 ...

  8. WPF 页面切换效果

    原文:WPF 页面切换效果 最近做一个有页面切换的吧.. 我觉得这个功能是比较基础的吧.. 在网上百度了一下.. 用NavigationWindow的比较好.. 因为Demo中是带了淡入淡出的页面效果 ...

  9. WPF 视图导航

    <Window x:Class="ViewExam.MainWindow"        xmlns="http://schemas.microsoft.com/w ...

  10. WPF关于控件 父级控件,子级控件,控件模板中的控件,等之间的相互访问

    原文:WPF关于控件 父级控件,子级控件,控件模板中的控件,等之间的相互访问 1,在菜单中访问 弹出菜单的控件 var mi = sender as MenuItem;//菜单条目 MenuItem ...