零拷贝(java+netty+kafka+RocketMQ)

本文深入探讨了零拷贝技术在Java、Netty、RocketMQ和Kafka等系统中的应用,详细介绍了CompositeChannelBuffer如何通过组合多个ChannelBuffer实现零拷贝,以及RocketMQ和Kafka如何利用mmap和sendfile实现高效数据传输。
摘要由CSDN通过智能技术生成

Java零拷贝

1.MappedByteBuffer + 2.DirectByteBuffer+3.Channel-to-Channel传输

Netty零拷贝

netty提供了零拷贝的buffer,在传输数据时,最终处理的数据会需要对单个传输的报文,进行组合和拆分,Nio原生的ByteBuffer无法做到,netty通过提供的Composite(组合)和Slice(拆分)两种buffer来实现零拷贝;看下面一张图会比较清晰:

关于零拷贝的一点认识

 

TCP层HTTP报文被分成了两个ChannelBuffer,这两个Buffer对我们上层的逻辑(HTTP处理)是没有意义的。 但是两个ChannelBuffer被组合起来,就成为了一个有意义的HTTP报文,这个报文对应的ChannelBuffer,才是能称之为”Message”的东西,这里用到了一个词”Virtual Buffer”。

可以看一下netty提供的CompositeChannelBuffer源码:

public class CompositeChannelBuffer extends AbstractChannelBuffer {
 private final ByteOrder order;
 private ChannelBuffer[] components;
 private int[] indices;
 private int lastAccessedComponentId;
 private final boolean gathering;
 
 public byte getByte(int index) {
 int componentId = componentId(index);
 return components[componentId].getByte(index - indices[componentId]);
 }
 ...省略...

components用来保存的就是所有接收到的buffer,indices记录每个buffer的起始位置,lastAccessedComponentId记录上一次访问的ComponentId;CompositeChannelBuffer并不会开辟新的内存并直接复制所有ChannelBuffer内容,而是直接保存了所有ChannelBuffer的引用,并在子ChannelBuffer里进行读写,实现了零拷贝。

其他零拷贝

RocketMQ的消息采用顺序写到commitlog文件,然后利用consume queue文件作为索引;RocketMQ采用零拷贝mmap+write的方式来回应Consumer的请求;

同样kafka中存在大量的网络数据持久化到磁盘和磁盘文件通过网络发送的过程,kafka使用了sendfile零拷贝方式;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值