RabbitMQ、RocketMQ、Kafka性能对比分析 您所在的位置:网站首页 怎么把百度网盘映射到本地文件 RabbitMQ、RocketMQ、Kafka性能对比分析

RabbitMQ、RocketMQ、Kafka性能对比分析

2023-05-02 07:44| 来源: 网络整理| 查看: 265

而这种方式只是一次拷贝,因为是内存映射。map方法在系统启动的时候就被调用了。

传统的方式,每次都要new一个FileInputStream,这里涉及到了2次拷贝(每一次读取出来,读到buffer中,涉及到2次拷贝:一次DMA拷贝、一次CPU拷贝),耗时202毫秒,因为要发送网络,通过连接本机的8081端口,发送给它,还要创建一个对应的输出流拿取结果。

传统的方式本质上和文件读取是一样的,这是通过流的方式读取,while true不断的读并且累加,读完之后,拿到了buffer,再写网络,网络就通过socket创建的getOutputStream(文件的输出流、socket的输出流)转到DataOutputStream。

创建的socket就是一个连接,应用要跟消费者建立一个TCP的连接,这个TCP的连接在底层表示都是socket,不单单只是数据连接,还包含了数据通道,这里new一个socket就相当于跟另外一个消费者8081这样的socket通道建立了链接,通过socket通道里面的dataOutputStream.write方法输出数据,这里又会涉及到一次DMA拷贝,一次CPU拷贝。

首先做一次CPU拷贝,相当于把buffer的数据首先要发到套接字缓冲区(socket里面的缓冲区),这个socket要通过网卡发给消费者最终要把应用内存发送给网卡里面的内存,网卡是一个外设,网卡通过一个USB都可以去接,所以就需要做一个DMA拷贝。

这种方式共有4次拷贝,耗时为422毫秒,这是RabbitMQ的情况,而RocketMQ的mmap发送只有204毫秒,DMA拷贝速度一般是CPU的百倍。

 

Kafka不会涉及到cpu拷贝,只是进行文件描述符的传递,这点消耗的时间可以忽略。

文件描述符类似一个指针,在linux上面所有东西都是文件描述符。

把数据放到文件数据读取缓冲区,这里就会有一个文件描述符,类似于网盘的地址,比如百度云网盘的分享链接,而真实的数据放百度网盘,这种开销可以忽略,既然数据已经放到了文件缓冲区,只要拿到文件缓冲区的指针,指针在应用程序里面内存的大小就可以忽略不计了。

在现代新的操作系统里面,既然都属于内核操作系统的进程,文件读取缓冲区的内存和套接字的内存可以共享。

文件描述符(offset=1024,size=9721823),比如要读取的文件,偏移量是1024,读取9721823这个大小的数据。

把文件描述符传给应用,这个速度和时间可以忽略不计,调用socket,相当于告诉socket你要去文件读取缓冲区内存找我要发送的数据,因为我已经告诉你偏移量和大小了。

通过sendfile的方式,只剩下2次DMA拷贝了,数据的传输基本上在内核就完成了。

第一步new出一个SocketChannel,使用8081的服务器地址,SocketChannel是套接字发送缓冲区的一个通道,FileChannel是针对磁盘文件的通道,

2个通道通过transferTo进行共享。

共享的位置是从0开始,长度是文件大小,这里没有使用多文件,只读了一个文件。

fileName可以通过FileChannel传过去,传过去就已经网络传输了,只要调用transferTo方法就会完成网络发送,这种方式的耗时只需要16毫秒。

传统的传输要转换成InputStream、FileInputStream、DataOutputStream,所以开销会大些,同样的一张图片,转换出来的字节流会多一点。

通过NIO转换transferTo直接就这么转了,如果把中间的CPU拷贝的时间忽略,相当于2+2+12,传输文件描述符的话,还是会占据一点点时间。

不同的序列化方式即转换的流不一样,传输的字节数大小也不一样。

为什么Kafka不用mmap?

既然sendfile零拷贝技术效率更高,RocketMQ早期版本也是基于Kakfa java版本重写改进的,那RocketMQ为什么不用sendfile技术?

因为它们的设计理念不一样。

作为文件描述符等同于网盘地址。

RocketMQ有很多功能的延伸点是不一样的,比如延迟消息、死信消息需要数据流转到MQ应用。

RocketMQ要支持延迟消息,数据最好要进入应用,不能单纯拿一个文件描述符做延迟消息,这也是为什么Kafka没有延迟消息的原因。

数据是通过这样的方式发送的,数据不会直接经过Kafka。

Kafka的设计比较简单,没有延迟消息、死信消息等。

比如1万条消息中有一个消息发送不成功,这种情况一定要放到mq的应用内存才能处理,

而通过sendfile方式,很多的消息数据都是文件读取缓冲区的文件描述符。

类似网盘资料中的数据很多,是一个代码压缩包,单独把其中的一段代码拿出来是非常麻烦的。

Kafka做死信消息,要写一个定时器,不断的轮询,如果消息失败了,把这个消息写入到Kafka的一个文件或一个队列中,可以这样变相的实现,

但自身原生是不支持死信消息的。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有