0 课程地址
https://coding.imooc.com/lesson/380.html#mid=28221
1 个人收获(面试要用)
1.1 使用io多路复用原因
在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流。
什么,你还没有搞懂“一个请求到来了,nginx使用epoll接收请求的过程是怎样的”, 多看看这个图就了解了。提醒下,ngnix会有很多链接进来, epoll会把他们都监视起来,然后像拨开关一样,谁有数据就拨向谁,然后调用相应的代码处理。
要弄清问题 先要知道问题的出现原因
原因:
由于进程的执行过程是线性的(也就是顺序执行),当我们调用低速系统I/O(read,write,accept等等),进程可能阻塞,此时进程就阻塞在这个调用上,不能执行其他操作.阻塞很正常.
接下来考虑这么一个问题:一个服务器进程和一个客户端进程通信,服务器端read(sockfd1,bud,bufsize),此时客户端进程没有发送数据,那么read(阻塞调用)将阻塞直到客户端调用write(sockfd,but,size)发来数据.
在一个客户和服务器通信时这没什么问题,当多个客户与服务器通信时,若服务器阻塞于其中一个客户sockfd1,当另一个客户的数据到达套接字sockfd2时,服务器不能处理,仍然阻塞在read(sockfd1,...)上;此时问题就出现了,不能及时处理另一个客户的服务,咋么办?
I/O多路复用来解决!
I/O多路复用:
继续上面的问题,有多个客户连接,sockfd1,sockfd2,sockfd3..sockfdn同时监听这n个客户,当其中有一个发来消息时就从select的阻塞中返回,然后就调用read读取收到消息的sockfd,然后又循环回select阻塞;这样就不会因为阻塞在其中一个上而不能处理另一个客户的消息
1.2 多路io复用模型
使用select 或 epoll 或 poll系统函数同时监察多个流的io实现能力,空闲的时候把当前的线程阻塞,当一个或多个流有io实现的时候,从阻塞态中唤醒,于是程序轮询一遍所有的流。
epoll轮询的是真正活跃的流,select 轮询所有的流,依次顺序处理有序的流
1.3 select,poll,epoll是什么,做什么?
poll是Linux中的字符设备驱动中的一个函数。Linux 2.5.44版本后,poll被epoll取代。和select实现的功能差不多,poll的作用是把当前的文件指针挂到等待队列。
epoll是Linux内核为处理大批量文件描述符而作了改进的poll的函数,epoll和poll,select作用类似。是为了提高io性能。
1.4 select,poll,epoll实现原理
多路复用模型的特点:
同时监控(select/epoll)多个文件描述符的可读可写情况,当其中的某些文件描述符可读或者可写时,就会返回可读以及可写的文件描述符(个数)
进程切换:
为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。
从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化: \1. 保存处理机上下文,包括程序计数器和其他寄存器。 \2. 更新PCB信息。 \3. 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。 \4. 选择另一个进程执行,并更新其PCB。 \5. 更新内存管理的数据结构。 \6. 恢复处理机上下文。
1.5 select,poll,epoll使用场景:
1.select能监听的文件描述符个数受限于FD_SETSIZE,一般为1024,单纯改变进程打开 的文件描述符个数并不能改变select监听文件个数 .
2.解决1024以下客户端时使用select是很合适的,但如果链接客户端过多,select采用 的是轮询模型,会大大降低服务器响应效率.
假如连接数量不是很多,还会时常发生连接加入退出时,采取select 或者poll来运用
假如说有十万文件描述符,只有三个文件描述符就绪的话,很体现出epoll的优越性,但是十万中有九万文件描述符都是活跃的话,就体现不出大优势了。
epoll中有create ctl 会注册一个fd 会采取回调方式才检测就绪的事件。 而selsect 、poll 则是轮询方式来检测就绪事件。
(可以理解为12306平常的时候用epoll函数,但是在春节,国庆的时候使用poll函数)
1.6 select,poll,epoll的区别
2 课程内容
2.1 Redis速度快的原因:
1.完全基于内存操作(快于硬盘操作)
2.数据结构简单
3.单线程,避免了上下文状态切换,没有上锁而影响性能
4.多路IO复用模型(select,poll,epoll)
2.2 常见问题及解决方案
缓存穿透:解决一给没有命中的key设定“没有意义的空值”
缓存雪崩:解决一给key设置不同的(随机的)过期时间
3 引用博客
https://www.jianshu.com/p/430141f95ddb