Kafka分布式的单位是partition,同一个partition用一个write ahead log组织,所以可以保证FIFO的顺序。不同partition之间不能保证顺序。

但是绝大多数用户都可以通过message key来定义,因为同一个key的message可以保证只发送到同一个partition,比如说key是user id,table row id等等,所以同一个user或者同一个record的消息永远只会发送到同一个partition上,保证了同一个user或record的顺序。当然,如果你有key skewness 就有些麻烦,需要特殊处理


Apache Kafka官方保证了partition内部的数据有效性(追加写、offset读);为了提高Topic的并发吞吐能力,可以提高Topic的partition数,并通过设置partition的replica来保证数据高可靠;

但是在多个Partition时,不能保证Topic级别的数据有序性。

因此,如果你们就像死磕kafka,但是对数据有序性有严格要求,那我建议:

  1. 创建Topic只指定1个partition,这样的坏处就是磨灭了kafka最优秀的特性。

所以可以思考下是不是技术选型有问题, kafka本身适合与流式大数据量,要求高吞吐,对数据有序性要求不严格的场景。


原文链接:http://www.lpnote.com/2017/01/17/sequence-message-in-kafka/

顺序消息包括以下两方面:

  • 全局顺序
  • 局部顺序

全局顺序

全局顺序就目前的应用范围来讲,可以列举出来的也就限于binlog日志传输,如mysql binlog日志传输要求全局的顺序,不能有任何的乱序。这种的解决办法通常是最为保守的方式:

  1. 全局使用一个生产者
  2. 全局使用一个消费者(并严格到一个消费线程)
  3. 全局使用一个分区(当然不同的表可以使用不同的分区或者topic实现隔离与扩展)

局部顺序

其实在大部分业务场景下,只需要保证消息局部有序即可,什么是局部有序?局部有序是指在某个业务功能场景下保证消息的发送和接收顺序是一致的。如:订单场景,要求订单的创建、付款、发货、收货、完成消息在同一订单下是有序发生的,即消费者在接收消息时需要保证在接收到订单发货前一定收到了订单创建和付款消息。

针对这种场景的处理思路是:针对部分消息有序(message.key相同的message要保证消费顺序)场景,可以在producer往kafka插入数据时控制,同一key分发到同一partition上面。因为每个partition是固定分配给某个消费者线程进行消费的,所以对于在同一个分区的消息来说,是严格有序的(在kafka 0.10.x以前的版本中,kafka因消费者重启或者宕机可能会导致分区的重新分配消费,可能会导致乱序的发生,0.10.x版本进行了优化,减少重新分配的可能性)。

注意事项

消息重试对顺序消息的影响

对于一个有着先后顺序的消息A、B,正常情况下应该是A先发送完成后再发送B,但是在异常情况下,在A发送失败的情况下,B发送成功,而A由于重试机制在B发送完成之后重试发送成功了。
这时对于本身顺序为AB的消息顺序变成了BA

消息producer发送逻辑的控制

消息producer在发送消息的时候,对于同一个broker连接是存在多个未确认的消息在同时发送的,也就是存在上面场景说到的情况,虽然A和B消息是顺序的,但是由于存在未知的确认关系,有可能存在A发送失败,B发送成功,A需要重试的时候顺序关系就变成了BA。简之一句就是在发送B时A的发送状态是未知的。
针对以上的问题,严格的顺序消费还需要以下参数支持:max.in.flight.requests.per.connection
这个参数官方文档的解释是:

The maximum number of unacknowledged requests the client will send on a single connection before blocking. Note that if this setting is set to be greater than 1 and there are failed sends, there is a risk of message re-ordering due to retries (i.e., if retries are enabled).

大体意思是:

在发送阻塞前对于每个连接,正在发送但是发送状态未知的最大消息数量。如果设置大于1,那么就有可能存在有发送失败的情况下,因为重试发送导致的消息乱序问题。
所以我们应该将其设置为1,保证在后一条消息发送前,前一条的消息状态已经是可知的。

Kafka分布式的消息顺序的更多相关文章

  1. kafka——分布式的消息队列系统

    总听公司人说kafka kafka... 所以这玩意到底是个啥? 好像是一个高级版的消息队列,什么高吞吐量,数据持久,消息均衡,emmm https://blog.csdn.net/nawenqian ...

  2. Apache Kafka分布式流处理平台及大厂面试宝典v3.0.0

    概述 **本人博客网站 **IT小神 www.itxiaoshen.com 定义 Apache Kafka官网地址 http://kafka.apache.org/ 最新版本为 3.0.0 Apach ...

  3. kafka 分布式(不是单机)的情况下,如何保证消息的顺序消费?

    Kafka 分布式的单位是 partition,同一个 partition 用一个 write ahead log 组织, 所以可以保证 FIFO 的顺序.不同 partition 之间不能保证顺序. ...

  4. Kafka 分布式的,基于发布/订阅的消息系统

    Kafka是一种分布式的,基于发布/订阅的消息系统.主要设计目标如下: 通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能. 高吞吐量:即使是非常 ...

  5. Kafka——分布式消息系统

    Kafka——分布式消息系统 架构 Apache Kafka是2010年12月份开源的项目,采用scala语言编写,使用了多种效率优化机制,整体架构比较新颖(push/pull),更适合异构集群. 设 ...

  6. 【转】快速理解Kafka分布式消息队列框架

     from:http://blog.csdn.net/colorant/article/details/12081909 快速理解Kafka分布式消息队列框架 标签: kafkamessage que ...

  7. Kafka 分布式消息队列介绍

    Kafka 分布式消息队列 类似产品有JBoss.MQ 一.由Linkedln 开源,使用scala开发,有如下几个特点: (1)高吞吐 (2)分布式 (3)支持多语言客户端 (C++.Java) 二 ...

  8. 快速理解Kafka分布式消息队列框架

    作者:刘旭晖 Raymond 转载请注明出处 Email:colorant at 163.com BLOG:http://blog.csdn.net/colorant/ ==是什么 == 简单的说,K ...

  9. KAFKA分布式消息系统

    2015-01-05 大数据平台 Hadoop大数据平台 基本概念 kafka的工作方式和其他MQ基本相同,只是在一些名词命名上有些不同.为了更好的讨论,这里对这些名词做简单解释.通过这些解释应该可以 ...

随机推荐

  1. centos7删除Apache组件

    非特殊需要不要删除centos7中Apache等组件!首先查看centos中Apache版本(前面我们说了centos7删除PHP,centos7删除MariaDB,可能很多朋友会有疑问为什么要把所有 ...

  2. stm32定时器频率采样的方式

    频率采样方法通常采样定时器的计数方法,在stm32中,输入捕捉模式,PWM输入模式,都是可以测试外部信号频率采样的.1.输入捕捉模式需要频繁的进中断,这个方式不太好的.如果一定要用,那么就软件上处理一 ...

  3. connect ECONNREFUSED 127.0.0.1:80错误解决

    这个报错也是一直困扰了我许久,服务端一直打印这个报错,但是页面数据响应又都正常,起初真不知道是因为什么原因,能看出来他是在调用80端口, 但是不明白为什么会调用80端口.一度以为是config.js里 ...

  4. 第02组 团队Git现场编程实战

    目录 1. 组员职责分工(2分) 2. github 的提交日志截图(1分) 3. 程序运行截图(3分) 4. 程序运行环境(1分) 5. GUI界面(5分) 6. 基础功能实现(10分) 7. 鼓励 ...

  5. React创建组件的方法,组件的props属性、state属性的用法和特点,父子组件传值,兄弟组件传值

    创建组件的方法,组件的props属性.state属性的用法和特点,父子组件传值,兄弟组件传值 1.react组件 1.1.创建组件的方法 1.1.1.函数组件 定义一个组件最简单的方式是使用JavaS ...

  6. scp 文件 : /目录: Permission denied

    Q: A: 进入目录,用root登录,修改权限为777 再进行上传即可:

  7. 每日一问:说说你对 LeakCanary 的了解

    昨天的问题说到了关于 内存泄漏需要注意的点,在文章最后有说到 LeakCanary 检测内存泄漏.实际上,我相信绝大多数人也知道甚至使用过这个库. 这个系列通常来说如果发现了不错的资源,会选择直接截取 ...

  8. Python(三)对装饰器的理解

    装饰器是 Python 的一个重要部分,也是比较难理解和使用好的部分.下面对装饰器做一下简单整理 1. 前言 装饰器实际上是应用了设计模式里,装饰器模式的思想: 在不概念原有结构的情况下,添加新的功能 ...

  9. Gamma阶段测试报告

    测试计划 Gamma阶段依然以场景测试为主.我们归纳了三条场景主线: 一.典型用户:查看 访问排名页面 / 搜索课程 查看课程页面 查看教师页面 为他人评论点赞或点踩 二.典型用户:评论 登录网站 搜 ...

  10. Laravel自动备份到阿里云OSS

    背景 之前做备份时,主要是拿一台备份机对生产机做数据库做主备,用rsync同步上传的图片,文件.随着项目的增多,许多小项目都这样做感觉太过繁琐,每次都要在2台机器之间配置,同时单独拿一台机器做备份成本 ...