✅Redis为什么被设计成是单线程的?

典型回答

我们所说的Redis单线程,指的是"其网络IO和键值对读写是由一个线程完成的",也就是说,Redis中只有网络请求模块和数据操作模块是单线程的。而其他的如持久化存储模块、集群支撑模块等是多线程的。


所以说,Redis中并不是没有多线程模型的,早在Redis 4.0的时候就已经针对部分命令做了多线程化。

一个计算机程序在执行的过程中,主要需要进行两种操作分别是读写操作和计算操作。

其中读写操作主要是涉及到的就是I/O操作,其中包括网络I/O和磁盘I/O。计算操作主要涉及到CPU。

而多线程的目的,就是通过并发的方式来提升I/O的利用率和CPU的利用率。

之所以Redis没有用多线程处理IO操作,主要是因为,Redis的操作基本都是基于内存的,CPU资源根本就不是Redis的性能瓶颈。

扩展知识

Redis为什么最开始被设计成单线程的?

Redis作为一个成熟的分布式缓存框架,它由很多个模块组成,如网络请求模块、索引模块、存储模块、高可用集群支撑模块、数据操作模块等。

很多人说Redis是单线程的,就认为Redis中所有模块的操作都是单线程的,其实这是不对的。

我们所说的Redis单线程,指的是"其网络IO和键值对读写是由一个线程完成的",也就是说,Redis中只有网络请求模块和数据操作模块是单线程的。而其他的如持久化存储模块、集群支撑模块等是多线程的。

所以说,Redis中并不是没有多线程模型的,早在Redis 4.0的时候就已经针对部分命令做了多线程化。

那么,为什么网络操作模块和数据存储模块最初并没有使用多线程呢?

这个问题的答案比较简单!因为:"没必要!"

为什么没必要呢?我们先来说一下,什么情况下要使用多线程?

多线程适用场景

一个计算机程序在执行的过程中,主要需要进行两种操作分别是读写操作和计算操作。

其中读写操作主要是涉及到的就是I/O操作,其中包括网络I/O和磁盘I/O。计算操作主要涉及到CPU。

而多线程的目的,就是通过并发的方式来提升I/O的利用率和CPU的利用率。

那么,Redis需不需要通过多线程的方式来提升提升I/O的利用率和CPU的利用率呢?

首先,我们可以肯定的说,Redis不需要提升CPU利用率,因为Redis的操作基本都是基于内存的,CPU资源根本就不是Redis的性能瓶颈。

所以,通过多线程技术来提升Redis的CPU利用率这一点是完全没必要的。

那么,使用多线程技术来提升Redis的I/O利用率呢?是不是有必要呢?

Redis确实是一个I/O操作密集的框架,他的数据操作过程中,会有大量的网络I/O和磁盘I/O的发生。要想提升Redis的性能,是一定要提升Redis的I/O利用率的,这一点毋庸置疑。

但是,提升I/O利用率,并不是只有采用多线程技术这一条路可以走!

多线程的弊端

我们在很多文章中介绍过一些Java中的多线程技术,如内存模型、锁、CAS等,这些都是Java中提供的一些在多线程情况下保证线程安全的技术。

线程安全:是编程中的术语,指某个函数、函数库在并发环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。

和Java类似,所有支持多线程的编程语言或者框架,都不得不面对的一个问题,那就是如何解决多线程编程模式带来的共享资源的并发控制问题。

虽然,采用多线程可以帮助我们提升CPU和I/O的利用率,但是多线程带来的并发问题也给这些语言和框架带来了更多的复杂性。而且,多线程模型中,多个线程的互相切换也会带来一定的性能开销。

所以,在提升I/O利用率这个方面上,Redis并没有采用多线程技术,而是选择了多路复用 I/O技术。

小结

Redis并没有在网络请求模块和数据操作模块中使用多线程模型,主要是基于以下四个原因:

  • 1、Redis 操作基于内存,绝大多数操作的性能瓶颈不在 CPU
  • 2、使用单线程模型,可维护性更高,开发,调试和维护的成本更低
  • 3、单线程模型,避免了线程间切换带来的性能开销
  • 4、在单线程中使用多路复用 I/O技术也能提升Redis的I/O利用率

还是要记住:Redis并不是完全单线程的,只是有关键的键值对读写是由一个线程完成的。

Redis的多路复用

为什么Redis设计成单线程也能这么快?

为什么Redis 6.0 引入多线程

为什么Redis 6.0引入了多线程?

原文: https://www.yuque.com/hollis666/xkm7k3/og6nf4