专栏首页IT技术小咖Kafka 消息可靠性

Kafka 消息可靠性

在 Kafka 工作机制 一文提及了 Kafka 消息的不可靠性。本文就 Kafka 消息的三种不可靠性(重复、丢失、乱序),分析它们出现的内部原因和解决办法。

1 Kafka 消息的问题

Kafka就比较适合高吞吐量并且允许少量数据丢失的场景,如果非要保证“消息只读取一次”,可以使用JMS。 参考: http://blog.csdn.net/u012050154/article/details/78592854

Kafka Producer 消息发送有两种方式(配置参数 producer.type):

  • producer.type=sync(默认值): 后台线程中消息发送是同步方式,对应的类为 kafka.producer.SyncProducer;
  • producer.type=async: 后台线程中消息发送是异步方式,对应的类为 kafka.producer.AyncProducer;优点是可批量发送消息(消息个数达到 batch.num.messages=200 或时间达到 时发送)、吞吐量佳,缺点是发送不及时可能导致丢失;

对于同步方式(producer.type=sync)?Kafka Producer 消息发送有三种确认方式(配置参数 acks):

  • acks=0: producer 不等待 Leader 确认,只管发出即可;最可能丢失消息,适用于高吞吐可丢失的业务;
  • acks=1(默认值): producer 等待 Leader 写入本地日志后就确认;之后 Leader 向 Followers 同步时,如果 Leader 宕机会导致消息没同步而丢失,producer 却依旧认为成功;
  • acks=all/-1: producer 等待 Leader 写入本地日志、而且 Leader 向 Followers 同步完成后才会确认;最可靠。

Kafka Consumer 有两个接口:

  • Low-level API: 消费者自己维护 offset 等值,可以完全控制;
  • High-level API: 封装了对 parition 和 offset 的管理,使用简单;可能遇到 Consumer 取出消息并更新了 offset,但未处理消息即宕机,从而相当于消息丢失;

Kafka 支持 3 种消息传递语义:

  • 最多一次 -消息可能会丢失,但永远不会重新发送。
  • consumer.poll();
  • consumer.commitOffset();
  • processMsg(messages);
  • 至少一次 -消息永远不会丢失,但可能会重新传递。
  • consumer.poll();
  • processMsg(messages);
  • consumer.commitOffset();
  • 恰恰一次 - 这就是人们真正想要的,每条信息只传递一次。以事务来保证。

2 消息重复

  • 根本原因:已经消费了数据,但是 offset 没提交。
  • 外在原因:(1)消费数据后、提交 offset 前,线程被杀; (2)设置 offset 为自动提交,consumer.close() 之前 consumer.unsubscribe(); (3)consumer 取了一批数据,尚未处理完毕时,达到了 session.timeout.ms,导致没有接收心跳而挂掉,自动提交offset失败,下次会重复消费本批消息;
  • 解决办法:(1)唯一 ID 保存在外部介质中,每次消费时根据它判断是否已处理; (2)如果在统计用,丢失几条关系不大,则无需理会; (3)如果消费者来不及处理,可以这样优化:增加分区以提高并行能力;增加消费者线程;关闭自动提交 enable.auto.commit=false

3 消息丢失

  • 根本原因:已经提交了 offset,但数据在内存中尚未处理,线程就被杀掉。 同步模式下,确认机制设置为-1(不可为1),即让消息写入Leader和Follower之后再确认消息发送成功; 异步模式下,设置为不限制阻塞超时时间(不可为acks=0),当缓冲区满时不清空缓冲池,而是让生产者一直处于阻塞状态;

4 消息乱序

传统的队列,在并行处理时,由于网络故障或速度差异,尽管服务器传递是有序的,但消费者接收的顺序可能不一致; Kafka 在主题内部有分区,并行处理时,每个分区仅由消费者组中的一个消费者使用,确保了消费者是该分区的唯一读者,并按顺序使用这些数据。 但是它也仅仅是保证Topic的一个分区顺序处理,不能保证跨分区的消息先后处理顺序,除非只提供一个分区。

作者:王克锋

出处:https://kefeng.wang/2017/11/22/kafka-reliability/

本文分享自微信公众号 - IT技术小咖(IT-arch),作者:王克锋

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何设计才可以让系统从未分库分表动态切换到分库分表上?

    我先给你说一个最 low 的方案,就是很简单,大家伙儿凌晨 12 点开始运维,网站或者 app 挂个公告,说 0 点到早上 6 点进行运维,无法访问。

    IT技术小咖
  • Kafka 工作机制

    Kafka 是 Apache 的子项目,是一个高性能跨语言的分布式发布/订阅消息队列系统(没有严格实现 JMS 规范的点对点模型,但可以实现其效果),在企业开发...

    IT技术小咖
  • SpringBoot 使用 ELK 日志收集之 Kibana 安装

    本文环境是在腾讯云服务器CentOS7.2搭建的,JDK1.8,kibana-5.4.2。

    IT技术小咖
  • 面试官为什么喜欢拿 Kafka 考验求职者

    小灰工作3年了,一直在一家初创公司做大数据架构师,最近几次大厂的面试经历都百般不顺,小灰心如死灰,想着如果一直跳槽无望,只能跟着时下最火的地摊儿大军一起去出摊儿...

    江帅帅
  • Apache Kafka简单入门

    为了理解Kafka是如何做到以上所说的功能,从下面开始,我们将深入探索Kafka的特性。

    大数据技术与架构
  • Kafka集群消息积压问题及处理策略

    通常情况下,企业中会采取轮询或者随机的方式,通过Kafka的producer向Kafka集群生产数据,来尽可能保证Kafk分区之间的数据是均匀分布的。

    大数据学习与分享
  • Kafka系列文章第1篇之Kafka是什么

    如果有幸目睹过系统从零到一的演变过程,大家估计都会有一种感叹,就是随着业务复杂度和流量的不断上升,系统变得越来越难以维护,面对高额的维护成本,攻城师们不得不对现...

    z小赵
  • 大数据开发:Apache Kafka分布式流式系统

    Kafka在大数据流式处理场景当中,正在受到越来越多的青睐,尤其在实时消息处理领域,kafka的优势是非常明显的。相比于传统的消息中间件,kafka有着更多的潜...

    成都加米谷大数据
  • 使用Kubernetes和Docker将Spring Boot和MongoDB作为容器部署

    对于本教程,您将拥有一个Dockerized示例spring-boot应用程序,该应用程序与MongoDB通信以获取GET / POST REST API并部署...

    February
  • Kafka,凭什么这么快?

    在过去的几年里,软件架构领域发生了巨大的变化。人们不再认为所有的系统都应该共享一个数据库。微服务、事件驱动架构和CQRS(命令查询的责任分离 Command Q...

    程序员小强

扫码关注云+社区

领取腾讯云代金券