Kafka Delivery Semantics

在Kafka Consumer中,有3种delivery semantics,分别为:至多一次(at most once)、至少一次(at least once)、以及准确一次(exactly once),下面我们分别介绍这3种Delivery 语义。

1. At Most Once

在message batch在被consumer接收后,立即commit offsets。此时若是在消息处理逻辑中出现异常,则未被处理的消息会丢失(不会再次被读取)。

此场景一个例子如下图:

此例流程如下:

  1. Consumer读一个batch的消息
  2. 在接收到消息后,Consumer commits offsets
  3. Consumer 处理数据,例如发送邮件,但是此时一个batch中的最后两条消息由于consumer异常宕机而未被正常处理
  4. Consumer 重启并重新开始读数据。但是此时由于已经committed offset,所以consumer会在最新的offset处读一个batch的消息,之前上一个batch中由于异常而未被处理的消息会丢失

所以at most once 会有丢失数据的风险,但若是应用可以承受丢失数据的风险,则可以使用此方式。

2. At Least Once

在消息被consumer接收并处理后,offsets才被 commit。若是在消息处理时发生异常,则消息会被重新消费。也就是说,会导致消息被重复处理。

At Least Once 是默认使用的语义,在这种情况下,需要保证应用是idempotent 类型(处理重复的消息不会对应用产生影响)。

此场景一个例子如下:

此示例流程如下:

  1. Consumer 读一个batch的消息
  2. 在接收到消息并正常处理
  3. 在consumer 正常处理消息完毕后,commits offset
  4. 继续读并处理下一个batch 的消息。若是在此过程中发生异常(例如consumer 重启),则consumer会从最近的 offset 开始读一个batch的消息并处理。所以此时会导致有重复消息被处理(此例中为4263、4264、4265)

3. Exactly once

此语义较难实现,在kafka中仅能在Kafka => Kafka的工作流中,通过使用Kafka Stream API 实现。对于Kafka => Sink 的工作流,请使用 idempotent consumer。

对于大部分应用程序,我们应使用at least once processing,并确保consumer端的transformation/processing 是idempotent类型。

4. 构建 idempotent consumer

一个idempotent consumer可以在处理重复消息时,不影响整个应用的逻辑。在ElasticSearch 中,通过一个_id 字段唯一识别一条消息。所以在这个场景下,为了实现idempotent consumer,我们需要对同样_id字段的消息做同样的处理。

之前给出的Elastic Search Consumer的例子中,每条消息的 _id 都是默认随机生成的,也就是说:若是处理之前重复的消息,生成的id也是一条新的随机_id,此行为不符合一个idempotent consumer。对此,我们可以自定义一个­_id 模式,修改代码如下:

// poll for new data
while(true){
ConsumerRecords<String, String> records =
consumer.poll(Duration.ofMinutes(100)); for(ConsumerRecord record : records) { // construct a kafka generic ID
String kafka_generic_id = record.topic() + "_" + record.partition() + "_" + record.offset(); // where we insert data into ElasticSearch
IndexRequest indexRequest = new IndexRequest(
"kafkademo"
).id(kafka_generic_id).source(record.value(), XContentType.JSON); IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
String id = indexResponse.getId(); logger.info(id); try {
Thread.sleep(1000); // introduce a small delay
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

打印出id结果为:

可以看到新的 id 由 kafka topic + partition + offset 这3 部分组成,可以唯一定位一个 record。所以即使重复处理一条record,它发往 ElasticSearch 的 id 也是一样的(即处理逻辑一样)。在这个场景下,即为一个imdepotent consumer。

Apache Kafka(八)- Kafka Delivery Semantics for Consumers的更多相关文章

  1. Apache Kafka安全| Kafka的需求和组成部分

    1.目标 - 卡夫卡安全 今天,在这个Kafka教程中,我们将看到Apache Kafka Security 的概念  .Kafka Security教程包括我们需要安全性的原因,详细介绍加密.有了这 ...

  2. Apache ZooKeeper在Kafka中的角色 - 监控和配置

    1.目标 今天,我们将看到Zookeeper在Kafka中的角色.本文包含Kafka中需要ZooKeeper的原因.我们可以说,ZooKeeper是Apache Kafka不可分割的一部分.在了解Zo ...

  3. Message Delivery Semantics

    4.6 Message Delivery Semantics Now that we understand a little about how producers and consumers wor ...

  4. kafka实战教程(python操作kafka),kafka配置文件详解

    kafka实战教程(python操作kafka),kafka配置文件详解 应用往Kafka写数据的原因有很多:用户行为分析.日志存储.异步通信等.多样化的使用场景带来了多样化的需求:消息是否能丢失?是 ...

  5. CentOS 7部署Kafka和Kafka集群

    CentOS 7部署Kafka和Kafka集群 注意事项 需要启动多个shell脚本交互客户端进行验证,运行中的客户端不要停止. 准备工作: 安装java并设置java环境变量,在`/etc/prof ...

  6. Spark Streaming + Kafka整合(Kafka broker版本0.8.2.1+)

    这篇博客是基于Spark Streaming整合Kafka-0.8.2.1官方文档. 本文主要讲解了Spark Streaming如何从Kafka接收数据.Spark Streaming从Kafka接 ...

  7. 【Kafka】Kafka集群环境搭建

    目录 一.初始环境准备 二.下载安装包并上传解压 三.修改配置文件 四.启动ZooKeeper 五.启动Kafka集群 一.初始环境准备 必须安装了JDK和ZooKeeper,并保证Zookeeper ...

  8. Kafka(3)--kafka消息的存储及Partition副本原理

    消息的存储原理: 消息的文件存储机制: 前面我们知道了一个 topic 的多个 partition 在物理磁盘上的保存路径,那么我们再来分析日志的存储方式.通过 [root@localhost ~]# ...

  9. Kafka记录-Kafka简介与单机部署测试

    1.Kafka简介 kafka-分布式发布-订阅消息系统,开发语言-Scala,协议-仿AMQP,不支持事务,支持集群,支持负载均衡,支持zk动态扩容 2.Kafka的架构组件 1.话题(Topic) ...

随机推荐

  1. MySQL之分库分表

    MySQL之分库分表(MyCAT实现)   分库分表介绍 随着微服务这种架构的兴起,我们应用从一个完整的大的应用,切分为很多可以独立提供服务的小应用.每个应用都有独立的数据库. 数据的切分分为两种: ...

  2. Centos7 修改/etc/profile错误后导致所有命令“not found”

    因为Centos7中运行着两个版本的php,今天在设置环境变量时导致所有命令都 "not found". 修复方式: 第一:执行 /bin/vi /etc/profile 把文件修 ...

  3. BZOJ 3698: XWW的难题

    Description XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核. XWW给你出了这么一个难题:XWW给你一个N ...

  4. vjudge A^B Mod C 然后,10.6最。。。的 快速幂!!!

    链接:https://vjudge.net/contest/331993#problem/D 给出3个正整数A B C,求A^B Mod C. 例如,3 5 8,3^5 Mod 8 = 3. Inpu ...

  5. BZOJ2190 SDOI2008 仪仗队 gcd,欧拉函数

    题意:求从左下角能看到的元素个数 引理:对点(x,y),连线(0,0)-(x,y),元素个数为gcd(x,y)-1(中间元素) 即要求gcd(x,y)=1 求gcd(x,y)=1的个数 转化为2 \s ...

  6. asp.net core 发布到linux下Docker

    1.linux Docker 安装 内核升级:https://www.cnblogs.com/zksfyz/p/7919425.html 安装:   https://www.runoob.com/do ...

  7. C++ socket编程-转载

    转自:https://www.cnblogs.com/L-hq815/archive/2012/07/09/2583043.html 若有违规请联系我删除. 介绍 Socket编程让你沮丧吗?从man ...

  8. SpringBoot学习- 4、整合JWT

    SpringBoot学习足迹 1.Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于 ...

  9. spring微服务实战 - 1 一个完整的HTTP JSON REST服务

    import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.Spr ...

  10. hashlib加密模块_python

    一.hashlib模块 1.功能 主要用于字符串加密 2.常用方法 md5()/sha1():创建一个md5或者sha1加密模式的hash对象update(arg):用字符串参数来更新hash对象,如 ...