1.Redis是一个单线程程序,但是他的所有数据都在内存中,所以速度超快。但同时也容易造成卡顿
2.redis单线程怎么处理那么多的并发客户端请求?
多路复用技术+select系列的事件轮询API(Java NIO)
3.传统IO:读写阻塞
4.非阻塞IO
不再阻塞读写,想读多少读多少,想写多少写多少。缺点:不知道何时读,何时写(用事件轮询API解决)
5.最简单的事件轮询API----select函数,它是操作系统提供给用户程序的api。输入是读写描述符列表,输出是与之对应的可读可写事件。同时还提供一个timeout参数,如果没有任何事件到来,那么就最多等待timeout规定的时间,一旦期间有任何事件到来,就可以立即返回结果,之后继续轮询。时间过了还没有任何事件到来,也会立即返回。每循环一轮描述符列表称为一个事件循环周期。
6.因为我们通过select系统同时处理多个通道描述符的读写事件,因此我们将这类系统调用称为多路复用API。现代系统的多路复用API已不在采用select,而改用epoll(linux)和kqueue
7.select,poll,epoll的特点及区别
- IO复用就是进程告诉内核一个监听条件,使得内核一旦发现IO条件就绪就通过进程处理,从而不在单个IO上阻塞
- Linux支持select,poll,epoll三种接口来实现IO复用,IO多路复用适合一下场景:当客户处理多个描述符时·当一个客户处理多个套接口时·如果一个TCP既要处理监听套接字,又要处理已连接的套接字·一个服务器既要处理TCP又要处理UDP·一个服务器要处理多个服务或协议
- Fd:一个进程的“打开文件”的数组(存放指向文件的对象的指针)的下标
- LT模式(普通模式)(水平触发):多次提醒描述符有数据
- ET模式(高效模式)(边沿触发):只提醒一次描述符有数据
- Select系统调用:默认可以监听1024个,采用轮询的方式遍历所有fd,性能差
- Poll系统调用(与select本质一样,都是将描述符全部存入内存):采用poll_list来存储描述符,可以监听65535个描述符,数量过大后性能也会下降
- Epoll系统调用:为什么epoll比poll和select更高效(在连接数少并且都非常活跃的情况下除外)?
减少了用户态和内核态之间的文件拷贝
减少了对就绪文件描述符的遍历
Select和poll只支持LT模式,而epoll支持ET(高效)模式,并且支持EPOLLONESHOT事件
8.套接字:套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。
- 指令队列:reids将每个客户端套接字都关联到一个指令队列,排队处理指令
- 响应队列:redis同样为每个客户端套接字关联一个响应队列,通过它将指令的返回结果回复给客户端
9.定时任务:服务器除了要响应IO时间外,还要响应其他事情,比如定时任务。将定时任务放在最小堆,在timeout时必须执行