在消费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偏移量提交的更多相关文章

  1. 「翻译」Unity中的AssetBundle详解(二)

    为AssetBundles准备资源 使用AssetBundles时,您可以随意将任何Asset分配给所需的任何Bundle.但是,在设置Bundles时,需要考虑一些策略.这些分组策略可以使用到任何你 ...

  2. 「翻译」Unity中的AssetBundle详解(一)

    AssetBundles AssetBundle是一个存档文件,其中包含平台在运行时加载的特定资产(模型,纹理,预制,音频剪辑,甚至整个场景).AssetBundles可以表示彼此之间的依赖关系;例如 ...

  3. 「JSOI2013」游戏中的学问

    「JSOI2013」游戏中的学问 传送门 考虑 \(\text{DP}\) 设 \(dp_{i, j}\) 表示将前 \(i\) 个人分成 \(j\) 个集合,并且第 \(i\) 个人在第 \(j\) ...

  4. 30分钟带你了解「消息中间件」Kafka、RocketMQ

    消息中间件的应用场景 主流 MQ 框架及对比 说明 Kafka 优点 Kafka 缺点 RocketMQ Pulsar 发展趋势 各公司发展 Kafka Kafka 是什么? Kafka 术语 Kaf ...

  5. 「MYSQL」MYSQL中的int(11)到底代表什么意思?

    一.前言 在工作中经常要与mysql打交道,但是对mysql的各个字段类型一直都是一知半解,因此写本文总结记录一番. 二.简介 对于int类型的一些基础知识其实上图已经说的很明白了,在这里想讨论下常用 ...

  6. 「Python-Django」Django中使用数据库的 9 个小技巧

    Django 中使用数据库的 9 个小技巧. 1. 过滤器聚合 在 Django 2.0 之前,如果你想得到“用户总数”.“活跃用户总数”等信息时,你不得不使用条件表达式. Django 2.0 中, ...

  7. 「数据分析」Sqlserver中的窗口函数的精彩应用之数据差距与数据岛(含答案)

    上一篇介绍过数据差距与数据岛的背景,这里不再赘述,请翻阅上一文.此篇在Sqlserver上给大家演示1000万条记录的计算性能. 测试电脑软硬件说明 一般般的笔记本电脑,2017年7月,价格:4500 ...

  8. 「数据分析」Sqlserver中的窗口函数的精彩应用-问题篇

    最近看到PowerBI圈子在讨论最大连续区间段的问题,即某人最大的全勤时间,某人的最长的连续打卡时间等问题的计算,佐罗老师给出了10万倍性能的答案.这个问题也引发了笔者一些兴趣,隐约记得以前看过Sql ...

  9. 「Flink」Flink中的时间类型

    Flink中的时间类型和窗口是非常重要概念,是学习Flink必须要掌握的两个知识点. Flink中的时间类型 时间类型介绍 Flink流式处理中支持不同类型的时间.分为以下几种: 处理时间 Flink ...

随机推荐

  1. Python通过win32 com接口实现offic自动化

    最近几天通过Python做一些自动生成office报表的东东,比如解析.xml文件,导出.html/WORD/PPT等格式,html不足一提,只需要简单的html静态网页知识即可,这儿要说的是怎么生成 ...

  2. 聊一聊 MySQL 中的数据编辑过程中涉及的两阶段提交

    MySQL 数据库中的两阶段提交,不知道您知道不?这篇文章就简单的聊一聊 MySQL 数据库中的两阶段提交,两阶段提交发生在数据变更期间(更新.删除.新增等),两阶段提交过程中涉及到了 MySQL 数 ...

  3. kuangbin专题专题十一 网络流 Going Home POJ - 2195

    题目链接:https://vjudge.net/problem/POJ-2195 思路:曼哈顿距离来求每个人到每个房间的距离,把距离当作费用. 就可以用最小费用最大流来解决了,把每个房子拆成两个点,限 ...

  4. SpringBoot任务篇Ⅴ --- 异步任务、定时任务、邮件任务

    Java的任务在项目中需要用到的地方很多,比如,每月月末的财务报表给财务部门,定时给领导发个邮件短信等等.这时候我们就需要用到任务了,任务调度本身涉及到多线程并发.运行时间规则制定和解析.场景保持与恢 ...

  5. 深入了解Zookeeper

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等.Zookeeper是hadoop的一个子项目,其 ...

  6. Leetcode 题目整理-5 Valid Parentheses & Merge Two Sorted Lists

    20. Valid Parentheses Given a string containing just the characters '(', ')', '{', '}', '[' and ']', ...

  7. Docker(二):理解容器编排工具Kubernetes内部工作原理

    一.Kubernetes是什么 要说到Docker就不得不说说Kubernetes.当Docker容器在微服务的环境下数量一多,那么统一的,自动化的管理自然少不了.而Kubernetes就是一个这样的 ...

  8. 用java编写代码实现关机

    public static void main(String[] args) { Runtime runtime = Runtime.getRuntime(); try { runtime.exec( ...

  9. go接口详解

    go面向接口编程知识点 接口定义与格式 隐式实现及实现条件 接口赋值 空接口 接口嵌套 类型断言 多态 接口定义与格式 接口(interface)是一种类型,用来定义行为(方法).这句话有两个重点,类 ...

  10. BZOJ 1042 [HAOI2008]硬币购物(完全背包+容斥)

    题意: 4种硬币买价值为V的商品,每种硬币有numi个,问有多少种买法 1000次询问,numi<1e5 思路: 完全背包计算出没有numi限制下的买法, 然后答案为dp[V]-(s1+s2+s ...