本文主要介绍Redis 6.0前后的IO线程模型,是本人通过学习资料做的学习总结和记录;
1.Redis6.0之前的单线程模型
Redis 单线程是指它对网络 IO 和数据读写的操作采用了一个线程,而采用单线程的一个核心原因是避免多线程开发的并发控制问题,并且也因为单线程的缘故,带来了天然的事务隔离级别为串行化级别,也带来了原子性的特点。
但是,单线程模型的Redis其性能还如此高效,不仅仅是因为其高效的数据结构,主要是在网络IO阶段做了优化。
朴素理解下的单线程模型:
朴素理解下的单线程将网络IO操作和对内存数据操作工作都揽在一起,这样明显性能是不高效的,因为accept和recv都是阻塞操作,且在执行线程操作时会响应不了其他连接,因此,需要借助操作系统的nio网络模型提升网络IO性能。
基于多路复用的Redis单线程模型:
借助操作系统的nio,内核会帮我们bind,listen,accept消息,当套接字收到请求,所有添加到epoll中的事件都会与设备(网卡)驱动程序建立回调关系,也就是说,一旦监测到fd上有请求到达时,就会触发相应的事件,当相应的事件发生时会调用回调方法。这个回调方法在内核中叫ep_poll_callback,它会将发生的事件添加到rdlist双链表中。然后redis自己的单线程只需要循环调度事件处理队列进行处理即可,得益于事件处理在内存,以及高效的数据结构,因此单线程模型也有高效的性能。
不足:
- 由于单线程的缘故,在执行长时间请求时,会导致redis的不可用,因此慎用范围操作等耗时操作;
- 虽然使用了nio模型,可以在内核收到消息自动通知用户态拷贝走内核中的请求消息,但时拷贝操作还是单线程,其是高并发下的性能瓶颈;
2.Redis6.0之后的多线程模型:
redis的多线程模型指的是网络IO的多线程,对内存操作还是单线程,因此新版本在得到更高吞吐量的同时还保留了原来的原子性。
多线程模型:
可以看到,6.0版本在与套接字交互的IO上做了优化,将以往的单线程改为了多线程,显著提升了从用户态写入到内核态,内核态拷贝到用户态的速度,解决了高并发时的性能问题。