1.定义

  • 精确一次消费(Exactly-once) 是指消息一定会被处理且只会被处理一次。不多不少就一次处理。

如果达不到精确一次消费,可能会达到另外两种情况:

  • 至少一次消费(at least once),主要是保证数据不会丢失,但有可能存在数据重复问题。

  • 最多一次消费 (at most once),主要是保证数据不会重复,但有可能存在数据丢失问题。

如果同时解决了数据丢失和数据重复的问题,那么就实现了精确一次消费的语义了。

2. 问题如何产生

数据何时会丢失: 比如实时计算任务进行计算,到数据结果存盘之前,进程崩溃,假设在进程崩溃前kafka调整了偏移量,那么kafka就会认为数据已经被处理过,即使进程重启,kafka也会从新的偏移量开始,所以之前没有保存的数据就被丢失掉了。

数据何时会重复: 如果数据计算结果已经存盘了,在kafka调整偏移量之前,进程崩溃,那么kafka会认为数据没有被消费,进程重启,会重新从旧的偏移量开始,那么数据就会被2次消费,又会被存盘,数据就被存了2遍,造成数据重复。

3.解决方案

方案一:利用关系型数据库的事务进行处理

出现丢失或者重复的问题,核心就是偏移量的提交与数据的保存,不是原子性的。如果能做成要么数据保存和偏移量都成功,要么两个失败。那么就不会出现丢失或者重复了。

这样的话可以把存数据和偏移量放到一个事务里。这样就做到前面的成功,如果后面做失败了,就回滚前面那么就达成了原子性。

问题与限制

  1. 数据库选型受限, 只能使用支持事务的关系型数据库 ,如mysql, oracle ,无法使用其他功能强大的nosql数据库。

  2. 如果保存的数据量较大一个数据库节点不够,多个节点的话,还要考虑分布式事务的问题。做分布式事务,结构复杂,拖慢性能。

  3. 如果做本地事务 ,只能把分区数据提取到driver中进行保存,降低并发 ,增加executor到driver的数据传递io。

方案二:手动提交偏移量+幂等性处理

咱们知道如果能够同时解决数据丢失和数据重复问题,就等于做到了精确一次消费。

那咱们就各个击破。

首先解决数据丢失问题,办法就是要等数据保存成功后再提交偏移量,所以就必须手工来控制偏移量的提交时机。

但是如果数据保存了,没等偏移量提交进程挂了,数据会被重复消费。怎么办?那就要把数据的保存做成幂等性保存。即同一批数据反复保存多次,数据不会翻倍,保存一次和保存一百次的效果是一样的。如果能做到这个,就达到了幂等性保存,就不用担心数据会重复了。

难点

话虽如此,在实际的开发中手动提交偏移量其实不难,难的是幂等性的保存,有的时候并不一定能保证。所以有的时候只能优先保证的数据不丢失。数据重复难以避免。即只保证了至少一次消费的语义。

文章来源:https://blog.csdn.net/wangsl754/article/details/107479977?

Spark消费Kafka如何实现精准一次性消费?的更多相关文章

  1. 17-Flink消费Kafka写入Mysql

    戳更多文章: 1-Flink入门 2-本地环境搭建&构建第一个Flink应用 3-DataSet API 4-DataSteam API 5-集群部署 6-分布式缓存 7-重启策略 8-Fli ...

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

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

  3. spark streaming - kafka updateStateByKey 统计用户消费金额

    场景 餐厅老板想要统计每个用户来他的店里总共消费了多少金额,我们可以使用updateStateByKey来实现 从kafka接收用户消费json数据,统计每分钟用户的消费情况,并且统计所有时间所有用户 ...

  4. Spark streaming消费Kafka的正确姿势

    前言 在游戏项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark streaming从kafka中不 ...

  5. 本机spark 消费kafka失败(无法连接)

    本机spark 消费kafka失败(无法连接) 终端也不报错 就特么不消费:  但是用console的consumer  却可以 经过各种改版本 ,测试配置,最后发现 只要注释掉 kafka 配置se ...

  6. spark streaming从指定offset处消费Kafka数据

    spark streaming从指定offset处消费Kafka数据 -- : 770人阅读 评论() 收藏 举报 分类: spark() 原文地址:http://blog.csdn.net/high ...

  7. Spark Streaming消费Kafka Direct保存offset到Redis,实现数据零丢失和exactly once

    一.概述 上次写这篇文章文章的时候,Spark还是1.x,kafka还是0.8x版本,转眼间spark到了2.x,kafka也到了2.x,存储offset的方式也发生了改变,笔者根据上篇文章和网上文章 ...

  8. spark streaming 消费 kafka入门采坑解决过程

    kafka 服务相关的命令 # 开启kafka的服务器bin/kafka-server-start.sh -daemon config/server.properties &# 创建topic ...

  9. Spark Steaming消费kafka数据条数变少问题

    对于基于Receiver 形式,我们可以通过配置 spark.streaming.receiver.maxRate 参数来限制每个 receiver 每秒最大可以接收的记录的数据:对于 Direct ...

随机推荐

  1. java.io.NotSerializableException:异常解决

    创建的pojo类未实现Serializable接口,启动服务器会报此异常. 解决此问题 添加一个Serializable接口即可 1 import java.io.Serializable; 2 3 ...

  2. Guava - 字符串处理

    Joiner 连接 比如,有这样一个集合[1,2,3,4,5,7,null],想把这个集合转换成以#分割的字符串,并过滤掉集合中的空元素 List<Integer> eleList = A ...

  3. POJ3268-最短路径-反向存边

    因为是单向边,牛儿来回的路径长度并不相同,所以需要用两次dijkstra,一次正向从x开始dijkstra,再将边全部反向存再来一次. 因为是板子题比较良心n比较小,我们就可以用矩阵来存储啦.如果n比 ...

  4. 关于hashcode和equals方法说明

    一.前言 我们都知道,要比较两个对象是否相等时需要调用对象的equals()方法,即判断对象引用所指向的对象地址是否相等,对象地址相等时,那么与对象相关的对象句柄.对象头.对象实例数据.对象类型数据等 ...

  5. SAML 2.0 流程分析(2)

  6. javascript中“==”,“===”和“Object.is(a,b)”的区别

    作为两个量比较的三种方式"==","==="和"Object.is(a,b)"有一定区别,如下(具体见MDN): (1)Object.is( ...

  7. mysql中的with rollup得到group by的汇总信息

    使用mysql中的with rollup可以得到每个分组的汇总级别的数据: 表如下: CREATE TABLE `test3` (  `id` int(5) unsigned NOT NULL AUT ...

  8. 还不了解一下 Java 8 Predicate 函数接口

    同学你好,这里有一份你的未读代码,等你查收. 这篇文章属于 Java 8 教程(LTS)系列教程,点击阅读更多相关文章. Predicate 函数接口同之前介绍的 Function 接口一样,是一个函 ...

  9. ABC165C题解

    题目 看题目的时候一脸懵,直到看见数据范围 \[N \le 10,\; M \le 10,\; Q \le 50 \] 之后才意识到问题的严重性. 毕竟数据如此的小,我们完全可以用阶乘复杂度算法卡过去 ...

  10. Java面向对象01——什么是面向对象

    面向过程&面向对象 面向过程思想(微观): 步骤清晰简单,第一步做什么,第二部做什么....... 面向过程适合处理一些较为简单的问题 面向对象思想(宏观): 物以类聚,分类的思维模式,思考问 ...