首页 > 其他分享 >DMA:为什么Kafka这么快?

DMA:为什么Kafka这么快?

时间:2023-08-17 22:32:59浏览次数:42  
标签:DMA 为什么 Kafka 传输 内存 DMAC 数据传输 数据 CPU

  • 提升I/O设备速度,HDD换成SSD,仍觉不够快
  • PCI Express接口的SSD硬盘替代SATA接口的SSD硬盘,还是不够快

但无论I/O速度如何提升,比CPU还是太慢。SSD IOPS可到2万、4万,但CPU主频2GHz以上,每秒20亿次操作。如对I/O操作都由CPU发出对应指令,然后等待I/O设备完成操作后返回,那CPU有大量时间浪费在等待I/O设备完成操作。

这种等待无实际意义,对I/O设备大量操作,都只是把内存数据,传输到I/O设备,CPU只是傻等。传输数据量大时,如大文件复制,若所有数据都要经过CPU,就太浪费时间。

就有了DMA(Direct Memory Access,直接内存访问),减少CPU等待时间。

1 协处理器

DMA就是在主板放一块独立芯片。在内存和I/O设备数据传输时,不再通过CPU控制数据传输,而通过DMA控制器(DMA Controller,DMAC)。这块芯片,可认为是个协处理器(Co-Processor)。

DMAC最有价值在:

  • 当传输数据大、速度快
    如千兆网卡或硬盘,传输大量数据时,若都用CPU搬运,就忙不过来,可选择DMAC
  • 或传输数据特别小、速度慢
    数据传输很慢,DMAC可等数据到齐,再发送信号,给到CPU去处理,而不让CPU忙等待

DMAC是“协助”CPU,完成对应的数据传输工作。在DMAC控制数据传输的过程中,还是需要CPU。

DMAC也是一个特殊I/O设备,CPU以及其他I/O设备一样,通过连接到总线来进行实际的数据传输。总线上的设备呢,其实有两种类型:

  • 主设备(Master)
  • 从设备(Slave)

想主动发起数据传输,须为主设备,如CPU。 从设备(如硬盘)只能接受数据传输。所以,若通过CPU传输数据:

  • 要么是CPU从I/O设备读数据
  • 要么是CPU向I/O设备写数据

那I/O设备不能向主设备发请求吗?可以是可以,不过发送的不是数据内容,而是控制信号。I/O设备可告诉CPU,我这里有数据要传输给你,但实际数据是CPU拉走的,而不是I/O设备推给CPU的。

DMA:为什么Kafka这么快?_数据传输

DMAC既是主设备,又是从设备:

  • 对CPU,它是从设备
  • 对硬盘这样的IO设备,是主设备

2 DMAC数据传输的过程

① CPU作为主设备,向DMAC设备发请求

就是在DMAC里修改配置寄存器。

CPU修改DMAC配置时,会告诉DMAC:源地址的初始值及传输时的地址增减方式。

源地址

数据从哪传过来:

  • 若从内存写数据到硬盘,即数据在内存里的地址
  • 若从硬盘读数据到内存,即硬盘的I/O接口的地址
    I/O地址是个内存地址,也能是个端口地址。

地址增减方式

数据是从大地址向小地址传输,还是从小地址往大地址传输。

还要传输目标地址初始值和传输时的地址增减方式。目标地址自然就是和源地址对应的设备,即数据传输的目的地。

要传输的数据长度

即共要传输多少数据。

② 设置完这些信息后,DMAC就变成空闲状态(Idle)。

若要从硬盘往内存加载数据,这时

③ 硬盘会向DMAC发起数据传输请求

这请求不是通过总线,而是通过一个额外连线。

④ DMAC再通过一个额外连线响应该申请

⑤ DMAC芯片就向硬盘的接口发起总线读的传输请求

数据就从硬盘读到DMAC控制器。

⑥ DMAC再向内存发起总线写的数据传输请求

把数据写入内存。

⑦ DMAC反复执行上面的⑤、⑥ 步

直到DMAC的寄存器里设置的数据长度传输完成。

  1. 数据传输完成之后,DMAC重新回到第3步的空闲状态

所以,整个数据传输的过程中,不是通过CPU来搬运数据,而由DMAC芯片来搬运数据。但是CPU在这个过程中也是必不可少的。因为传输什么数据,从哪里传输到哪里,其实还是由CPU来设置的。这也是为什么,DMAC被叫作“协处理器”。

外设很多都内置DMAC。最早计算机里没有DMAC,所有数据由CPU搬运。随数据传输需求多,先出现主板独立的DMAC控制器。到今天,各种I/O设备,数据传输需求越来越复杂,使用场景各不相同。显示器、网卡、硬盘对数据传输需求都不一样,所以各设备都有自己DMAC芯片。

2 你咋那么快?来看Kafka实现原理

有啥API,我们应用层调用一下,就能加速数据传输,减少CPU占用?开源项目很好利用了DMA数据传输方式,通过DMA实现非常大的性能提升,如Kafka。Kafka是处理实时数据的管道,常用做消息队列或收集和落地海量日志,其瓶颈也就在I/O。

Kafka有两种常见的海量数据传输情况:

  • 从网络中接收上游的数据,然后落地到本地磁盘,确保数据不丢
  • 从本地磁盘读出来,通过网络发送出去

写个简单程序,最直观的用个文件读操作,从磁盘上把数据读到内存,然后再用个Socket,把这些数据发送到网络:

1File.read(fileDesc, buf, len);2Socket.send(socket, buf, len);

这过程中,数据发生四次传输过程:

  • 两次DMA传输
  • 两次通过CPU控制的传输

① 第一次传输,从硬盘读到 os 内核缓冲区。通过DMA搬运

② 第二次传输,从内核缓冲区里数据,复制到应用分配的内存。通过CPU搬运

③ 第三次传输,从应用内存,再写到操作系统的Socket缓冲区。由CPU搬运

④ 最后一次传输,再从Socket缓冲区,写到网卡缓冲区。通过DMA搬运

只要“搬运”一份数据,却运了四次。从内核读缓冲区传输到应用内存,再从应用内存传输到Socket缓冲区,是把同一份数据在内存里搬来搬去,特没效率。

像Kafka的应用场景大部分最终利用到的硬件资源,其实又都是在干这搬运数据,要尽可能减少数据搬运。

Kafka做的就是把这数据搬运次数,从上面四次,变成两次,且只有DMA进行数据搬运,不需要CPU。

1@Override2public long transferFrom(FileChannel fileChannel, long position, long count) throws IOException {3    return fileChannel.transferTo(position, count, socketChannel);4}

最终调用Java NIO库transferTo方法。数据并没读到中间的应用内存,而是直接通过Channel,写入对应网络设备。且对Socket操作,也不是写入SocketBuffer,而是直接根据描述符(Descriptor)写入网卡缓冲区。于是,这过程只进行两次数据传输:

DMA:为什么Kafka这么快?_零拷贝_02

  • 第一次,通过DMA,从硬盘读到os内核读缓冲区
  • 第二次,则是根据Socket描述符信息,直接从读缓冲区里,写入网卡的缓冲区

同一份数据传输的次数从4次变成2次,并且没有通过CPU进行数据搬运,所有数据通过DMA传输。

这方法没有在内存层面去“复制(Copy)”数据,所以称零拷贝(Zero-Copy)。无论传输数据量的大小,传输同样数据,使用零拷贝能缩短65%时间,大幅提升机器传输数据的吞吐量。

3 总结

如果始终让CPU来进行各种数据传输工作,会特别浪费:

  • 我们的数据传输工作用不到多少CPU核心的“计算”功能
  • CPU的运转速度也比I/O操作要快很多。所以,我们希望能够给CPU“减负”

于是,工程师们就在主板上放上了DMAC这样一个协处理器芯片。通过这个芯片,CPU只需要告诉DMAC,我们要传输什么数据,从哪里来,到哪里去,就可以放心离开了。后续的实际数据传输工作,都会由DMAC来完成。随着现代计算机各种外设硬件越来越多,光一个通用的DMAC芯片不够了,我们在各个外设上都加上了DMAC芯片,使得CPU很少再需要关心数据传输的工作了。

在我们实际的系统开发过程中,利用好DMA的数据传输机制,也可以大幅提升I/O的吞吐率。最典型的例子就是Kafka。

传统地从硬盘读取数据,然后再通过网卡向外发送,我们需要进行四次数据传输,其中有两次是发生在内存里的缓冲区和对应的硬件设备之间,我们没法节省掉。但是还有两次,完全是通过CPU在内存里面进行数据复制。

在Kafka里,通过Java的NIO里面FileChannel的transferTo方法调用,我们可以不用把数据复制到我们应用程序的内存里面。通过DMA的方式,我们可以把数据从内存缓冲区直接写到网卡的缓冲区里面。在使用了这样的零拷贝的方法之后呢,我们传输同样数据的时间,可以缩减为原来的1/3,相当于提升了3倍的吞吐率。

这也是为什么,Kafka是目前实时数据传输管道的标准解决方案。

标签:DMA,为什么,Kafka,传输,内存,DMAC,数据传输,数据,CPU
From: https://blog.51cto.com/JavaEdge/7128043

相关文章

  • 为什么 cl_gui_dialogbox_container 只能在 at selection output 事件中使用
    首先,我们来了解一下cl_gui_dialogbox_container类。这是SAP的一个类,用于创建一个对话框容器,通常用于在对话框中显示一些GUI控件,例如:图形、控件等。cl_gui_dialogbox_container对象主要用于在模态对话框中创建自定义容器,它允许我们将GUI控件(如ALVGRID,HTMLViewer等)嵌入......
  • 为什么企业需要内部威胁检测软件?
    在数字时代,企业不仅需要抵御外部威胁,还必须密切关注内部威胁,因为内部因素可能对数据安全造成严重威胁。作为一款强大的内部威胁监测工具,ADAuditPlus在这一领域发挥着关键作用。本文将深入探讨ADAuditPlus在内部威胁监测中的重要性。 一、内部威胁的隐患 内部威胁是......
  • 云桌面服务跟瘦终端为什么可以成为学校首选
    现如今,越来越多的学校开始采用云桌面服务和瘦终端作为教学工具,这是一种全新的技术,目前也可以说是学校首选的理想解决方案。下面小编将跟大家一起详细探讨云桌面服务与瘦终端在教育领域中的种种优势和应用,以及这些技术为什么能够成为学校的首选。首先,让我们来了解一下什么是云桌面......
  • 云桌面有哪些优势?为什么说企业使用云桌面是大势所趋
    怎么在一个电脑上打开两个电脑?以前很多的技术人员用过一种方式,就是在自己的本地电脑开设一个虚拟的电脑,这种东西也叫桌面“云”,桌面其实是云端的虚拟桌面。我们日常登录的“云桌面”其实就是使用服务器上的虚拟的桌面,虽然我们叫做虚拟的桌面,但是这种桌面实际上也是真的电脑界面。......
  • 云电脑哪个平台好?为什么都推荐青椒云
    在当今数字化时代,云计算是一种越来越受欢迎的技术,而云电脑作为云计算的一种具体应用形式,也引起了人们的广泛关注。众所周知,云电脑平台的选择对于用户来说是非常重要的,因为不同的平台提供的服务和体验可能有很大的差别。在众多云电脑平台中,青椒云凭借其卓越的性能和全面的服务备受......
  • 什么是等级保护?信息系统为什么需要做等保?
    等保也就是信息安全等级保护,它是我国网络安全领域的基本国策、基本制度,那么等级保护是什么,为什么信息系统需要做等级保护?以下是详细的内容:什么是等级保护?信息安全等级保护测评是指对企业、组织或政府机构的信息系统、网络和应用程序进行评估和测试,以确定它们的安全等......
  • 数据库连接池为什么要用threadlocal呢?不用会怎样?
    数据库连接池使用ThreadLocal的主要原因是为了保证每个线程都有其独立的数据库连接,这样可以避免多个线程之间的连接干扰,提高系统的稳定性和性能。为什么使用ThreadLocal?线程安全:ThreadLocal可以为每个线程提供一个独立的数据库连接,确保多个线程操作数据库时不会出现资源竞争的......
  • 为什么自学web学不会?
    很多同学在学习web全栈上,喜欢选择自学,可是结果却不尽人意,学不到知识不说,最后浪费了学习最佳的学习时间。那么为什么自学web学不会?而最适合学习web的方式又是什么? 1.百度搜索  2.书籍学习 web全栈有关的书,可是很多人都不知道应该买那本书,导致很多人去买了一些销量不错的书籍,......
  • 为什么 MySQL 选择 B+树做索引?
    提到MySQL索引,相信使用过的小伙伴并不陌生,日常工作中,我们经常会加索引来提升查询效率,那么,为什么一个慢查询加上索引查询速度就能提升一个档次?索引后面的实现机制到底是什么?今天就让我们一起来探讨这个话题。申明:本文说的磁盘是指普通的机械磁盘一、索引是什么比如阅读时,索引......
  • Flink and Kafka Streams: a Comparison and Guideline for Users
    ThisblogpostiswrittenjointlybyStephanEwen,CTOofdataArtisans,andNehaNarkhede,CTOofConfluent. StephanEwenisPMCmemberofApacheFlinkandco-founderandCTOofdataArtisans.BeforefoundingdataArtisans,Stephanwasleadingthedevelo......