• Netty中的零拷贝


    Netty 的零拷贝

    传统意义的拷贝

    是在发送数据的时候,传统的实现方式是:

    1. File.read(bytes)
    2. Socket.send(bytes)

    这种方式需要四次数据拷贝和四次上下文切换:

    1. 数据从磁盘读取到内核的read buffer
    2. 数据从内核缓冲区拷贝到用户缓冲区
    3. 数据从用户缓冲区拷贝到内核的socket buffer
    4. 数据从内核的socket buffer拷贝到网卡接口(硬件)的缓冲区

    零拷贝的概念

    明显上面的第二步和第三步是没有必要的,通过java的FileChannel.transferTo方法,可以避免上面两次多余的拷贝(当然这需要底层操作系统支持)

    1. 调用transferTo,数据从文件由DMA引擎拷贝到内核read buffer
    2. 接着DMA从内核read buffer将数据拷贝到网卡接口buffer

    上面的两次操作都不需要CPU参与,所以就达到了零拷贝。

    Netty中的零拷贝

    主要体现在三个方面:

    1、bytebuffer

    Netty发送和接收消息主要使用bytebuffer,bytebuffer使用对外内存(DirectMemory)直接进行Socket读写。

    原因:如果使用传统的堆内存进行Socket读写,JVM会将堆内存buffer拷贝一份到直接内存中然后再写入socket,多了一次缓冲区的内存拷贝。DirectMemory中可以直接通过DMA发送到网卡接口

    2、Composite Buffers

    传统的ByteBuffer,如果需要将两个ByteBuffer中的数据组合到一起,我们需要首先创建一个size=size1+size2大小的新的数组,然后将两个数组中的数据拷贝到新的数组中。但是使用Netty提供的组合ByteBuf,就可以避免这样的操作,因为CompositeByteBuf并没有真正将多个Buffer组合起来,而是保存了它们的引用,从而避免了数据的拷贝,实现了零拷贝。

    3、对于FileChannel.transferTo的使用

    Netty中使用了FileChannel的transferTo方法,该方法依赖于操作系统实现零拷贝。

    Netty 内部执行流程

    服务端:
    在这里插入图片描述
    在这里插入图片描述
    1、创建ServerBootStrap实例

    2、设置并绑定Reactor线程池:EventLoopGroup,EventLoop就是处理所有注册到本线程的Selector上面的Channel

    3、设置并绑定服务端的channel

    4、5、创建处理网络事件的ChannelPipeline和handler,网络时间以流的形式在其中流转,handler完成多数的功能定制:比如编解码 SSl安全认证

    6、绑定并启动监听端口

    7、当轮训到准备就绪的channel后,由Reactor线程:NioEventLoop执行pipline中的方法,最终调度并执行channelHandler

    客户端 :
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    创建包含前后255天所有天数的视图。
    VC获取主机名和主机信息
    在PowerDesigner增加unique约束
    差集的几种计算方法
    动态列的处理(统计)。
    一个查询语句各个部分的执行顺序
    IDC机房跳线
    软件下载链接
    IDC装机检查思路
    运维工程师之IDC系列
  • 原文地址:https://www.cnblogs.com/richard713/p/15935364.html
Copyright © 2020-2023  润新知