「Kafka」Kafka中offset偏移量提交
在消费Kafka中分区的数据时,我们需要跟踪哪些消息是读取过的、哪些是没有读取过的。这是读取消息不丢失的关键所在。
Kafka是通过offset顺序读取事件的。如果一个消费者退出,再重启的时候,它知道从哪儿继续读取消息进行处理。所以,消费者需要「提交」属于它们自己的偏移量。如果消费者已经提交了偏移量,但消息没有得到有效处理,此时就会造成消费者消息丢失。所以,我们应该重视偏移量提交的时间点以及提交的方式。
Kafka消费者的可靠性配置
1、group.id
- 如果两个消费者有相同的 group.id,并且定义同一个主题,那么每个消费者都会消费一个分区的数据
2、auto.offset.reset
- 这个参数的作用是:当没有偏移量提交(例如:消费者第一次启动、或者请求的偏移量在broker上不存在时),消费者会如何处理
- earliest:消费者从分区的开始位置读取大量的重复数据,可以保证个最少的数据丢失
- latest:消费者会从分区的末尾开始读取数据,可以减少重复读,但很有可能会错过一些消息
3、enable.auto.commit
- 可以设置自动提交偏移量,可以在代码中手动提交偏移量
- 自动提交,可以让消费者逻辑更简单
- 但它无法控制重复处理消息、或者如果消息交给另外一个后台线程去处理,自动提交机制可能会在消息还没有处理完就提交了偏移量
4、auto.commit.interval.ms
- 通过该参数,可以配置提交的频率。默认:每5秒钟提交一次
- 提交的频率高,也是会增加额外的开销的
显示提交偏移量
如果我们希望能够更有效地控制偏移量提交的时间点,就需要显示地提交偏移量。
1、总是在处理完事件后再提交偏移量
如果所有的处理都是在轮询里完成,无需在轮询之间维护状态,那么可以使用自动提交,或者在轮询结束后进行手动提交。
2、提交频率是性能和重复消息数量之间的权衡
这个意思是:提交频率越高,重复消息处理的数量越少,性能也是比较低的。提交频率越低,重复消息处理的数量越多,性能是比较好的。所以,要根据实际的情况,来衡量在什么时机,来提交偏移量。即使是在最简单的场景你,也需要在一个循环中多次提交偏移量。
3、确保对提交的偏移量心里有数
一定要在处理完消息后,再提交偏移量,否则会出现某些消息会被处理。
4、消费者可能需要重试
但处理消息出现问题时,例如:把Kafka中的数据写入到HBase中,此时HBase临时不可用。我们想要重试。假设这条消息是:#30,#30处理失败了。那大家想想?#31能提交吗?
显然是不能的,如果#31提交了,那么#31之前的所有数据,都不会被处理了。我们可以使用以下几种模式来处理:
模式一
① 但遇到可重试错误时,提交最后一个处理成功的偏移量
② 把没有处理好的消息保存到缓冲区
③ 调用 pause() 方法,确保其他的轮询不会返回数据
④ 尝试重新处理缓存中的数据,如果重试成功,或者重试次数达到上限并决定放弃,把错误记录下来并丢弃消息
⑤ 调用 resume() 方法让消费者继续从轮询里获取新数据
模式二
① 遇到可重试错误时,把错误写入一个独立的主题,然后继续
② 用一个独立的消费者组负责从该主题上读取错误消息,并进行重试
5、长时间处理
有时候要进行比较复杂的处理,暂停轮询的时间不能超过几秒钟。要保持轮询,因为只有在轮询过程中,才能往broker发送心跳。可以使用一个线程池来处理数据,可以让轮询不获取新的数据,直到工作县好吃呢个处理完成。消费者一直保持轮询,心跳正常,就不会发生再均衡。
8、仅一次传递
有的程序不仅是需要“至少一次”(at least-once语义)(意味着没有数据丢失),还需要仅一次(exactly-once)语义。实现一次性语义,最常用的办法就是把结果写入到一个支持唯一键的系统里,比如:k-v存储、关系数据库、ES或者其他数据存储。可以使用主题、分区和偏移量来作为主键,这样,可以碰巧读取到同一个相同的消息,直接覆盖写入就可以了。这种称为幂等性写入。
还有一种,就是使用关系型数据库,HDFS中一些被定义过的原子操作也经常用来达到相同的目的。把消息和偏移量放在同一个事务里,这样让它们保持同步。消费者启动,获取最近处理过的偏移量,调用seek()方法从偏移量位置继续读取数据
参考文件:
「Kafka权威指南」
「Kafka」Kafka中offset偏移量提交的更多相关文章
- 「翻译」Unity中的AssetBundle详解(二)
为AssetBundles准备资源 使用AssetBundles时,您可以随意将任何Asset分配给所需的任何Bundle.但是,在设置Bundles时,需要考虑一些策略.这些分组策略可以使用到任何你 ...
- 「翻译」Unity中的AssetBundle详解(一)
AssetBundles AssetBundle是一个存档文件,其中包含平台在运行时加载的特定资产(模型,纹理,预制,音频剪辑,甚至整个场景).AssetBundles可以表示彼此之间的依赖关系;例如 ...
- 「JSOI2013」游戏中的学问
「JSOI2013」游戏中的学问 传送门 考虑 \(\text{DP}\) 设 \(dp_{i, j}\) 表示将前 \(i\) 个人分成 \(j\) 个集合,并且第 \(i\) 个人在第 \(j\) ...
- 30分钟带你了解「消息中间件」Kafka、RocketMQ
消息中间件的应用场景 主流 MQ 框架及对比 说明 Kafka 优点 Kafka 缺点 RocketMQ Pulsar 发展趋势 各公司发展 Kafka Kafka 是什么? Kafka 术语 Kaf ...
- 「MYSQL」MYSQL中的int(11)到底代表什么意思?
一.前言 在工作中经常要与mysql打交道,但是对mysql的各个字段类型一直都是一知半解,因此写本文总结记录一番. 二.简介 对于int类型的一些基础知识其实上图已经说的很明白了,在这里想讨论下常用 ...
- 「Python-Django」Django中使用数据库的 9 个小技巧
Django 中使用数据库的 9 个小技巧. 1. 过滤器聚合 在 Django 2.0 之前,如果你想得到“用户总数”.“活跃用户总数”等信息时,你不得不使用条件表达式. Django 2.0 中, ...
- 「数据分析」Sqlserver中的窗口函数的精彩应用之数据差距与数据岛(含答案)
上一篇介绍过数据差距与数据岛的背景,这里不再赘述,请翻阅上一文.此篇在Sqlserver上给大家演示1000万条记录的计算性能. 测试电脑软硬件说明 一般般的笔记本电脑,2017年7月,价格:4500 ...
- 「数据分析」Sqlserver中的窗口函数的精彩应用-问题篇
最近看到PowerBI圈子在讨论最大连续区间段的问题,即某人最大的全勤时间,某人的最长的连续打卡时间等问题的计算,佐罗老师给出了10万倍性能的答案.这个问题也引发了笔者一些兴趣,隐约记得以前看过Sql ...
- 「Flink」Flink中的时间类型
Flink中的时间类型和窗口是非常重要概念,是学习Flink必须要掌握的两个知识点. Flink中的时间类型 时间类型介绍 Flink流式处理中支持不同类型的时间.分为以下几种: 处理时间 Flink ...
随机推荐
- Python通过win32 com接口实现offic自动化
最近几天通过Python做一些自动生成office报表的东东,比如解析.xml文件,导出.html/WORD/PPT等格式,html不足一提,只需要简单的html静态网页知识即可,这儿要说的是怎么生成 ...
- 聊一聊 MySQL 中的数据编辑过程中涉及的两阶段提交
MySQL 数据库中的两阶段提交,不知道您知道不?这篇文章就简单的聊一聊 MySQL 数据库中的两阶段提交,两阶段提交发生在数据变更期间(更新.删除.新增等),两阶段提交过程中涉及到了 MySQL 数 ...
- kuangbin专题专题十一 网络流 Going Home POJ - 2195
题目链接:https://vjudge.net/problem/POJ-2195 思路:曼哈顿距离来求每个人到每个房间的距离,把距离当作费用. 就可以用最小费用最大流来解决了,把每个房子拆成两个点,限 ...
- SpringBoot任务篇Ⅴ --- 异步任务、定时任务、邮件任务
Java的任务在项目中需要用到的地方很多,比如,每月月末的财务报表给财务部门,定时给领导发个邮件短信等等.这时候我们就需要用到任务了,任务调度本身涉及到多线程并发.运行时间规则制定和解析.场景保持与恢 ...
- 深入了解Zookeeper
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等.Zookeeper是hadoop的一个子项目,其 ...
- Leetcode 题目整理-5 Valid Parentheses & Merge Two Sorted Lists
20. Valid Parentheses Given a string containing just the characters '(', ')', '{', '}', '[' and ']', ...
- Docker(二):理解容器编排工具Kubernetes内部工作原理
一.Kubernetes是什么 要说到Docker就不得不说说Kubernetes.当Docker容器在微服务的环境下数量一多,那么统一的,自动化的管理自然少不了.而Kubernetes就是一个这样的 ...
- 用java编写代码实现关机
public static void main(String[] args) { Runtime runtime = Runtime.getRuntime(); try { runtime.exec( ...
- go接口详解
go面向接口编程知识点 接口定义与格式 隐式实现及实现条件 接口赋值 空接口 接口嵌套 类型断言 多态 接口定义与格式 接口(interface)是一种类型,用来定义行为(方法).这句话有两个重点,类 ...
- BZOJ 1042 [HAOI2008]硬币购物(完全背包+容斥)
题意: 4种硬币买价值为V的商品,每种硬币有numi个,问有多少种买法 1000次询问,numi<1e5 思路: 完全背包计算出没有numi限制下的买法, 然后答案为dp[V]-(s1+s2+s ...