1、Redis是单线程吗?
Redis 的单线程主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能,比如持久化、异步删除、集群数据同步等,是由其他线程执行的。
2、Redis 单线程为什么这么快?
关键:内存和避免了多线程上下文切换。
内存操作:数据存储在内存中,操作Redis时是内存级别的操作,可支持百万的QPS。
多线程上下文切换:我们使用的操作系统大多是分时系统,CPU采用时间片轮转规则执行任务时,在执行下一个任务前,要先将当前任务的状态信息,也就是当前CPU寄存器的所有内容保存到任务自己的堆栈中。再把下一个任务的状态信息加载到CPU寄存器中。时间片大小设置不同,每秒可能进行几十到上百次切换,每次切换都会产生耗时。而单线程避免了这个问题
3、既然使用单线程,又如何处理并发客户端连接?
关键:使用I/O多路复用技术;
IO多路复用,指多个连接复用同一个阻塞对象,进程只需要在一个阻塞对象上等待,无需轮询所有连接请求。当某个连接请求的资源可用时,操作系统通知进程,进程从阻塞状态返回,开始进行事务处理。
epoll是用户进程从内核态获取到资源可用通知的方法之一。epoll将用户空间的fd放到内核的事件表,内核进程遍历事件表,查看是否有事件可用的资源。当有可用资源时,内核通过回调函数激活fd。用户进程在epoll_wait中收到通知,知道哪个socket连接的资源就绪。
epoll使用内核映射技术,只需要将fd在用户态和内核态拷贝一次。同时,当资源就绪时,内核激活对应的fd,用户态可以直接获取到资源就绪的fd,无需像select和poll通过遍历fd列表获取,时间复杂度是O(1).