netty nio reactor epoll 多路I/O redis这些常容易混在一块的名词

  1. 首先reactor是一种设计模型;redis(单线程reactor),netty都用到了这种模型.
  • Acceptor,Dispatch,handler,socketchannel是reactor模型中的概念,Acceptor用于监听端口接收TCP连接请求,而后通过Dispatch将对应的ByteBuffer转发到指定的handler上,进行消息的处理
  1. Channel(通道),Buffer(缓冲区), Selector这些是java nio中的概念。
  • Channel接口下有FileChannel,DatagramChannel,SocketChannel对应文件IO、UDP和TCP。
  • Buffer有ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer,分别对应java基本数据类型
  1. 其次select/poll/epoll是I/O复用技术,I/O多路复用就通过一种机制,可以监视多个描述符(socket),一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
  • 为了安全问题,一些I/O操作的指令都被限制在只有内核模式可以执行,所以I/O操作必不可免地要使用系统调用进行用户态与内核态的转换,从而把内核缓存区数据写入到用户内存空间实现I/O数据交换.select/poll/epoll就是通过系统调用进行I/O复用的几种方案.
  • 由于select/poll都采用了轮询的处理方式所以他们的时间复杂度是O(n),poll比select的优点是没有最大连接数的限制;
  • epoll采用信号驱动方式改进了轮询方式, 当数据准备就绪,会产生相应信号回调通知程序进行处理
  1. Java nio的selector就是基于epoll的多路复用技术实现的.
  2. netty是一个高性能NIO框架,他的出现是对Java自带nio的一种升级改造,使得Java nio的编程更加简单并减少Bug的出现,他和redis一样都基于事件驱动
  • reactor模型
  • 零拷贝:(1)Netty的接收和发送ByteBuffer采用DIRECT BUFFERS,使用堆外直接内存进行Socket读写,不需要进行字节缓冲区的二次拷贝。如果使用传统的堆内存(HEAP BUFFERS)进行Socket读写,JVM会将堆内存Buffer拷贝一份到直接内存中,然后才写入Socket中。相比于堆外直接内存,消息在发送过程中多了一次缓冲区的内存拷贝。
    (2)不再将文件内容拷贝到用户空间(User Space)而直接在内核空间(Kernel Space)中传输到网络的方式。
    传统拷贝方式:
    首先,操作系统是分用户内存空间和内核内存空间的,区分的原因是因为,很多操作系统的指令,安全级别很高,不是随随便便就能调用的,对应的,一部分归操作系统使用的内存空间安全级别也很高,不是随随便便就能访问的,二者都是操作系统才能操作的“内核态”。“内核态”的指令,叫做系统调用,“内核态”的内存空间,成为内核空间。
    从硬盘读文件的过程,然后通过网络发送出去,一般的操作,需要经过:
  • 拷贝流程
    用户空间->(1. 读文件,系统调用,硬盘文件从硬件缓存复制到内核空间,使用DMA)->内核空间->(2. 用户程序读取文件数据,使用CPU)->用户空间->(3. 通过socket发送文件到网络,系统调用,数据复制回内核空间socket关联的内存,使用DMA)->内核空间->(4. 数据复制到网卡驱动硬件的缓存,系统调用,使用DMA,执行完成).
    实现零拷贝的方法有:
    文件内存映射(用户空间与内核空间地址映射),sendFile方式(transferTo,transferFrom)

参考:https://www.cnblogs.com/aspirant/p/9166944.html, netty权威指南第二版,
https://blog.csdn.net/lqadam/article/details/85010781

你可能感兴趣的:(netty nio reactor epoll 多路I/O redis这些常容易混在一块的名词)