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

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

MetaQ和kafka的消息读写方式

零拷贝

我们知道,我们在写数据的时候并不是直接写入到磁盘中去的,而是写入到pageCache中去的,pageCache的主要作用是减少磁盘的I/O操作。

在磁盘写入的时候会写入到pageCache中去的,然后pageCache中可以将一些小的写入合并成一个大的写入,再进行异步刷盘。当然我们也可以使用fsync进行强制刷盘,强制刷盘会影响写入性能。一般为了保证消息的可靠性,我们是会采用多副本来存储消息,而不是采用同步刷盘。

读取消息的时候如果在pageCache中有命中则直接返回,如果在pageCache中无法命中则会产生缺页中断,需要从磁盘中加载数据到缓存中,然后返回数据。并且根据局部性原理,在读数据的时候也会进行预读,把该也相邻的磁盘快读入到页缓存中去。

mmap

由于我们读取数据的时候,需要将数据从磁盘拷贝到pageCache中,但是由于pageCache属于内核空间,用户空间无法访问,所以还需要将数据从内核空间拷贝到用户空间。        

image.png

所以数据需要两次拷贝应用程序才能够访问的到,我们可以通过mmap来减少数据从内核态到用户态的拷贝。通过将程序虚拟页面映射到页缓存中,这样就不需要将数据从内核态拷贝到用户态,也可以避免产生重复数据。也不必要再通过调用read和write方法对文件进行读写,而是通过映射地址和偏移量来直接操作pageCache。      

image.png      

sendfile

下面我们来看下常规的发送文件的过程中,从磁盘读取消息到发送文件的过程是怎么样的。

image.png

DMA Copy是指不需要CPU接入,可以直接读写系统内存,类似显卡、网卡和磁盘都是用到DMA,然而像上下文切换的话就需要有CPU接入。

下面我们看看如果采用mmap发送文件之后的流程是怎么样的。

image.png

可以看到上下文切换的次数没有变化,但是数据少拷贝了一份,这个和我们上面说到的mmap所能够达到的效果是一样的。

               image.png


上图中,sendfile采用一次系统调用就完成了发送数据的需求,相比于read+write或者说mmap+writ来

说上下文切换次数变少了,但是数据还是有冗余的。在linux2.4中采用 sendfile+带[分散-收集]DMA。真正实现了无冗余的功能。

image.png

上面就是我们说的零拷贝,在Java中是通过FileChannal.transferTo()调用的,底层是通过sendfile实现。

MetaQ和kafka的读写对比

目前kafka支持sendfile的消息读写方式,MetaQ支持mmap的消息读写方式,另外MetaQ还支持sendfile的消息写方式。

image.png

默认情况下,MetaQ不论是在CommitLog或者ComsumerQueue中都是采用mmap来实现消息读写的。在发送消息的时候,通常情况下会将数据拷贝到堆内存中去,然后再塞到响应体中进行发送。当然我们也可以通过参数配置不经过堆,通过mapedBuffer直接发送到SocketBuffer。

当消费消息的时候,严格来说对于CommitLog的读取是随机的,因为CommitLog的消息是混合进行存储的,但是从整体上面来看,消息还是会从CommitLog上顺序读取的,先读取旧数据,然后再读取新数据。消息存进去之后很快就会被消费,这个时候消息还是存放在pageCache中的,所以我们是不需要读取磁盘的。

image.png

同时pageCache会定时刷盘,但是刷盘的时机是不可控制的,所以会出现swap等现象。mmap也只是做了映射,如果真正去取数据的时候不在内存中,也会产生缺页中断,需要加载数据到内存中,这个时候也会有一些延时。MetaQ采用文件预分配和文件预热来解决pageCache的不确定性。

kafka的消息写入对于单分区来说是顺序写入的,由上文可知,kafka是有.index索引文件和.log数据文件构成的。其中.index索引文件是采用mmap进行读写的,这对于本地读写索引文件则可以提高读取效率,而.log数据文件则采用sendfile的零拷贝进行实现的。对于消息的写入来说,采用mmap其实并没有什么用,因为消息都是从网络中获取的,采用sendfile来发送消息比mmap+write更能提高效率,因为在内存中少了一个SocketBuffer的拷贝。

另外通过网上研究测试表明,如果读取的数据小于4kb的时候,使用mmap的性能效率比sendfile高,当读取数据大于4kb的时候,sendfile的效率比mmap高;对于写数据,如果写入的数据包小于64kb的时候,mmap的性能效率比sendfile高,当写入数据包大于64kb的时候sendfile的效率比mmap高。

由于kafka主要是用于日志传输,处理海量数据,对于数据的正确度要求不是很高,并且在发送消息的时候一般会进行消息的汇聚,然后批量发送消息,所以整体上来说kafka的读写数据量会比较大,这个时候使用sendfile能够获取更高的性能,而MetaQ主要是用来针对阿里的复杂应用场景,对于数据的可靠性、数据的实时性要求会比较高,由于对数据的实时性要求较高,一般不会进行汇聚批量发送消息,所以读写数据量不会很大,这个时候使用mmap可以获得更好的性能,当如果发现写入的数据量比较大时,也可以切换为sendfile进行写入。

目录
相关文章
|
4月前
|
消息中间件 人工智能 Kafka
AI 时代的数据通道:云消息队列 Kafka 的演进与实践
云消息队列 Kafka 版通过在架构创新、性能优化与生态融合等方面的突破性进展,为企业构建实时数据驱动的应用提供了坚实支撑,持续赋能客户业务创新。
503 45
|
5月前
|
消息中间件 Java Kafka
消息队列比较:Spring 微服务中的 Kafka 与 RabbitMQ
本文深入解析了 Kafka 和 RabbitMQ 两大主流消息队列在 Spring 微服务中的应用与对比。内容涵盖消息队列的基本原理、Kafka 与 RabbitMQ 的核心概念、各自优势及典型用例,并结合 Spring 生态的集成方式,帮助开发者根据实际需求选择合适的消息中间件,提升系统解耦、可扩展性与可靠性。
355 1
消息队列比较:Spring 微服务中的 Kafka 与 RabbitMQ
|
消息中间件 Java Kafka
初识Apache Kafka:搭建你的第一个消息队列系统
【10月更文挑战第24天】在数字化转型的浪潮中,数据成为了企业决策的关键因素之一。而高效的数据处理能力,则成为了企业在竞争中脱颖而出的重要武器。在这个背景下,消息队列作为连接不同系统和服务的桥梁,其重要性日益凸显。Apache Kafka 是一款开源的消息队列系统,以其高吞吐量、可扩展性和持久性等特点受到了广泛欢迎。作为一名技术爱好者,我对 Apache Kafka 产生了浓厚的兴趣,并决定亲手搭建一套属于自己的消息队列系统。
356 2
初识Apache Kafka:搭建你的第一个消息队列系统
|
消息中间件 存储 负载均衡
2024消息队列“四大天王”:Rabbit、Rocket、Kafka、Pulsar巅峰对决
本文对比了 RabbitMQ、RocketMQ、Kafka 和 Pulsar 四种消息队列系统,涵盖架构、性能、可用性和适用场景。RabbitMQ 以灵活路由和可靠性著称;RocketMQ 支持高可用和顺序消息;Kafka 专为高吞吐量和低延迟设计;Pulsar 提供多租户支持和高可扩展性。性能方面,吞吐量从高到低依次为
5305 1
|
消息中间件 中间件 Kafka
解锁Kafka等消息队列中间件的测试之道
在这个数字化时代,分布式系统和消息队列中间件(如Kafka、RabbitMQ)已成为日常工作的核心组件。本次公开课由前字节跳动资深专家KK老师主讲,深入解析消息队列的基本原理、架构及测试要点,涵盖功能、性能、可靠性、安全性和兼容性测试,并探讨其主要应用场景,如应用解耦、异步处理和限流削峰。课程最后设有互动答疑环节,助你全面掌握消息队列的测试方法。
|
消息中间件 存储 缓存
kafka 的数据是放在磁盘上还是内存上,为什么速度会快?
Kafka的数据存储机制通过将数据同时写入磁盘和内存,确保高吞吐量与持久性。其日志文件按主题和分区组织,使用预写日志(WAL)保证数据持久性,并借助操作系统的页缓存加速读取。Kafka采用顺序I/O、零拷贝技术和批量处理优化性能,支持分区分段以实现并行处理。示例代码展示了如何使用KafkaProducer发送消息。
|
消息中间件 存储 运维
为什么说Kafka还不是完美的实时数据通道
【10月更文挑战第19天】Kafka 虽然作为数据通道被广泛应用,但在实时性、数据一致性、性能及管理方面存在局限。数据延迟受消息堆积和分区再平衡影响;数据一致性难以达到恰好一次;性能瓶颈在于网络和磁盘I/O;管理复杂性涉及集群配置与版本升级。
512 1
|
消息中间件 Java Kafka
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
405 1
|
消息中间件 Java Kafka
Kafka不重复消费的终极秘籍!解锁幂等性、偏移量、去重神器,让你的数据流稳如老狗,告别数据混乱时代!
【8月更文挑战第24天】Apache Kafka作为一款领先的分布式流处理平台,凭借其卓越的高吞吐量与低延迟特性,在大数据处理领域中占据重要地位。然而,在利用Kafka进行数据处理时,如何有效避免重复消费成为众多开发者关注的焦点。本文深入探讨了Kafka中可能出现重复消费的原因,并提出了四种实用的解决方案:利用消息偏移量手动控制消费进度;启用幂等性生产者确保消息不被重复发送;在消费者端实施去重机制;以及借助Kafka的事务支持实现精确的一次性处理。通过这些方法,开发者可根据不同的应用场景灵活选择最适合的策略,从而保障数据处理的准确性和一致性。
1418 9
|
消息中间件 监控 Kafka
实时计算 Flink版产品使用问题之处理Kafka数据顺序时,怎么确保事件的顺序性
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。