这个问题严格来说是肯定有的,kafka只能保证分区内的有序性。
下面是kafka作者Jay Kreps的blog中介绍kafka设计思想的一段话。
Each partition is a totally ordered log, but there is no global ordering between partitions (other than perhaps some wall-clock time you might include in your messages). The assignment of the messages to a particular partition is controllable by the writer, with most users choosing to partition by some kind of key (e.g. user id). Partitioning allows log appends to occur without co-ordination between shards and allows the throughput of the system to scale linearly with the Kafka cluster size.
针对部分消息有序(message.key相同的message要保证消费顺序)场景,可以在producer往kafka插入数据时控制,同一key分发到同一partition上面。
kafka源码如下,支持该方式
private[kafka]classDefaultPartitioner[T]extendsPartitioner[T]{ privateval random = newjava.util.Random def partition(key: T, numPartitions: Int): Int = { if(key== null){ println("key is null") random.nextInt(numPartitions) } else{ println("key is "+ key + " hashcode is "+key.hashCode) math.abs(key.hashCode) % numPartitions } } }
在kafka-storm中,如果one partition -> one consumer instance 的话,就没这样的问题,但失去了并行。
如果N1 partitions -> N2 consumer instances的话 ,
1)N1<N2,这种情况会造成部分consumer空转,资源浪费。
2)N1>N2(N2>1),这种情况,每个kafka-spout实例会消费固定的1个或者几个partition,msg不会被不同consumer重复消费。
3)N1=N2,这种情况,实际操作发现,1个consumer instance都对应消费1个partition。1个partition只会有1个consumer实例,否则需要加锁等操作,这样减少了消费控制的复杂性。
具体应用场景:
计算用户在某个位置的滞留时间,日志内容可以抽象成用户ID、时间点、位置。
应用系统-》日志文件sftp服务器-》数据采集层-》kafka-》storm实时数据清洗处理层-》Redis、Hbase-》定时任务、mapreduce
在集成测试期间,由于没有实际的日志,所以在采集层模拟往kafka插入数据(特别在发送频率模拟的很粗糙),发现在实时处理层,计算出来用户在某个位置滞留时间计算出来为负数,原因如下,
1)采集层模拟不真实(同一用户往kafka插入的位置的时间是随机生成),但要考虑目前的日志文件sftp服务器 或者 采集层 是否会有这种情况,如果有,可以从业务层面规避,过滤掉该条无效数据。
2)就是storm中tuple处理失败,重发,kafka-storm中就使offset回到失败的那个位置,但之前位置信息可能已经缓存到了redis(为了减少hbase访问次数,用户的最近一条位置信息放在了redis中),这样offset之后的所有消息会重新被消费,这样以来滞留时间为负数,可以过滤掉该条记录,不存到redis中。
真实数据:U1 T1 A1->U1 T2 A2
fail重发 :U1 T1 A1->U1 T2 A2 -> 前两条都失败,重发 -> U1 T1 A1(负数的滞留时间) -> U1 T2 A2
由于采用的是失败重发,是at least once,如果是only once的话,就会没有这样的情况,
PS:一些原理性问题,可以参考“kafka消费原理”介绍。
相关推荐
springboot2.x整合kafka,发送者包含自定义分区发送,发送之后的回调函数,消费者有两个监听,一个是批量消费多topic,另外一个是消费指定topic的不同分区
kafka管理工具,主要用于创建、删除、查看管理topic信息
springboot集成kafka实战项目代码 项目介绍地址:https://blog.csdn.net/qq_38105536/article/details/122308040
SpringBoot整合kafka代码,两个工程 一个消费者 一个生产者,利用定时任务和restapi发送消息,自动分配分区消费和指定分区消费,再也不用写死分区了真好。代码简洁。欢迎大家下载。
当kafka中的某一个topic数据量很大的时候就会导致消费者处理数据很慢,那我们可能会想着适当的增加分区(partition)来提高消费者的消费速度,那么我们创建多个分区的时候,生产者是如何分配生产的消息到分区的尼,让我...
kafka指定分区消费,发送到指定分区
能力申请提交成功后,自动根据标识ID创建对应Kafka的Topic。 设计思路: 1、在Java代码中调用ZooKeeper的工具类,创建Topic。 2、建立一个含有Topic属性的JavaBean,set内容到各个属性中。 3、Id的规则尚不明确,...
消费者可以并行地从多个分区读取消息,提高了处理大量数据的效率。此外,消费者还可以自动处理偏移量,以便在出现问题时能够重新开始消费。 这两个工具的优点在于它们提供了一种可靠且高效的方式来处理和传输大规模...
自动位移提交在正常情况下不会发生消息丢失或重复消费的现象,唯一可能的情况,你拉取到消息后,消费者那边刚好进行了位移提交,Kafka那边以为你已经消费了这条消息,其实你刚开始准备对这条消息进行业务处理,但你...
kafka脚本实现自动化无损热迁移topic。不用停kafka进程,不影响写入。在迁移过程中业务无感知。
Flink 无法获取 Kafka Topic Metadata 异常及解决 一、问题现象 在使用 Kafka 0.11.0.1 和 Flink 1.4 进行实时计算时,Flink 无法获取 Kafka Topic Metadata,报以下异常:org.apache.kafka.common.errors....
grafana上kafka 测试消费者组消费情况使用的json文件
Kafka分区策略浅谈,Kafka分区策略浅谈,Kafka分区策略浅谈。
KafkaMiddleWare利用kafka开发的一个中间件,其可以根据配置创建topic,向指定的topic中发送消息以及消费消息。其可打包供生产端和消费端调用。使用方式:首先按DataQualityMessage类生产数据,然后可按照测试文件中...
消息topic分区:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。 消息顺序的保证:在每个partition内部,消息是按照发送...
所以在实际产环境中,个Topic会设置成多分区的模式,来持多个消费者,参照下图:在互联企业的实际产环境中,Topic数量和分区都会较多,这就要求消息中间件在多T
Kafka Producer机制优化-提高发送消息可靠性
使用netty实现TCP长链接消息写入kafka以及kafka批量消费数据,数据可以批量进行操作
kafka多线程顺序消费
java -jar kafka-topic-exporter-0.0.6-jar-with-dependencies.jar config/kafka-topic-exporter.properties 配置 启动过程时,必须将配置文件作为参数传递。 ## Kafka Exporter Properties # ...