现在只要涉及到存储,涉及到和文件相关的开源框架,几乎都不约而同的会使用零拷贝技术,因为零拷贝技术可以让速度变快。零拷贝技术并不是说完全不拷贝,而是尽可能的减少拷贝。
在没有零拷贝技术之前,你操作一个文件一般是这样的流程:
你可以发现一共进行了4次拷贝,两次DMA拷贝,两次CPU拷贝,并且你会发现发生了4次user space和kernel space之间的切换。
在IO的世界里,拷贝和上下文切换都是非常昂贵的,这一切都源于CPU的介入。为了安全,凡事都得经过CPU这一关,但这也带来一个问题就是性能下降。为此,计算机界的大佬们苦苦研究和探索,想着如何让CPU不介入或者减少介入,最后他们终于探索出两大零拷贝技术:mmap、sendfile。
ps:其实上面那个DMA拷贝也是一个减少CPU介入的更加快速的方案。
那我们接下来就来看看这两种零拷贝技术分别是怎么实现的。
mmap
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
什么是MMAP技术呢?其实就是虚拟内存技术,磁盘即内存,内存即磁盘。
相比 read()
方法,mmap技术主要的不同是向操作系统内核发起IO调用的mmap方法。通过MMAP技术,你会发现减少了一次CPU的拷贝,一共是三次拷贝:两次DMA拷贝和一次CPU拷贝。具体步骤:
sendfile
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
sendfile方法是直接面向fd的,也就是file descriptor的,文件描述符,sendfile让两个fd之间直接传输数据,这个动作是在操作系统内核层执行,这样就避免了内核buffer和user buffer之间的数据拷贝操作,所以它也被称为是一种零拷贝技术。具体流程如下:
可以发现基于sendfile的零拷贝技术只有两次context的切换,3次拷贝(2次DMA拷贝、1次CPU拷贝)。
这里需要注意的是sendfile和mmap同样都发生了3次拷贝,但在上下文切换上sendfile比mmap少了两次,mmap切换了4次,但sendfile只有两次切换。所以从性能上讲sendfile更出色。
Kafka和RocketMQ
众所周知这两个MQ框架有异曲同工之妙,犹如孪生兄妹一般,但据笔者所知他们之间还是有一些不同的,其中一个重要的不同就是使用的零拷贝技术不同,RocketMQ使用的mmap技术,而Kafka则使用的sendfile技术。
总结
通过上面的分析,我们知道了两种主要的零拷贝技术:mmap和sendfile。这两个零拷贝技术都有效地减少了拷贝次数,都是三次拷贝,同时sendfile还减少了context切换的次数,变成了2次。同时我们知道了Kafka和RocketMQ他们使用了不同的零拷贝技术。目前只要涉及到存储和文件相关的开源框架为了提高性能几乎都会使用到零拷贝技术,比如IO框架(Netty)、MQ、分布式NoSQL数据库等。
本文分享自 ImportSource 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!