文章目录
- 前言
- 为什么Redis不采取多线程?
- Redis单线程+IO多路复用
- Linux多路复用
- 多路复用技术已经大大的提升了IO利用率,为啥Redis6.0还需要多线程?
- 引入多线程之后,如何解决并发带来的线程安全问题呢?
- 参考
前言
- Redis单线程是指网络IO模块和数据读取模块(读取KV键值对)是单线程的,而不是指redis就完全是单线程的!
- 在Redis 6.0,它引入了多线程,但也只是针对处理网络请求过程采用了多线程,而数据的读写命令,仍然是单线程处理的。
为什么Redis不采取多线程?
没必要,Redis的性能瓶颈不在CPU,它是基于内存的
而且最重要的是,不要一味的多线程,因为多线程也是有缺陷的,比如数据的线程安全问题
Redis单线程+IO多路复用
先看看Linux多路复用的多路复用模型
Linux多路复用
多路复用技术已经大大的提升了IO利用率,为啥Redis6.0还需要多线程?
单线程处理网络IO的Redis已经够大多数公司用了,但针对一些上亿的QPS,还是存在性能瓶颈。
经过分析,限制Redis的性能的主要瓶颈出现在网络IO的处理上,虽然之前采用了多路复用技术,但多路复用的IO模型本质上仍然是同步阻塞型IO模型。
下面是多路复用IO中select函数的处理过程:
从上图我们可以看到,在多路复用的IO模型中,在处理网络请求时,调用 select (其他函数同理)的过程是阻塞的,也就是说这个过程会阻塞线程,如果并发量很高,此处可能会成为瓶颈。
虽然现在很多服务器都是多个CPU核的,但是对于Redis来说,因为使用了单线程,在一次数据操作的过程中,有大量的CPU时间片是耗费在了网络IO的同步处理上的,并没有充分的发挥出多核的优势。
如果能采用多线程,使得网络处理的请求并发进行,就可以大大的提升性能。多线程除了可以减少由于网络 I/O 等待造成的影响,还可以充分利用 CPU 的多核优势。
所以,Redis 6.0采用多个IO线程来处理网络请求,网络请求的解析可以由其他线程完成,然后把解析后的请求交由主线程进行实际的内存读写。提升网络请求处理的并行度,进而提升整体性能。
但是,Redis 的多 IO 线程只是用来处理网络请求的,对于读写命令,Redis 仍然使用单线程来处理。
引入多线程之后,如何解决并发带来的线程安全问题呢?
Redis 6.0 只有在网络请求的接收和解析,以及请求后的数据通过网络返回给时,使用了多线程。而数据读写操作还是由单线程来完成的,所以,这样就不会出现并发问题了。