关于Redis单线程问题

为什么说Redis是单线程的

误区: "通常说'Redis 是单线程的',指的是其核心的数据操作(命令执行)是单线程的 。实际上,Redis 内部还有后台线程(如 RDB/AOF 异步刷盘、Lazy Free 等)。从 Redis 6.0 开始,网络 I/O(接收请求、发送响应)和协议解析 可以启用多线程,但命令执行仍由主线程串行处理。"

一个计算机程序执行的过程中主要分为两种操作:分别是读写操作计算操作

注意: 这里的读写操作指的是网络请求**(** I/O操作 ) ,计算操作指的是数据处理操作**(涉及到CPU)**

先说下 多线程 的适用场景

**前情提要:**一个计算机程序执行过程中主要分为两个操作:分别是读写操作和计算操作

其中读写操作涉及到的就是I/O操作,计算操作涉及到的是CPU

多线程 的目的就是通过并发的方式提高 I/O 和CPU的利用率

但是Redis不需要利用多线程的方式来提高I/O和CPU的利用率

为什么呢?

关于CPU的利用率

由于Redis是基于内存存储的,所以它的操作非常快,CPU根本来不及成为瓶颈;

❤️ 先理解:什么是"基于 内存 存储"?🧠

🔹 内存 vs 磁盘的速度对比:

|---------|----------|-------------------|
| 存储类型 | 访问速度 | 举个例子 |
| 内存(RAM) | ~100 ns | 读一个字节 ≈ 1/1000 秒 |
| 磁盘(HDD) | ~10 ms | 读一个字节 ≈ 1/100 秒 |
| SSD | ~100 μs | 读一个字节 ≈ 1/10000 秒 |

👉 内存比磁盘快上万倍!


关于 I/O 利用率

I/O的利用率确实是Redis的瓶颈,但是不一定要通过多线程的方式来解决(😂虽然6.0版本还是使用了多线程方式解决,不过需要手动开启不然用的还是多路复用I/O技术(下面开始讲)

为什么不用 多线程 来解决这个问题呢?

因为虽然采用多线程技术可以帮助我们解决提高I/O和CPU利用率的问题,但是多线程带来的并发问题也给我们带来了更多的复杂性**(比如:我们平常用到的编程语言都有用到多线程技术,我们都会遇到** 线程安全 问题比如调用某个方法时,我们应该如何保证共享变量的正确性,如果正确处理多个线程之间的共享变量)。而且多线程模型,多个线程的上下文切换也会有性能的开销

所以Redis使用的是多路复用 I/O 技术保证的I/O利用率

多路复用 I/O **技术:**将进程的请求都放入一个管道当中,这个管道会统一和内核进行交互,当管道中的某一个请求的数据准备好之后,进程再把相应的数据拷贝到用户空间


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

其实前面就已经说过在6.0版本网络请求模块已经变成多线程的了,但是数据处理模块还是单线程的

虽然Redis的性能已经很高,已经可以满足绝大多数的应用了,但是不可避免地是大公司的数据量都是很大的,所以为了QPS都会部署Redis集群,但是这种做法是很耗资源的。

其实主要还是多路复用I/O技术产生的问题,我们都知道多路复用I/O技术是将进程的请求都放入管道中,但这种模型,是同步阻塞型I/O模型

多路复用I/O模型在处理网络请求的过程是阻塞的,也就是说这个过程会阻塞线程,如果并发量很高此处会成为瓶颈。

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

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

那么引入 多线程 之后不会造成 线程安全 问题吗?

前面其实也说过了只是对网络请求模块使用多线程模块,对数据处理模块并没有使用多线程

相关推荐
威风少侠9 小时前
Redis集群配置优化指南
数据库·redis·缓存
企鹅郁金香9 小时前
Gitlab和Gerrit部署后的工作(二)
数据库·gitlab·gerrit域名无法修改·激活gitlab·gitlab注册ldap·nginx反向代理gitlab·nginx反向代理gerrit
悄悄敲敲敲9 小时前
MySQL表的内外连接
数据库·mysql
kaico20189 小时前
MYSQL的各版本对比
数据库·mysql
zgl_200537799 小时前
ZGLanguage 解析SQL数据血缘 之 Python提取SQL表级血缘树信息
大数据·数据库·数据仓库·hive·hadoop·python·sql
rgeshfgreh10 小时前
Python函数全解析:定义、参数与作用域
前端·数据库·python
亮子AI10 小时前
【MySQL】node.js 如何判断连接池是否正确连接上了?
数据库·mysql·node.js
Chef_Chen10 小时前
数据科学每日总结--Day41--ubuntu安装tailscale
数据库·ubuntu·postgresql
a程序小傲10 小时前
【Node】单线程的Node.js为什么可以实现多线程?
java·数据库·后端·面试·node.js