赞
踩
redis网络模型背景
1.进程分为用户空间和内核空间;
用户空间和内核空间共同目标是对系统资源的访问,为了提高IO效率,给用户空间和内核空间都加入了缓存;访问的流程为读写两部分,读:用户空间访问内核空间的缓存产看是否存在资源,若没有内核空间再对系统资源进行访问获取资源后存在缓存层,再读取到用户空间进行逻辑操作;写:将用户空间的缓存内容拷贝到内核空间缓存层,然后写入硬件中;
2.阻塞IO
阻塞IO指的是IO模型中等待数据的状态,发生在两个阶段,第一个阶段:用户空间执行recvfrom从内核空间中查找资源,内核缓存层并没有数据就进入到等待状态,第二个阶段:内核空间从硬件上也无法拷贝资源,进入等待状态;
3.非阻塞IO
非阻塞IO指的是用户进程执行recvfrom从内核空间查找数据,但是没有数据内核空间就会返回错误给用户,但其实内核空间的从缓存层拷贝数据也是处于等待状态,用户进程得到错误信息后会不断访问内核空间,知道内核空间拷贝数据成功后返回正确给用户进程,用户在进行逻辑调用;与阻塞IO的区别在于第一阶段等待与否,性能稍差,不如阻塞IO;
4.IO多路复用
无论阻塞IO还是非阻塞IO,存在一个问题是在第二个阶段都要进行等待,cpu的利用率不太好,IO多路复用解决了这一问题,使用单线程监听FD的状态,然后再调用recvfrom从内核空间拷贝资源到用户空间供用户进行使用;
FD:用来关联linux中的文件,linux中一切皆为文件,FD是一个无符号整数
IO多路复用过程:用户调用select同时监听多个socekt,如果发现FD 是readable,就调用recvfrom从内核空间拷贝数据到用户供用户使用
IO多路复用采用select存在很多的缺点,例如:监听的FD不能超过1024,需要拷贝FD到内核空间并且要遍历所有的FD;而采用epoll不用遍历所有的FD,直接拷贝到用户空间,采用红黑树来存储FD,大小不上限,增删改查非常方便 ,性能不会因FD的数量受影响;
Web服务使用Redis epoll 流程:用户空间的服务端创建实例epoll_create,severSocket得到FD,epoll_ctl 监听FD,注册所有FD到红黑树,如果监听到FD就绪,将就绪的FD存储链表中,epoll_wait 等待FD从链表中判断是否存在链表头,如果存在判断事件类型,如果是异常写出响应 ,如果是epollin判断ssfd是否可读,如果可读 accept接收客户端socket得到对应的FD然后到监听FD再到注册过程,如果ssfd不可读就直接读取请求参数作出响应。
异步IO:用户进程调用aio_read函数通知内核空间然后不再关心干其他事情,而内核空间进行等待数据带数据就绪拷贝数据到用户空间,递交aio的信号,信号函数处理信号到用户进程;
总结:所谓阻塞IO中的阻塞实际上是指第一阶段等待数据是否阻塞,都不阻塞的是异步IO;同步与异步是看第二阶段是否阻塞,阻塞与非阻塞IO都是同步IO;
Redis网络模型核心是IO多路复用和事件派发,使用单线程,使用多线程的地方是两部分,一个是对命令的解析,还有就是写返回结果,性能的关键在于IO本身,与是否多线程关系不大。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。