某林操作系统——网络系统

什么是零拷贝?

DMA技术:使用一个DMA控制器将数据从硬盘传输到内存,除了一开始调用DMA控制器发起传输,数据搬运全称不需要CPU参与。

发送一段数据到网上如下所示

4次状态切换4次拷贝。

为了加快速度就要减少上下文切换,减少拷贝次数。

mmap+write() 

共发生3次拷贝,4次上下文切换。

sendfile

发生两次上下文切换和两次拷贝。

IO多路复用——select/ poll / epoll

基本socket模型

socket是进程通信的一种方式,服务端的一个socket会被绑定一个ip+端口。

然后等待客户端的connect()。TCP连接的具体去看网络的内容。

如何服务更多的用户?

服务器理论上能服务的客户端的TCP数量=ip*端口数。ip有2^32,端口有2^16,所以最多有2^48个客户端。

这也只是理论。

这受限于两个条件:

        系统内存:每个TCP连接都是要占用一定内存的。

        文件描述符:socket在系统里面也是一个文件,对应一个文件描述符。在linux中,能同时打开的文件描述符数量是有限的。

多进程模型

基于原始的阻塞网络IO,如果要支持多个客户端,可以使用多进程模型,为每个客户端分配一个进程。

服务器的主进程负责监听socket,与客户端连接完成之后调用accept()得到一个“已连接socket”,然后就可以直接fork一个子进程去使用已连接socket和客户端通信。

弊端:客户端数量越多,进程越多,上下文切换也越久。

多线程模型

为了解决多进程上下文切换重的问题,可以使用多线程模型。为了防止创建和销毁线程的开销,使用线程池技术,有一个客户端连接就取一个线程出来去拿一个已连接socket.

弊端:如果要应对1万个客户端就要有1万个线程,操作系统还是抗不住。

I/O 多路复用

一个请求分配一个进程/线程不可行,那就一个进程/线程负责多个socket.

Redis里面也是用到了这个。

为了实现多路复用,需要用到内核提供给用户态的多路复用系统调用select/poll/epoll ,进程可以通过一个系统调用函数从内核中获取多个事件

select/poll/epoll 是如何获取网络事件的呢?在获取事件时,先把所有连接(文件描述符)传给内核,再由内核返回产生了事件的连接,然后在用户态中再处理这些连接对应的请求即可。

select/poll/epoll

select是直接将所有已连接socket放到一个文件描述符集合,然后调用select将其拷贝到内核,让内核检查是否有事件发生,有的话标记socket为可读或可写。然后将其拷贝到用户态,用户态遍历对可读可写的socket进行操作。在linux里面最多只能监听1024个文件描述符。

poll采用链表的形式组织socket,不受1024的数量限制,受文件描述符的数量限制。本质上和select没有区别。操作方法雷同。

epoll

 边缘触发和水平触发

高性能网络模式——Reactor

redis,nginx,netty中都有采用这个模式。

redis高性能的原因有IO多路复用。Reactor模式是对IO多路复用的一个封装。

Reactor 模式主要由 Reactor 和处理资源池这两个核心部分组成,它俩负责的事情如下:

  • Reactor 负责监听和分发事件,事件类型包含连接事件、读写事件;
  • 处理资源池负责处理事件,如 read -> 业务逻辑 -> send;

单Reactor 单进程/线程

Redis6.0之前里面用的就是这个模式,redis性能的瓶颈不在CPU上,所以6.0之前引入了多线程去处理网络IO。 6.0之前是一个线程还要进行IO数据的拷贝,6.0开始主线程就只负责执行命令了。引入了多线程去处理IO数据。

单Reactor 多线程 / 多进程

多Reactor 多进程 / 线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值