Kafka经典三大问:数据有序丢失重复

在kafka中有三个经典的问题:

  • 如何保证数据有序性
  • 如何解决数据丢失问题
  • 如何处理数据重复消费

这些不光是面试常客,更是日常使用过程中会遇到的几个问题,下面分别记录一下产生的原因以及如何解决。

1. 消息有序

kafka 的数据,在同一个partition下是默认有序的,但在多个partition中并不一定能够保证其顺序性。kafka因为其自身的性质,适合高吞吐的流式大数据,对数据有序性要求不严格的场景比较适用。

1.1. 为什么只保证单partition有序?

如果Kafka要保证多个partition有序,不仅broker保存的数据要保持顺序,消费时也要按序消费。假设partition1堵了,为了有序,那partition2以及后续的分区也不能被消费,这种情况下,Kafka 就退化成了单一队列,毫无并发性可言,极大降低系统性能。因此Kafka使用多partition的概念,并且只保证单partition有序。这样不同partiiton之间不会干扰对方。

1.2. 解决方式

kafka自身没有提供整个topic级别的消息顺序性,但我们可以在业务层面来处理。

可以通过message key来保证你需要保持顺序性的数据发送到同一个partition,即send方法,可以指定三个参数(topic, partition, key), partition和key是可选的,如果指定了同一个partition的话,那么数据就是有序的。

同时在消费端,只创建一个消费者来消费topic,但后续的话这个消费者可以写入N个内存队列,保证具有相同key的数据写入同一个内存队列即可。引入内存队列是为了解决业务处理单线程处理太慢的问题,多个内存队列可以起多个线程进行消费,同时具有相同key的数据在同一个内存队列中,这样就能保证顺序性。

2. 数据丢失

丢失数据一般分为两种情况:mq自己弄丢了,业务处理弄丢了。

2.1. kafka弄丢了数据

kafka的某个broker宕机,重新选举partition的leader时,如果其他的follower还没有完成数据同步,此时leader挂了,那么就有可能造成数据丢失的问题。

kafka提供了几个参数来保证数据不丢失:

  • replication.factor:分区副本数,最低设置为2,即要求每个Partition至少拥有两个副本;

  • min.insync.replicas:要求一个leader感知到有至少一个follower还跟自己保持联系,没掉队,这样才能确保leader挂了还有一个follower;

  • acks:在producer发送数据成功后,kafka会给生产者返回一个ack信息,这个称为kafka的ack机制;

    ack有3个可选值,-1、0、1;

    • ack=1:producer只要收到一个分区副本写入成功的通知就认为推送消息成功,这个分区副本特指leader副本;

    • ack=0:producer发送一次就不再发送了,不管是否发送成功;

    • ack=-1:producer只有收到分区内所有副本的成功写入通知才算推送消息成功;

  • retries:重试次数,如果写入失败就会进行重试,直到超过retries设置的值;

2.2. 消费端弄丢了数据

例如消费者已经获取到这个数据,并且提交了offset,但后续在对数据进行业务操作的时候挂掉了,导致数据没有成功处理,这时候kafka认为你已经成功获取了,但实际没有,就造成了数据丢失的问题。

一般情况下用手动提交的方式来解决,当数据处理成功后再提交offset。

3. 重复消费

ack=1的情况下,是有可能存在消息丢失的情况的,因为producer收到leader写入成功的通知就认为推送成功,但实际上leader副本在把消息同步到follower副本的时候失败了,这时候消息就丢失了。

为了处理这种推送失败的情况,kakfa引入了回调机制来处理,实际上就是一种重试的方式,这时候会出现因为重试机制导致消息乱序的情况。

3.1. 解决重试机制引起的消息乱序

生产者Producer

为了实现producer的幂等性,kafka引入了Producer IDSequence Number两个参数,对于每个生产者,该Producer发送的消息都对应一个单调增的Sequence Number。同样的Broker端也会为每个生产者的每条消息维护一个序号,并且每commit一条数据时就会将其序号递增。

对于接收到的数据,如果其序号比Borker维护的序号大一(即表示是下一条数据),Broker会接收它,否则将其丢弃。

如果消息序号比Broker维护的序号差值比一大,说明中间有数据尚未写入,即乱序,此时Broker拒绝该消息,Producer抛出InvalidSequenceNumber

如果消息序号小于等于Broker维护的序号,说明该消息已被保存,即为重复消息,Broker直接丢弃该消息,Producer抛出DuplicateSequenceNumber

Sender发送失败后会重试,这样可以保证每个消息都被发送到broker

消费者Consumer

同样的也是利用幂等性的原理来解决,可以给每条数据加上一个唯一标识,进行数据处理的时候校验这个标识是否存在,如果存在即为重复数据,丢弃。

Kafka经典三大问:数据有序丢失重复的更多相关文章

  1. [转帖]kafka 如何保证数据不丢失

    kafka 如何保证数据不丢失 https://www.cnblogs.com/MrRightZhao/p/11498952.html   一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数 ...

  2. kafka 如何保证数据不丢失

    一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数据不丢失,在面试中也会问到相关的问题.但凡遇到这种问题,是指3个方面的数据不丢失,即:producer consumer 端数据不丢失  b ...

  3. Kafka在高并发的情况下,如何避免消息丢失和消息重复?kafka消费怎么保证数据消费一次?数据的一致性和统一性?数据的完整性?

    1.kafka在高并发的情况下,如何避免消息丢失和消息重复? 消息丢失解决方案: 首先对kafka进行限速, 其次启用重试机制,重试间隔时间设置长一些,最后Kafka设置acks=all,即需要相应的 ...

  4. Oracle Goldengate是如何保证数据有序和确保数据不丢失的?

    工作中一直在用Oracle 的中间件Oracle GondenGate 是如何保证消息的有序和不丢失呢? Oracle GoldenGate逻辑架构 首先,先看一下Oracle GoldenGate ...

  5. Spark Streaming消费Kafka Direct方式数据零丢失实现

    使用场景 Spark Streaming实时消费kafka数据的时候,程序停止或者Kafka节点挂掉会导致数据丢失,Spark Streaming也没有设置CheckPoint(据说比较鸡肋,虽然可以 ...

  6. Spark Streaming和Kafka整合保证数据零丢失

    当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢失机制.为了体验这个关键的特性,你需要满足以下几个先决条件: 1.输入的数据来自可靠的数据源 ...

  7. Spark Streaming使用Kafka保证数据零丢失

    来自: https://community.qingcloud.com/topic/344/spark-streaming使用kafka保证数据零丢失 spark streaming从1.2开始提供了 ...

  8. Kafka如何保证数据不丢失

    Kafka如何保证数据不丢失 1.生产者数据的不丢失 kafka的ack机制:在kafka发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够被收到,其中状态有0,1,-1. 如果是 ...

  9. 160728、Spark Streaming kafka 实现数据零丢失的几种方式

    定义 问题开始之前先解释下流处理中的一些概念: At most once - 每条数据最多被处理一次(0次或1次) At least once - 每条数据最少被处理一次 (1次或更多) Exactl ...

随机推荐

  1. NPOI处理Excel

    using NPOI; using NPOI.XSSF.UserModel; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; NPOI.SS.U ...

  2. 【刷题-LeetCode】289. Game of Life

    Game of Life According to the Wikipedia's article: "The Game of Life, also known simply as Life ...

  3. 【刷题-LeetCode】210. Course Schedule II

    Course Schedule II There are a total of n courses you have to take, labeled from 0 to n-1. Some cour ...

  4. 【体验】在Adobe After Effects CC 2018中使用脚本创建窗口

    1.主界面 2.脚本编辑器主界面 3.对象浏览器 在脚本编辑器中按F1 4.写一段 ScriptUI var win = new Window('window', 'my win', [100, 10 ...

  5. Spring boot + Vue axios 文件下载

    后端代码: @GetMapping("/{sn}") @ApiOperation(value = "获取文件",notes = "获取文件" ...

  6. python中的rpc库

    基于xml的rpc调用 rpcserver.py from xmlrpc.server import SimpleXMLRPCServer # python中类的命名方式遵循驼峰命名法 # 1. 没有 ...

  7. jsp 4-14 知识总结

    二   string类型 装换 boolean 的方法? 三   attribute对象  set 和 get  的用法 四  jsp 的四种属性范围? 五  jsp  <%  %>  和 ...

  8. ApacheCN PHP 译文集 20211101 更新

    PHP 入门指南 零.序言 一.PHP 入门 二.数组和循环 三.函数和类 四.数据操作 五.构建 PHP Web 应用 六.搭建 PHP 框架 七.认证与用户管理 八.建立联系人管理系统 使用 PH ...

  9. Java IO: ByteArrayOutputStream使用

    感谢原文作者:小思思smile 原文链接:https://blog.csdn.net/u014049880/article/details/52329333/ 更多请查阅Java API文档! 在创建 ...

  10. 1、interface/implements 接口与引用

    转载请注明来源:https://www.cnblogs.com/hookjc/ 1.类中全部为抽象方法 2.抽象方法前不用加abstract 3.接口抽象方法属性为public 4.成员属性必须为常量 ...