分布式场景下Kafka消息顺序性的思考
如果业务中,对于kafka发送消息异步消费的场景,在业务上需要实现在消费时实现顺序消费, 利用kafka在partition内消息有序的特点,消息消费时的有序性。
1、在发送消息时,通过指定partition hash
2、consumer 消费消息时,需要使用亲缘性线程池进行消费,才能实现消息的基本有序。否则即使通过发送时指定partition,在消费端由于线程池的异步消费,消息之间的处理都是并发进行的,消息就会被打乱。
上面的方式基本可以实现消息的消费顺序性,除了在极端场景下,比如:
1、进程A 在T0时刻发送一个消息A
2、进程B在T1时刻发送了一个消息B。
由于T1>T0,并且进程A和进程B发送消息都是同一个hash partition,消息理论上在partition内消息A是在消息B前被消费的。但假如进程A和进程B出于不同的机房等原因,导致在发送消息时进程A的消息由于网络原因,要比进程B更晚发送成功,那么就会导致消息B是在消息A之前。
多集群模式下
由于kafka的有序性,只是在单集群的单partition内是有效的,所以当多集群模式下,各个集群之间的消息就不满足了有序的条件。虽然由于每个集群都是使用相同的配置,都映射同一个consumer进程消费,如下:

但是由于cluster-1-partition-5和cluster-2-partition-5两个partition之间的是不同的partition,所以没有办法做到绝对有序。
同时由于conusmer-1会出现跨机房消费的多个集群的情况,所以原本在单集群模式下,由于网络耗时而导致的消息先后顺序,在多集群情况下就会增大。目前跨集群消费延迟在2-10ms之间,所以在实际业务处理中遇到了消息A比消息B早发送,在消息B先到达的场景。
io瓶颈
由于需要在consume端实现顺序消费,需要使用亲缘性线程池以确保同一个sku在同一个线程中消费消息。这种方式当某个sku的消息量特别大时,那么就会阻塞了io线程,导致其他消息也出现大量延迟。目前默认io线程拉取消息按broker来的,应该是等同于broker数量。虽然可以增加io线程数来减缓这个情况,但依然会存在这个场景。
总结
在分布式场景下要实现消息消费强顺序性需要付出很大的成本,并且需要做到绝对顺序十分困难。如果可以容忍这个消费的无序性,那么往往就不需要用到顺序消费了。
以上分析为实际应用中遇到的坑,仅供参考,欢迎拍砖。
ps:
业务进程在发送kafka消息后,会有一个linger时间,等待linger时间之后再发送,
来源:站长资讯平台
分布式场景下Kafka消息顺序性的思考的更多相关文章
- 面试官:如何在分布式场景下生成全局唯一 ID?
在分布式系统中,有一些场景需要使用全局唯一 ID ,可以和业务场景有关,比如支付流水号,也可以和业务场景无关,比如分库分表后需要有一个全局唯一 ID,或者用作事务版本号.分布式链路追踪等等,好的全局唯 ...
- 【转】MySQL乐观锁在分布式场景下的实践
背景 在电商购物的场景下,当我们点击购物时,后端服务就会对相应的商品进行减库存操作.在单实例部署的情况,我们可以简单地使用JVM提供的锁机制对减库存操作进行加锁,防止多个用户同时点击购买后导致的库存不 ...
- MySQL乐观锁在分布式场景下的实践
背景 在电商购物的场景下,当我们点击购物时,后端服务就会对相应的商品进行减库存操作.在单实例部署的情况,我们可以简单地使用JVM提供的锁机制对减库存操作进行加锁,防止多个用户同时点击购买后导致的库存不 ...
- 难道主键除了自增就是GUID?支持k8s等分布式场景下的id生成器了解下
背景 主键(Primary Key),用于唯一标识表中的每一条数据.所以,一个合格的主键的最基本要求应该是唯一性. 那怎么保证唯一呢?相信绝大部分开发者在刚入行的时候选择的都是数据库的自增id,因为这 ...
- 【融云分析】如何实现分布式场景下唯一 ID 生成?
◀背景▶ 对于一套分布式部署的 IM 系统,要求每条消息的 ID 要保证在集群中全局唯一且按生成时间有序排列.如何快速高效的生成消息数据的唯一 ID ,是影响系统吞吐量的关键因素.那么,融云是如何做到 ...
- Kafka分布式的消息顺序
Kafka分布式的单位是partition,同一个partition用一个write ahead log组织,所以可以保证FIFO的顺序.不同partition之间不能保证顺序. 但是绝大多数用户都可 ...
- RabbitMQ保证消息的顺序性
当我们的系统中引入了MQ之后,不得不考虑的一个问题是如何保证消息的顺序性,这是一个至关重要的事情,如果顺序错乱了,就会导致数据的不一致. 比如:业务场景是这样的:我们需要根据mysql的b ...
- Pulsar の 保证消息的顺序性、幂等性和可靠性
原文链接:Pulsar の 保证消息的顺序性.幂等性和可靠性 一.背景 前面两篇文章,已经介绍了关于Pulsar消费者的详细使用和自研的Pulsar组件. 接下来,将简单分析如何保证消息的顺序性.幂等 ...
- Kafka消息系统基础知识索引
一些观念的修正 从 0.9 版本开始,Kafka 的标语已经从“一个高吞吐量,分布式的消息系统”改为"一个分布式流平台". Kafka不仅仅是一个队列,而且是一个存储,有超强的堆积 ...
随机推荐
- Swift 协议protocol
// associatedtype 关键字 用来声明一个类型的占位符作为协议定义的一部分 protocol LXFViewModelType { associatedtype Input associ ...
- truncate table (tablename )表明
Truncate是SQL中的一个删除数据表内容的语句,用法是: 语法 TRUNCATE TABLE name 参数 name 是要截断的表的名称或要删除其全部行的表的名称. 下面是对Truncate语 ...
- crontab 实现Linux系统上定时任务的关键命令
附上原文链接 https://www.cnblogs.com/ftl1012/p/crontab.html 原文真是写得非常好,所谓他山之石可以攻玉~,我就不客气啦,哈哈
- Docker Python 例子
版权所有,未经许可,禁止转载 章节 Docker 介绍 Docker 和虚拟机的区别 Docker 安装 Docker Hub Docker 镜像(image) Docker 容器(container ...
- 【Android】家庭记账本手机版开发报告一
一.说在前面 昨天 学习了数据库的一些简单操作 今天 使用数据库,完成对记账本的账单记录的增删 问题 没有 二.数据库 1.账单表的结构 (注 id:账单的唯一标识,uid:记录账单的用户的id,co ...
- jQuery文档加载事件
$(document).ready(handler) $().ready(handler) (this is not recommended) $(handler) 相当于: $(document). ...
- PHP常用的数学函数和字符串函数
PHP常用函数总结 数学函数 1.abs(): 求绝对值 $abs = abs(-4.2); //4.2 数字绝对值数字 2.ceil(): 进一法取整 echo ceil(9.999); // 10 ...
- C++ STD Gems04
count.count_if.all_of.any_of.none_of #include <iostream> #include <vector> #include < ...
- gogs 小团队使用
最近小团队开始使用 gogs 来保存手头的项目.具体的使用流程如下: 由 root 用户新建 organization, 比如说建立 hardware,然后把团队的 技术负责人拉到 owners 这个 ...
- FTP和HTTP
一.字面上来看 HTTP是Hyper Text Transfer Protocol,超文本传输协议: FTP是File Transfer Protocol,文件传输协议: 简单说HTTP是面向网页的, ...