解决KafKa数据存储与顺序一致性保证

kafka 发送和接收消息 消息中间件kafka 进行消息的分发和接收示例 应用中包含分通道发送和多线程接收 立即下载

 

“严格的顺序消费”有多么困难

下面就从3个方面来分析一下,对于一个消息中间件来说,”严格的顺序消费”有多么困难,或者说不可能。

发送端

发送端不能异步发送,异步发送在发送失败的情况下,就没办法保证消息顺序。

比如你连续发了1,2,3。 过了一会,返回结果1失败,2, 3成功。你把1再重新发送1遍,这个时候顺序就乱掉了。

存储端

对于存储端,要保证消息顺序,会有以下几个问题: 
(1)消息不能分区。也就是1个topic,只能有1个队列。在Kafka中,它叫做partition;在RocketMQ中,它叫做queue。 如果你有多个队列,那同1个topic的消息,会分散到多个分区里面,自然不能保证顺序。

(2)即使只有1个队列的情况下,会有第2个问题。该机器挂了之后,能否切换到其他机器?也就是高可用问题。

比如你当前的机器挂了,上面还有消息没有消费完。此时切换到其他机器,可用性保证了。但消息顺序就乱掉了。

要想保证,一方面要同步复制,不能异步复制;另1方面得保证,切机器之前,挂掉的机器上面,所有消息必须消费完了,不能有残留。很明显,这个很难!!!

接收端

对于接收端,不能并行消费,也即不能开多线程或者多个客户端消费同1个队列。

总结

从上面的分析可以看出,要保证消息的严格有序,有多么困难!

发送端和接收端的问题,还好解决一点,限制异步发送,限制并行消费。但对于存储端,机器挂了之后,切换的问题,就很难解决了。

你切换了,可能消息就会乱;你不切换,那就暂时不可用。这2者之间,就需要权衡了。

业务需要全局有序吗?

通过上面分析可以看出,要保证一个topic内部,消息严格的有序,是很困难的,或者说条件是很苛刻的。

那怎么办呢?我们一定要使出所有力气、用尽所有办法,来保证消息的严格有序吗?

这里就需要从另外一个角度去考虑这个问题:业务角度。正如在下面这篇博客中所说的: 
http://www.jianshu.com/p/453c6e7ff81c

实际情况中: 
(1)不关注顺序的业务大量存在; 
(2) 队列无序不代表消息无序。

第(2)条的意思是说:我们不保证队列的全局有序,但可以保证消息的局部有序。

举个例子:保证来自同1个order id的消息,是有序的!

下面就看一下在Kafka和RocketMQ中,分别是如何对待这个问题的:

Kafka中:发送1条消息的时候,可以指定(topic, partition, key) 3个参数。partiton和key是可选的。

如果你指定了partition,那就是所有消息发往同1个partition,就是有序的。并且在消费端,Kafka保证,1个partition只能被1个consumer消费。

或者你指定key(比如order id),具有同1个key的所有消息,会发往同1个partition。也是有序的。

RocketMQ: RocketMQ在Kafka的基础上,把这个限制更放宽了一步。只指定(topic, key),不指定具体发往哪个队列。也就是说,它更加不希望业务方,非要去要一个全局的严格有序。

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

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

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

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

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

    2. 在Producer往Kafka插入数据时,控制同一Key分发到同一Partition,并且设置参数max.in.flight.requests.per.connection=1,也即同一个链接只能发送一条消息,如此便可严格保证Kafka消息的顺序
 

    3. 通过key, 一般会hash(某一属性)为key,来做若干个分组,这样只需在分组内严格有序即可,不牺牲并发性能。

再谈谈数据一致性保证:

一致性定义:若某条消息对client可见,那么即使Leader挂了,在新Leader上数据依然可以被读到
HW-HighWaterMark: client可以从Leader读到的最大msg offset,即对外可见的最大offset, HW=max(replica.offset)
对于Leader新收到的msg,client不能立刻消费,Leader会等待该消息被所有ISR中的replica同步后,更新HW,此时该消息才能被client消费,这样就保证了如果Leader fail,该消息仍然可以从新选举的Leader中获取。
对于来自内部Broker的读取请求,没有HW的限制。同时,Follower也会维护一份自己的HW,Folloer.HW = min(Leader.HW, Follower.offset)


数据存储
Topic
一类消息称为一个Topic

 

Topic逻辑结构
Topic可分为多个Parition;
Parition内部保证数据的有序,按照消息写入顺序给每个消息赋予一个递增的offset;
为保证数据的安全性,每个Partition有多个Replica

 

多Parition的优点
并发读写,加快读写速度
多Partition分布式存储,利于集群数据的均衡
加快数据恢复的速率:当某台机器挂了,每个Topic仅需恢复一部分的数据,多机器并发

缺点
Partition间Msg无序,若想保证Msg写入与读取的序不变,只能申请一个Partition

Partition


Partition存储结构
每个Partition分为多个Segment
每个Segment包含两个文件:log文件和index文件,分别命名为start_offset.log和start_offset.index
log文件包含具体的msg数据,每条msg会有一个递增的offset
Index文件是对log文件的索引:每隔一定大小的块,索引msg在该segment中的相对offset和在log文件中的位置偏移量


根据offset查找msg的过程
根据msg的offset和log文件名中的start_offset,找到最后一个不大于msgoffset的segment,即为msg所在的segment;
根据对应segment的index文件,进一步查找msg在log文件中的偏移量
从log文件的偏移量开始读取解析msg,比较msgoffset,找到所要读取的msg

 

Partition recovery过程
每个Partition会在磁盘记录一个RecoveryPoint, 记录已经flush到磁盘的最大offset。当broker fail 重启时,会进行loadLogs。首先会读取该Partition的RecoveryPoint,找到包含RecoveryPoint的segment及以后的segment, 这些segment就是可能没有完全flush到磁盘segments。然后调用segment的recover,重新读取各个segment的msg,并重建索引
优点
以segment为单位管理Partition数据,方便数据生命周期的管理,删除过期数据简单
在程序崩溃重启时,加快recovery速度,只需恢复未完全flush到磁盘的segment
通过命名中offset信息和index文件,大大加快msg查找时间,并且通过分多个Segment,每个index文件很小,查找速度更快

数据的同步


数据流
Partition的多个replica中一个为Leader,其余为follower
Producer只与Leader交互,把数据写入到Leader中
Followers从Leader中拉取数据进行数据同步
Consumer只从Leader拉取数据

 

ISR:所有不落后的replica集合, 不落后有两层含义:距离上次FetchRequest的时间不大于某一个值或落后的消息数不大于某一个值,Leader失败后会从ISR中选取一个Follower做Leader

数据可靠性保证
当Producer向Leader发送数据时,可以通过acks参数设置数据可靠性的级别
0: 不论写入是否成功,server不需要给Producer发送Response,如果发生异常,server会终止连接,触发Producer更新meta数据;
1: Leader写入成功后即发送Response,此种情况如果Leader fail,会丢失数据
-1: 等待所有ISR接收到消息后再给Producer发送Response,这是最强保证

仅设置acks=-1也不能保证数据不丢失,当Isr列表中只有Leader时,同样有可能造成数据丢失。要保证数据不丢除了设置acks=-1, 还要保证ISR的大小大于等于2,具体参数设置:
request.required.acks:设置为-1 等待所有ISR列表中的Replica接收到消息后采算写成功;
min.insync.replicas: 设置为大于等于2,保证ISR中至少有两个Replica

Producer要在吞吐率和数据可靠性之间做一个权衡
数据一致性保证
一致性定义:若某条消息对client可见,那么即使Leader挂了,在新Leader上数据依然可以被读到
HW-HighWaterMark: client可以从Leader读到的最大msg offset,即对外可见的最大offset, HW=max(replica.offset)
对于Leader新收到的msg,client不能立刻消费,Leader会等待该消息被所有ISR中的replica同步后,更新HW,此时该消息才能被client消费,这样就保证了如果Leader fail,该消息仍然可以从新选举的Leader中获取。

对于来自内部Broker的读取请求,没有HW的限制。同时,Follower也会维护一份自己的HW,Folloer.HW = min(Leader.HW, Follower.offset)
HDFS数据组织


与Kafka有几点明显不同:
数据分块,比如以64M为一个数据块;
流水线复制:每个数据块没有Leader和Follower之分,采用流水线的方式进行数据复制;
就近读取:为了减少读取时的网路IO,采用就近读取,加快读取速率

Linux下基于AHCI controller模块实现SATA Platform驱动附代码详细流程 本文主要是针对ARM A55集成了AHSATA controller模块开发sata驱动,通过Platform的形式在linux识别到SSD,本文详细讲述整个开发过程,同时对SATA Platform驱动进行讲解。1、配置SATA Phy的初始化;2、打开SATA Platform相关编译开关;3、配置设备树;4、linux启动识盘。 阅读详情

相关推荐

Innovus ECO技巧:用setEcoMode+ecoAddRepeater实现批量buffer替换的5个关键步骤

本文详细介绍了在Cadence Innovus工具中,利用setEcoMode与ecoAddRepeater命令实现高效、批量Buffer/Inverter替换的工程化策略。通过启用批处理模式、构建可维护的替换规则、掌握高级定位技巧以及规避布线陷阱等5个关键步骤,帮助芯片设计工程师在ECO阶段大幅提升修改效率与质量,确保设计稳定签核。

d6e7f8的博客 1120

kafka学习笔记2

1、kafka分布式的情况下如何保证消息的顺序性 kafka并不适用对数据时序性要求严格的场景 Kafka的做法是提供消息队列,让生产者单往队列的末尾添加数据,让多个消费者从队列里面依次读取数据然后自行处理 【生产】kafka的分布式单位是partition。同一个partition内的数据可以保证时序。不同partition之间无法保证消息的顺序性。可以设置producer生产messag...

cclucc的博客 726

benders分解算法 逻辑思路整理(加星)

一般我们经常可以看到的是经典的benders,此处我也结合经典的benders梳理下思路。

sinat_41348401的博客 7990

kafka 如何保证对应类型的消息被写到相同的分区?

然后使用 offset 对主题分区进行取模,为消息选取分区,这样就可以保证包含同一个键的消息会被写到同一个分区上。(非加密型 Hash 函数,具备高运算性能及低碰撞率)来计算分区分配。如果 ProducerRecord 没有指定分区,且消息的。没有指定分区,且消息的。的方式选择一个分区。

xljlckjolksl的博客 746

从零到一:手把手教你用C# WinForms搭建工控上位机(含Panel控件布局与事件处理详解)

本文详细介绍了如何使用C# WinForms框架从零开始搭建工控上位机系统,重点讲解了Panel控件的布局技巧和事件处理机制。通过实战案例,帮助开发者掌握界面分区规划、动态窗体切换及数据通信等核心功能,适用于工业自动化监控系统的开发。

weixin_30321709的博客 611

Mac电脑用Latex论文排版3天速成5天实战de笔记

我后悔了,这五天竞赛搞得我视力都下降了...一个冲动的决定后成为数模竞赛论文写手,3天速成+5天时间=点亮攻克latex写论文技能💡关于Overleaf我是Mac,曾经按照大部分推荐的方式用TEXshop+vs code,但是把模板导入就开始报错。跟着少之又少的适配mac的教程(此时我已知道大概是走错路了)改了配置也无效。海鲜市场找佬改了半天,佬问我:一定要用VC吗?我说,那倒也不是。于是佬推荐我overleaf,三下五除二帮我挑配了环境,美汁汁收了我30块钱。

luwanjoyce的博客 2252

什么是消息键(Key)?如何使用消息键进行消息顺序性保证?

需要注意的是,Kafka仅保证相同键的消息被分配到同一个分区,但不保证分区之间的顺序。因此,在某些特定情况下,当消息的严格顺序对您的应用程序很重要时,您需要使用只有一个分区的主题来保证严格的顺序性。这样可以确保消费者只消费自己感兴趣的键的消息,并保证了消费者消费消息的顺序。这样,相同键的消息将被放置在同一个分区,从而保证了相同键的消息在分区中的顺序。通过上述机制,Kafka可以保证具有相同键的消息在同一个分区中,并且消费者只消费自己感兴趣的键的消息,从而实现了消息的顺序性保证。

wzxue1984的博客 2929

ChatGPT高效制作PPT:从内容生成到设计优化全流程

人工智能技术正在改变传统办公文档的创作方式,其中自然语言处理(NLP)与生成式AI的结合为内容创作带来了革命性突破。以ChatGPT为代表的大语言模型(LLM)能够理解复杂指令并生成结构化内容,其核心原理是通过海量数据训练获得的语义理解和文本生成能力。在办公自动化场景中,这种技术特别适合解决PPT制作中的两大痛点:内容创作耗时和逻辑架构困难。通过精心设计的提示词工程,AI可以快速输出包含核心要点、数据支撑的完整内容框架,甚至直接生成Markdown格式的代码以便快速转换为PPT。对于商业计划、项目汇报等高频

weixin_42613018的博客 494

阻塞队列被异步消费怎么保持顺序

当阻塞队列中开始有任务要处理的时候,这些被阻塞的消费者线程会严格按照 FIFO 的顺序来唤醒,从而保证了消费的顺序型。其次,在阻塞队列里面,使用了 condition 条件等待来维护了两个等待队列(如图),一个是队列为空的时候存储被阻塞的消费者,第一种,就是阻塞队列里面已经包含了很多任务,这个时候启动多个消费者去消费的时候,它的有序性保证是通过加锁来实现的,也就是每个消费者线程去阻塞队列获取任务的时候 必须要先获得排他锁。并且存储在等待队列里面的线程,都符合 FIFO 的特性。

qq_63431773的博客 431

一步到位解决Docker拉取镜像失败的问题!超详细的Docker代理设置教程!(使用代理解决群晖Docker获取注册表失败的问题)

一步到位解决Docker拉取镜像失败的问题!超详细的Docker代理设置教程!(使用代理解决群晖Docker获取注册表失败的问题)

XiaoqiangClub的博客 1万+

本地 AI 自由!OpenClaw+Ollama 双系统部署教程(Windows/Linux),零成本离线跑大模型

本文详细介绍了如何在Windows和Linux双系统中部署OpenClaw AI助手,并通过Ollama对接本地大模型实现完全离线使用。教程包含环境准备、OpenClaw安装配置、Ollama本地模型部署、系统对接等完整流程,特别强调隐私安全和零Token消耗的优势。针对不同操作系统提供具体命令,并给出常见问题解决方案,即使是新手也能快速搭建专属本地AI助手。最终实现的方案无需联网、无使用成本,且能保障数据隐私安全。

2501_93651177的博客 7231

头条二面Kafka面经总结:搞懂Kafka的这个问题,你离大厂就不远了!!(建议收藏)

有些读者去头条二面,被面试官问了一个关于Kafka的问题:多个Kafka消费者如何同时消费相同Topic下的相同Partition的数据?看似一个简单的问题,竟然把这位读者问懵了!今天,我们一起来分析下这道面试题!

冰河的专栏 5740

【部署】Ubuntu 24.04.4虚拟机下部署OpenClaw

OpenClaw是一款基于AI的智能助手工具,本文详细介绍了在Ubuntu 24.04.4系统上的三种安装方法。推荐使用一键安装脚本(curl -fsSL https://openclaw.ai/install.sh | bash),自动完成Node.js检测、CLI安装和引导配置。对于开发者,提供了从源码构建的详细步骤,包括环境准备、依赖安装和构建流程。文章还包含常见问题解决方案(如sharp构建错误处理)以及后续维护建议(更新、配置检查和日志查看)。安装完成后,用户可通过终端TUI或Web UI进行初始

海兰 1万+

kafka的消费顺序_解决KafKa数据存储与顺序一致性保证

“严格的顺序消费”有多么困难下面就从3个方面来分析一下,对于一个消息中间件来说,”严格的顺序消费”有多么困难,或者说不可能。发送端发送端不能异步发送,异步发送在发送失败的情况下,就没办法保证消息顺序。比如你连续发了1,2,3。 过了一会,返回结果1失败,2, 3成功。你把1再重新发送1遍,这个时候顺序就乱掉了。存储端对于存储端,要保证消息顺序,会有以下几个问题:(1)消息不能分区。也就是1个top...

weixin_39615643的博客 619

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

kafka如何保证顺序消费?

使用synchronized进行加锁的话,会影响无关联的insert和update的数据消费能力,如id=1的insert和id=2的update,在synchronized的情况下,无法并发处理,这是没有必要的,我们需要的是对于id=1的insert和id=1的update在同一时间只有一个在处理,所以使用细粒度锁来完成加锁的操作。现有Topic-insert和Topic-update,数据唯一标识为id,对于id=1的数据而言,要保证Topic-insert消费在前,Topic-update消费在后。

一蓑烟雨任平生 1348

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

KafKa数据存储与数据一致性保证

tianjinsong2016-10-31 21:03:136141收藏 展开 http://yonghuiyang.github.io/2015/12/04/kafka_data_store/ 数据存储 Topic 一类消息称为一个Topic转存失败重新上传取消 Topic逻辑结构 Topic可分为多个Parition; Parition内部保证数据的有...

大JAVA解决方案 434

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Kafka 顺序消费方案

Kafka 顺序消费方案前言1、问题引入2、解决思路3、实现方案 前言     本文针对解决Kafka不同Topic之间存在一定的数据关联时的顺序消费问题。如存在Topic-insert和Topic-update分别是对数据的插入和更新,当insert和update操作为同一数据时,应保证先insert再update。 1、问题引入   ...

qq_38245668的博客 6015

kafka19-顺序写机制如何保证高速写入

Kafka 利用顺序写的策略,通过将消息批量追加到分区的末尾,并最终以大块数据的形式顺序写入磁盘,以实现高效的写入性能和吞吐量。这种方式有效地利用了现代操作系统和硬件的优化能力,使得 Kafka 能够处理大规模的数据流而不牺牲性能和可靠性。

m0_63833709的博客 2057

kafka数据一致性保证

数据一致性保证 一致性定义:若某条消息对client可见,那么即使Leader挂了,在新Leader上数据依然可以被读到 HW-HighWaterMark: client可以从Leader读到的最大msg offset,即对外可见的最大offset, HW=max(replica.offset) 对于Leader新收到的msg,client不能立刻消费,Leader会等待该消息被所有ISR中的replica同步后,更新HW,此时该消息才能被client消费,这样就保证了如果Leader fail,该消息仍然

weixin_37627646的博客 244

Kafka 学习笔记之 数据存储与高效读写

前言 ​ 上一篇笔记中概述了一下什么是消息队列以及 kafka 的组织架构,这篇笔记就来整理一下 kafka 是如何存储数据,以及其怎么保证了大数据场景下的高效读写,文中如有错误与纰漏欢迎指正,共同进步! kafka 数据存储结构 topic 与 partition ​ 在 kafka 的架构中有讲到作为基于订阅/发布模式的消息队列 kafka 的所有操作都是面向 topic 的,而为了水平扩展的弹性和增大吞吐量在 kafka 中又可以将一个 topic 分成多个 partition 分布在不同的机

an_vana的博客 534

##[一致性]KafKa数据存储与数据一致性保证

转自——KafKa数据存储与数据一致性保证 - tianjinsong的专栏 - 博客频道 - youkuaiyun.com http://blog.youkuaiyun.com/bluetjs/article/details/52986652数据一致性保证一致性定义:若某条消息对client可见,那么即使Leader挂了,在新Leader上数据依然可以被读到HW-HighWaterMark: client可以从Lea...

Orange_NanLu的博客 1175

Kafka:高吞吐量、消息精确一次语义以及保证消息顺序

文章目录前言高吞吐量顺序读写Page Cache零拷贝分区分段+索引批量读写批量压缩消息精确一次语义消息系统语义概述必须被处理的故障Apache Kafka 中的精确一次语义幂等性:每个分区中精确一次且有序事务:跨分区原子写入真实案例:Apache Kafka 中的精确一次流处理保证消息顺序 前言 Kafka 是最初由 Linkedin 公司开发,是一个分布式、支持分区的、多副本的,基于 Zookeeper 协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于 Hado

安正勋的博客 3716

Kafka 数据存储Topic和Partition

对于Kafka 数据的存储,我们最经常听到的两个概念就是Topic和Partition了,下面就简单介绍下他们在Kafka系统中的意思和作用。 Topic Topic是Kafka中消息的逻辑分类,每个Topic可有多个Partition Partition Partition是Kafka中实际的数据存储单元,每个Partition可以看做一个可以被订阅和消费的消息队列。每个Topic的pa...

Rocky的技术博客 1442

Kafka 面试大全,(总结)

原文链接:干货总结!Kafka 面试大全(万字长文,37 张图,28 个知识点) 大家好 周末用了整整两天时间,整理了一下Kafka面试的连环问题,保证你看完后,对 Kafka 有了更深层次的了解。 全文总结的Kafka题目之间的 关联性 很强,本文将通过问答 + 图解的形式 由浅入深 帮助大家进一步学习和理解 Kafka 分布式流式处理平台。 全文总计1.2 万字、28 个知识点。35 张原理、流程图。提纲如下: 此文已经制作成带目录的 PDF,获取本文PDF 版...

CCqwas的博客 1万+
上一篇: KafkaConsumer使用介绍、参数配置
下一篇: ps 命令查看进程下的线程及线程状态
王树民
博客等级 码龄10年 912粉丝 560原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值