文章目录

  • 前言
  • 为什么Redis不采取多线程?
  • Redis单线程+IO多路复用
  • Linux多路复用
  • 多路复用技术已经大大的提升了IO利用率,为啥Redis6.0还需要多线程?
  • 引入多线程之后,如何解决并发带来的线程安全问题呢?
  • 参考


前言

  • Redis单线程是指网络IO模块和数据读取模块(读取KV键值对)是单线程的,而不是指redis就完全是单线程的!
  • 在Redis 6.0,它引入了多线程,但也只是针对处理网络请求过程采用了多线程,而数据的读写命令,仍然是单线程处理的。

为什么Redis不采取多线程?

没必要,Redis的性能瓶颈不在CPU,它是基于内存的

而且最重要的是,不要一味的多线程,因为多线程也是有缺陷的,比如数据的线程安全问题

Redis单线程+IO多路复用

先看看Linux多路复用的多路复用模型

Linux多路复用

为什么不用redis做消息中间件 redis为什么不使用多线程_为什么不用redis做消息中间件

多路复用技术已经大大的提升了IO利用率,为啥Redis6.0还需要多线程?

单线程处理网络IO的Redis已经够大多数公司用了,但针对一些上亿的QPS,还是存在性能瓶颈。

经过分析,限制Redis的性能的主要瓶颈出现在网络IO的处理上,虽然之前采用了多路复用技术,但多路复用的IO模型本质上仍然是同步阻塞型IO模型

下面是多路复用IO中select函数的处理过程:

为什么不用redis做消息中间件 redis为什么不使用多线程_网络_02

从上图我们可以看到,在多路复用的IO模型中,在处理网络请求时,调用 select (其他函数同理)的过程是阻塞的,也就是说这个过程会阻塞线程,如果并发量很高,此处可能会成为瓶颈

虽然现在很多服务器都是多个CPU核的,但是对于Redis来说,因为使用了单线程,在一次数据操作的过程中,有大量的CPU时间片是耗费在了网络IO的同步处理上的,并没有充分的发挥出多核的优势。

如果能采用多线程,使得网络处理的请求并发进行,就可以大大的提升性能。多线程除了可以减少由于网络 I/O 等待造成的影响,还可以充分利用 CPU 的多核优势。

所以,Redis 6.0采用多个IO线程来处理网络请求,网络请求的解析可以由其他线程完成,然后把解析后的请求交由主线程进行实际的内存读写。提升网络请求处理的并行度,进而提升整体性能。

但是,Redis 的多 IO 线程只是用来处理网络请求的,对于读写命令,Redis 仍然使用单线程来处理

引入多线程之后,如何解决并发带来的线程安全问题呢?

Redis 6.0 只有在网络请求的接收和解析,以及请求后的数据通过网络返回给时,使用了多线程。而数据读写操作还是由单线程来完成的,所以,这样就不会出现并发问题了。