消息队列之 MetaQ 和 Kafka 哪个更香!(2)

简介: 消息队列之 MetaQ 和 Kafka 哪个更香!

Kafka和MetaQ之对比


Kafka和MetaQ存储机制


Kafka存储机制

Kafka和MetaQ一样,都是采用topic作为发布和订阅的主题,topic是个逻辑概念,而partition是物理上面的概念,每个partition对应一个log文件,该log文件中存储的就是producer生产的数据。producer生产的数据会被不断追加到log文件的末端,且每条数据都有自己的offset。

每个Partition都会有自己的副本,Kafka会尽量的使所有的分区均匀的分布到集群中的所有节点而不是集中在某些节点上,另外主从关系也尽量均衡这样每个几点都会担任一定比例的分区的leader。

image.png

每个partition以目录的形式存储在broker上,该目录底下存储着的是该partition内容被平均分配成的多个大小相等的数据文件,我们称之为segment(段)。每个segment文件分为两个部分,index file和data file,此两个文件一一对应,后缀".index"和".log"分别表示segment的索引文件和数据文件。文件的命名规则为partition全局的第一个segment为0开始,后续每个segment文件名为上一个全局partion的最大offset(偏移message数)。每个segment中存储很多条消息,消息id由其逻辑位置决定,即从消息id可直接定位到消息的存储位置,避免id到位置的额外映射。

segment index file采取稀疏索引存储方式,它减少索引文件大小,通过mmap可以直接内存操作,稀疏索引为数据文件的每个对应message设置一个元数据指针,先通过index文件中获取该message的一个位置范围,然后根据这个位置范围在log文件中找到该message的信息。

      image.png

MetaQ存储机制

MetaQ的消息存储方式和kafka的partition存放方式类似,在MetaQ中消息的存放分为物理队列和逻辑队列。

物理队列:物理队列我们一般用commitlog来表示,在一个broker上面,所有发到broker上的信息都会按顺序写入物理队列中,物理队列又由许多文件组成,当一个文件被写满(默认大小为1G)时,则创建一个新的文件继续写入,文件以offset的方式来命名,与kafka中的partition命名类似。

逻辑队列:逻辑队列我们一般用consumequeue来表示,在消息被写入物理队列之后,如果消费端想从broker拉取消息,就需要一个索引文件,MetaQ中将每个Topic分为了几个区,每个区对应了一个消费队列,不过这些消费队列只是由一个个索引文件组成。消费端在拉取消息的时候,只要知道自己订阅的Topic从nameserver获取broker地址建立连接之后,就能根据消费队列中的索引文件,去物理队列中获取订阅的消息。

CommitLog以物理文件的方式存放,每台Broker上的CommitLog被本机器上所有的ConsumeQueue共享。在CommitLog中,一个消息的存储长度是不固定的,MetaQ中采取了一些机制,尽量往CommitLog中顺序写,但是可以支持随机读。ConsumeQueue的内容也会被写到磁盘里进行持久存储,但是ConsumeQueue的内容是通过异步刷盘的方式进行。

image.png

为什么MetaQ需要采用这种存储架构呢?

我们知道,磁盘的顺序写比随机写的速度快的很多,目前的高性能磁盘,顺序写的速度可以达到600MB/s,超过了一般的网卡的传输速度,但是磁盘的随机写的速度只有大概100KB/s,和顺序写的性能相差了6000倍,而MetaQ正是利用磁盘顺序写的优势来设计的。

上文说到,MetaQ的主要存储文件包括CommitLog、ConsumeQueue文件,在一个Broker节点上,MetaQ会将所有Topic的消息存储在同一个文件commitlog中,这样能确保producer发送的消息顺序写入commitlog中,能够尽最大的能力确保消息发送的高性能和高吞吐量,接收消息的时候,只有CommitLog是需要同步落盘的。同时使用ConsumeQueue消息队列文件来作为索引文件,每个Topic包含有多个消息消费队列,每一个消息队列就有一个ConsumeQueue消息文件,ConsumeQueue是异步保存的,不需要同步落盘,如果在没有落盘的时候,broker发生宕机,MetaQ可以根据CommitLog来恢复ConsumeQueue。

虽然说在同一个broker上面由于不同的ConsumeQueue访问同一个CommitLog,CommitLog是进行随机读的,但是根据操作系统的局部性原理,也利用操作系统的分页机制,可以批量的从磁盘中获取CommitLog的信息,然后缓存到内存中,更快的进行读取。而对于ConsumeQueue,由于其内部只保存数据的索引信息,所以一般其数据量不大,可以全部读入内存,所以我们可以认为从ConsumeQueue这个中间结构获取数据很快,可以当成从内存读取数据的速度。

在kafka中,当如果一个broker上面有多个partition,如果多个partition并发写入数据,磁盘的访问会有很大的瓶颈,多个文件之间必然会有磁盘的寻道。而MetaQ对于数据来说就只有单文件写入,性能上将优于kafka。

MetaQ为什么不像Kafka使用zk作为元数据节点,而要使用自己实现的NameServer?

我们知道,kafka使用zk作为元数据节点,起到了Broker注册、Topic注册、生产者和消费者负载均衡以及使用zk进行leader角色的选举,当leader所在的broker挂了,将会经过以下两步操作重新选举leader:第1步,先通过Zookeeper在所有机器中,选举出一个KafkaController;第2步,再由这个Controller,决定每个partition的Master是谁,Slave是谁。因为有了选举功能,所以kafka某个partition的master挂了,该partition对应的某个slave会升级为主对外提供服务。        

image.png

MetaQ不具备选举,Master/Slave的角色也是固定的。当一个Master挂了之后,你可以写到其他Master上,但不能让一个Slave切换成Master。那么MetaQ是如何实现高可用的呢,其实很简单,MetaQ的所有broker节点的角色都是一样,上面分配的topic和对应的queue的数量也是一样的,MetaQ只能保证当一个broker挂了,把原本写到这个broker的请求迁移到其他broker上面,而并不是这个broker对应的slave升级为主。        

image.png

引入zk的主要目的是为了选主,kafka中如果一个broker挂了,这个broker上面的主partition可以通过zk的选举机制在其他broker上面选举主partition,而对于MateQ而言,在部署的时候已经决定了这个Broker是主或者是备了(一个Master可以对接多个Slave,但是一个Slave只能对接一个Master,Master与Slave之间可以通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,不为0的表示Slave),不能再通过选举变成主(认命吧,无法上位的),所以对于MetaQ,是不需要进行选举的,为了方便集群维护,直接使用NameServer这一个轻量级工具来存储元数据信息即可。

目录
相关文章
|
12天前
|
消息中间件 Java Kafka
初识Apache Kafka:搭建你的第一个消息队列系统
【10月更文挑战第24天】在数字化转型的浪潮中,数据成为了企业决策的关键因素之一。而高效的数据处理能力,则成为了企业在竞争中脱颖而出的重要武器。在这个背景下,消息队列作为连接不同系统和服务的桥梁,其重要性日益凸显。Apache Kafka 是一款开源的消息队列系统,以其高吞吐量、可扩展性和持久性等特点受到了广泛欢迎。作为一名技术爱好者,我对 Apache Kafka 产生了浓厚的兴趣,并决定亲手搭建一套属于自己的消息队列系统。
30 2
初识Apache Kafka:搭建你的第一个消息队列系统
|
16天前
|
消息中间件 中间件 Kafka
解锁Kafka等消息队列中间件的测试之道
在这个数字化时代,分布式系统和消息队列中间件(如Kafka、RabbitMQ)已成为日常工作的核心组件。本次公开课由前字节跳动资深专家KK老师主讲,深入解析消息队列的基本原理、架构及测试要点,涵盖功能、性能、可靠性、安全性和兼容性测试,并探讨其主要应用场景,如应用解耦、异步处理和限流削峰。课程最后设有互动答疑环节,助你全面掌握消息队列的测试方法。
19 0
|
3月前
|
图形学 人工智能 C#
从零起步,到亲手实现:一步步教你用Unity引擎搭建出令人惊叹的3D游戏世界,绝不错过的初学者友好型超详细指南 ——兼探索游戏设计奥秘与实践编程技巧的完美结合之旅
【8月更文挑战第31天】本文介绍如何使用Unity引擎从零开始创建简单的3D游戏世界,涵盖游戏对象创建、物理模拟、用户输入处理及动画效果。Unity是一款强大的跨平台游戏开发工具,支持多种编程语言,具有直观编辑器和丰富文档。文章指导读者创建新项目、添加立方体对象、编写移动脚本,并引入基础动画,帮助初学者快速掌握Unity开发核心概念,迈出游戏制作的第一步。
152 1
|
3月前
|
消息中间件 传感器 缓存
为什么Kafka能秒杀众多消息队列?揭秘它背后的五大性能神器,让你秒懂Kafka的极速之道!
【8月更文挑战第24天】Apache Kafka作为分布式流处理平台的领先者,凭借其出色的性能和扩展能力广受好评。本文通过案例分析,深入探讨Kafka实现高性能的关键因素:分区与并行处理显著提升吞吐量;批量发送结合压缩算法减少网络I/O次数及数据量;顺序写盘与页缓存机制提高写入效率;Zero-Copy技术降低CPU消耗;集群扩展与负载均衡确保系统稳定性和可靠性。这些机制共同作用,使Kafka能够在处理大规模数据流时表现出色。
61 3
|
3月前
|
消息中间件 存储 Kafka
ZooKeeper助力Kafka:掌握这四大作用,让你的消息队列系统稳如老狗!
【8月更文挑战第24天】Kafka是一款高性能的分布式消息队列系统,其稳定运行很大程度上依赖于ZooKeeper提供的分布式协调服务。ZooKeeper在Kafka中承担了四大关键职责:集群管理(Broker的注册与选举)、主题与分区管理、领导者选举机制以及消费者组管理。通过具体的代码示例展示了这些功能的具体实现方式。
88 2
|
25天前
|
消息中间件 存储 运维
为什么说Kafka还不是完美的实时数据通道
【10月更文挑战第19天】Kafka 虽然作为数据通道被广泛应用,但在实时性、数据一致性、性能及管理方面存在局限。数据延迟受消息堆积和分区再平衡影响;数据一致性难以达到恰好一次;性能瓶颈在于网络和磁盘I/O;管理复杂性涉及集群配置与版本升级。
|
1月前
|
消息中间件 Java Kafka
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
42 1
|
3月前
|
消息中间件 Java Kafka
Kafka不重复消费的终极秘籍!解锁幂等性、偏移量、去重神器,让你的数据流稳如老狗,告别数据混乱时代!
【8月更文挑战第24天】Apache Kafka作为一款领先的分布式流处理平台,凭借其卓越的高吞吐量与低延迟特性,在大数据处理领域中占据重要地位。然而,在利用Kafka进行数据处理时,如何有效避免重复消费成为众多开发者关注的焦点。本文深入探讨了Kafka中可能出现重复消费的原因,并提出了四种实用的解决方案:利用消息偏移量手动控制消费进度;启用幂等性生产者确保消息不被重复发送;在消费者端实施去重机制;以及借助Kafka的事务支持实现精确的一次性处理。通过这些方法,开发者可根据不同的应用场景灵活选择最适合的策略,从而保障数据处理的准确性和一致性。
239 9
|
3月前
|
消息中间件 负载均衡 Java
"Kafka核心机制揭秘:深入探索Producer的高效数据发布策略与Java实战应用"
【8月更文挑战第10天】Apache Kafka作为顶级分布式流处理平台,其Producer组件是数据高效发布的引擎。Producer遵循高吞吐、低延迟等设计原则,采用分批发送、异步处理及数据压缩等技术提升性能。它支持按消息键值分区,确保数据有序并实现负载均衡;提供多种确认机制保证可靠性;具备失败重试功能确保消息最终送达。Java示例展示了基本配置与消息发送流程,体现了Producer的强大与灵活性。
65 3
|
3月前
|
vr&ar 图形学 开发者
步入未来科技前沿:全方位解读Unity在VR/AR开发中的应用技巧,带你轻松打造震撼人心的沉浸式虚拟现实与增强现实体验——附详细示例代码与实战指南
【8月更文挑战第31天】虚拟现实(VR)和增强现实(AR)技术正深刻改变生活,从教育、娱乐到医疗、工业,应用广泛。Unity作为强大的游戏开发引擎,适用于构建高质量的VR/AR应用,支持Oculus Rift、HTC Vive、Microsoft HoloLens、ARKit和ARCore等平台。本文将介绍如何使用Unity创建沉浸式虚拟体验,包括设置项目、添加相机、处理用户输入等,并通过具体示例代码展示实现过程。无论是完全沉浸式的VR体验,还是将数字内容叠加到现实世界的AR应用,Unity均提供了所需的一切工具。
126 0
下一篇
无影云桌面