当前位置: 首页 > 知识库问答 >
问题:

Kafka多重划分排序

寿子轩
2023-03-14

我知道在Kafka中不可能对多个分区进行排序,并且分区排序只能保证组内的单个使用者(对于单个分区)。然而,用Kafka流0.10现在有可能实现这一点吗?如果我们使用时间戳特性,使每个分区中的每个消息都保持顺序,那么在消费者端,假设使用Kafka Streams0.10,这现在是可能的吗?假设我们收到了所有的消息,我们是否可以根据消耗的时间戳对所有的分区进行排序,并可能将它们转发到一个单独的主题以供使用呢?

有什么想法吗?谢谢你。

共有1个答案

颜思淼
2023-03-14

你在这样的情况下面临两个问题:

  1. 具有多个分区的Kafka主题,而Kafka不保证这种多分区主题的全局排序。
  2. 主题及其分区的消息延迟到达/顺序混乱的可能性,这与时间和时间戳有关。

我知道在Kafka中不可能对多个分区进行排序,并且分区排序只能保证组内的单个使用者(对于单个分区)。然而,用Kafaka流0.10现在有可能实现这一点吗?

简短的回答是:不,当你从有多个分区的Kafaka主题中阅读时,仍然不可能实现全局秩序。

此外,“分区排序”意味着“基于分区中消息的偏移量的分区排序”。订购保证与消息的时间戳无关。

最后,只有max.in.flight.requests.per.connection==1才保证排序:

Apache Kafka文档中的生产者配置设置:max.in.flight.requests.per.connection(默认值:5):在阻止之前,客户端将在单个连接上发送的未确认请求的最大数量。注意,如果将此设置设置为大于1,并且存在失败的发送,则存在由于重试而重新排序消息的风险(即,如果启用了重试)。

注意,在这一点上,我们讨论的是消费者行为(这也是你最初的问题开始的)和Kafaka中的生产者行为的结合。

如果我们使用时间戳特性,使每个分区中的每个消息都保持顺序,那么在消费者端,假设使用Kafka Streams0.10,这现在是可能的吗?

即使使用了时间戳特性,我们仍然不能实现“每个分区中的每个消息都保持顺序”。为什么?因为可能会出现晚到/乱序的消息。

分区按偏移量排序,但不能保证按时间戳排序。分区的以下内容在实践中是完全可能的(时间戳通常为milliseconds-sund-the-epoch):

Partition offsets     0    1    2    3    4    5    6    7    8
Timestamps            15   16   16   17   15   18   18   19   17
                                          ^^
                                         oops, late-arriving data!

什么是迟到/乱序消息?想象一下你有分散在世界各地的传感器,所有这些传感器都测量它们当地的温度,并将最新的测量结果发送到一个Kafaka主题上。一些传感器可能具有不可靠的Internet连接,因此它们的测量结果可能会延迟几分钟、几小时甚至几天到达。最终,他们被推迟的测量结果会到达Kafaka,但他们会“迟到”。城市里的手机也是一样:有些手机可能会耗尽电池/能量,需要充电才能发送数据;有些手机可能会因为你在地下开车而失去网络连接,等等。

假设我们收到了所有的消息,我们是否可以根据消耗的时间戳对所有的分区进行排序,并可能将它们转发到一个单独的主题以供使用呢?

理论上是的,但实际上很难做到。“我们接收所有消息”的假设对于流式系统(甚至对于批处理系统也是如此,尽管在这里通常会忽略数据延迟到达的问题)实际上是具有挑战性的。你永远不知道你是否真的收到了“所有的消息”--因为可能会有迟来的数据。如果你收到一条迟到的短信,你希望发生什么?重新处理/重新排序“所有”消息(现在包括迟到的消息),还是忽略迟到的消息(从而计算不正确的结果)?从某种意义上说,通过“让我们全部排序”实现的任何这样的全局排序要么是非常昂贵的,要么是最大的努力。

 类似资料:
  • 我想知道这是否可能,所以假设我有一个这样的模型: 现在,我还为当前用户设置了一个时区,如下所示: 存储在数据库中的时区总是以UTC格式存储(以确保一切是一致的),输出的日期应该始终格式化为特定的时区(但每个用户的时区不同),例如User1的America/Chicago和User2的America/Denver。 是否有一种方法可以在输出之前自动将每个Carbon实例的时区格式化为给定的时区,或者

  • 我有一个关于火警分类的问题。

  • 想要从使用的Spring启动应用程序的不同集群上创建同质。 即想要为已经定义的类创建一个 Kafka Consumer 对象,该对象侦听动态定义的多个集群。 例如:假设一个Spring启动应用程序S,其中包含kafkaconsumer的

  • 谢谢你抽出时间。 通过在每个分区上使用数据进行泛洪测试,完成读取需要。 再次使用parallelism_hint=1的代码 即 其中, parallelism_hint-是应该分配给执行此spout的任务数。每个任务将在集群周围某个进程的线程上运行。

  • 2019-05-17T10:40:32,380[MyID:]-INFO[Controller-Event-Thread:Logging$Class@70]-[PrefredReplicApartitionLeaderSelector]:分区[主题,9]的当前领导者-1不是首选副本。触发首选副本领导者选举 2019-05-17T10:40:32,380[MyID:]-警告[Controller-Ev

  • 问题是Spring Kafka侦听器只配置了主题名。 我似乎可以让Kafka产生100个消费者来处理来自“队列”(日志)的消息。怎么能做到呢?