Kafka 保证消息消费全局顺序性

当有消息被生产出来的时候,如果没有指定分区或者指定 key ,那么消费会按照【轮询】的方式均匀地分配到所有可用分区中,但不一定按照分区顺序来分配


我们知道,在 Kafka 中消费者可以订阅一个或多个主题,并被分配一个或多个分区
 


如果一个消费者消费了多个分区,某些场景下消费者需要顺序地消费消息,但消息并不是按照顺序分配给分区的,所以就不一定能够保证消息消费的全局顺序性

比如下图中 Msg0002 消息并不是在 Msg0001 消息之后的,就有可能导致消费者先把 Msg0002 消息给消费, Msg0001 消息才被消费
 


那么这种情况该怎么解决?如何尽可能地保证消息消费的全局顺序性?(即这些消息具有因果关系)要想消费消息 B 必须先消费消息 A

要注意的是,Kafka 的设计目标是提供高吞吐量和低延迟,而不是强制保证全局有序性

所以这篇文章探讨的是需要强调全局顺序性场景下的 Kafka 应用

单分区

最简单粗暴的方法,虽然 Kafka 不能保证全局消费顺序性,但是能够保证分区内的消息顺序性
 


所以我们可以只创建一个分区,并让消费者消费这个分区,这样就能够保证消费的消息是有序的

但是这样做大大降低了吞吐量和处理效率,容易使得性能出现瓶颈

基于 key

在 Kafka 中,基于 key 的消息分配策略是通过消息中的键(key)来确定消息发送到哪个分区

当生产者发送消息时,可以指定一个键(key),Kafka 使用这个键通过哈希算法来确定消息被发送到哪个分区
 


由于相同的 key 就发送到同一分区,这样就能够保证了消费的消息是有序的

然而,如果只有一个消费者消费相同 key 的消息,那么与单分区相比,基于 key 的消息分配策略不会提高吞吐量

因为即使相同 key 的消息在多个分区中,但同一消费者依然只能从一个分区中消费,这并不会增加整体的处理能力。

但如果有多个消费者消费相同 key 的消息,基于 key 的分区策略可以提高消费者并行消费的能力


因为这些消费者可以同时从不同分区中读取消息,从而增加整体的处理速度。这种情况下,基于 key 的消息分配可以提高整体吞吐量

最后总结一下:

  • Kafka 的设计目标是提供高吞吐量和低延迟,而不是强制保证全局有序性,所以Kafka使用多分区的概念,并且只保证单分区有序

  • 如果想要实现消息的全局有序

    • 单分区策略:

      一个主题下只创建一个分区,一个消费者只消费一个分区,但这样做毫无并发性可言,极大降低系统性能

    • 基于 key 的消息分配策略:

      由于相同的 key 就发送到同一分区,这样就能够保证了消费的消息是有序的。然而,如果只有一个消费者消费相同 key 的消息,与前面单分区相比没有什么区别

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/238714.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

旋转立方体.html(网上收集5)

<!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>旋转立方体</title><style>#cube {width: 200px;height: 200px;position: relative;transform-style: preserve-3d;animation: rotate 6s infinite linear;mar…

记一次SQL Server磁盘突然满了导致数据库锁死事件is full due to ‘LOG_BACKUP‘.

背景 最近我们的sql server 数据库磁盘在80左右&#xff0c;需要新增磁盘空间。还是处以目前可控的范围内&#xff0c;但是昨天晚上告警是80%&#xff0c;凌晨2:56分告警是90%&#xff0c;今天早上磁盘就满了。 经过 通过阿里云后台查看&#xff0c;磁盘已经占据99%&#xff0c…

react实现加载动画

1.Spinning.tsx import "./Spinning.scss";interface Props {isLoading: boolean;children?: React.ReactNode; }const Spinning: React.FC<Props> ({isLoading true,children }) > {return <div className{spinning-wrapper${isLoading ? " l…

Java线程池底层原理

文章目录 1. 线程和现场池的对比2. ThreadPoolExecutor分析3. ThreadPoolExecutor源码详解 1. 线程和现场池的对比 下面代码创建了100000个线程 public class Main {public static void main(String[] args) throws InterruptedException {Long start System.currentTimeMilli…

【爬虫逆向分析实战】某笔登录算法分析——本地替换分析法

前言 作者最近在做一个收集粉币的项目&#xff0c;可以用来干嘛这里就不展开了&#x1f601;&#xff0c;需要进行登录换算token从而达到监控收集的作用&#xff0c;手机抓包发现他是通过APP进行计算之后再请求接口的&#xff0c;通过官网分析可能要比APP逆向方便多&#xff0…

基于hadoop下的hbase安装

简介 HBase是一个分布式的、面向列的开源数据库&#xff0c;该技术来源于Fay Chang所撰写的Google论文“Bigtable&#xff1a;一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统&#xff08;File System&#xff09;所提供的分布式数据存储一样&#xff0c;…

【参数估计】---点估计之矩估计

点估计之矩估计 &#x1f47b;什么是参数估计&#x1f47b;引例---理解参数估计&#x1f41f;点估计&#x1f36d;引例&#x1f36d;点估计问题 &#x1f41f;矩估计&#x1f36d;预备知识&#x1f36d;矩估计的求解步骤&#x1f36d;矩估计例题 &#x1f47b;什么是参数估计 在…

产品待办列表中的内容是什么?详解

产品待办列表是敏捷开发中用来跟踪所有必须完成的工作的一个清单。这个清单涵盖了从新功能的添加&#xff0c;到缺陷的修复&#xff0c;再到对现有功能的改进等等。这个列表就像产品团队的任务中心&#xff0c;上面列出了所有需要完成的工作&#xff0c;而且只有列在这个清单上…

Python 批量修改文件名

主要步骤 通过os.listdir查看该文件夹下所有的文件&#xff08;包括文件夹&#xff09;遍历所有文件&#xff0c;如果是文件夹则跳过&#xff0c;或指定跳过指定文件获取文件扩展名按照需求生成新的文件路径文件名进行重命名 代码示例 # -*- coding: utf-8 -*- import osdef…

前端面试高频考点—TCP vs UDP

目录 简介&#xff1a; 区别&#xff1a; 应用选择&#xff1a; tcp为什么需要三次握手&#xff1f; 简介&#xff1a; TCP(传输控制协议)和UDP&#xff08;用户数据报协议&#xff09; TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;是专门为了在不…

蓝桥杯算法心得——小郑躲太阳(思维推导)

大家好&#xff0c;我是晴天学长&#xff0c;一道与平时的题型截然不同的题型&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .小郑躲太阳 问题描述 小郑一觉醒来发现起晚啦!现在需要从家里飞速前往公司…

uni-app 微信小程序之自定义圆形 tabbar

文章目录 1. 自定义tabbar效果2. pages新建tabbar页面3. tabbar 页面结构4. tabbar 页面完整代码 1. 自定义tabbar效果 2. pages新建tabbar页面 首先在 pages.json 文件中&#xff0c;新建一个 tabbar 页面 "pages": [ //pages数组中第一项表示应用启动页&#xff…