Redis是单线程还是多线程?

说Redis是单线程或者是多线程这种说法并不严谨,要拿版本说话,Redis的版本有很多3.x、4.x和6.x,版本不同架构也是不同的,不限定版本问是否单线程是不太严谨的。

  • 版本3.x,最早版本,此时Redis是单线程的
  • 版本4.x,严格意义来说此时Redis已经不是单线程了,而是负责处理客户端请求的线程是单线程,但是开始加了点多线程的东西(异步删除,aof)
  • 版本6.x,以及2022年出的7.0之后的版本,告别了大家印象中的额单线程,用一中全新的多线程来解决问题

开始为什么Redis只支持单线程?

Redis是单线程主要是指Redis的网络IO和键值对读写是由一个线程完成的,Redis在处理客户端的请求时包括获取(socket读)、解析、执行、内容返回(socket写)等都由一个顺序串行的主线程执行,这就是所谓的单线程,这也是Redis对外提供键值存储服务的主要流程。

但Redis的其他功能,比如持久化RDB、AOF、异步删除、集群数据同步等等,都是由其他额外的线程执行的,Redis命令工作线程是单线程的,但是对于Redis整体来说,它其实是多线程的。

Redis 3.x 单线程时代但性能依旧很快的原因?

  • 基于内存操作:Redis所有的数据都存在内存中,因此所有的运算都是内存级别的,多一他的性能比较高
  • 数据结构简单:Redis的数据结构是专门设计的,而这些简单的数据结构的查找和操作的时间大部分复杂度是O(1),因此性能比较高
  • I/O多路复用和非阻塞I/O:Redis使用I/O多路复用功能来监听多个socket连接客户端,这样就可以使用一个线程连接来处理多个请求,减少了线程切换带来的开销,同时也避免了I/O阻塞操作。(这个原因是Redis快最重要的原因)
  • 避免上下文切换:因为是单线程模型,因此就避免了不必要的上下文切换和多线程竞争,这就省去了多线程切换带来的时间和性能上的消耗,而且单线程不会导致死锁问题的产生

Redis 4之前一直使用单线程的原因?

  • 使用单线程模型是Redis的开发和维护更简单,因为单线程模型方便开发和调试
  • 即使使用单线程模型也并法的处理多客户端的请求,主要是IO多路复用和非阻塞IO
  • 对于Redis系统来说,主要的性能瓶颈是内存或者网络带宽而不是CPU

既然单线程这么好,为什么又要逐渐加入多线程的特性?

  • 硬件的发展:目前CPU早已经是多核时代了,如使用单线程会对硬件资源的使用十分不充分
  • 单线程存在的痛点如下:

例如正常情况下使用del命令很快就可以删除数据,而当被删除的key是一个非常大的对象时,例如包含了成千上万个元素的hash集合时,那么del指令就会造成redis主线程卡顿。这就是Redis 3.x单线程时代最经典的故障,大key删除的头疼问题

对于上面问题惰性删除 可以有效解决,于是在Redis4.0中就增加了多线程模块,当然此版本中的多线程主要是为了解决删除数据效率比较低的问题。

sql 复制代码
##异步删除
unlink k1
##异步清空库
flushdb async

将这些耗时的操作从主线程剥离让bio子线程来处理,极大减少主线程阻塞时间,从而减少删除导致性能和稳定性问题。

相关推荐
feifeigo1238 分钟前
升级到MySQL 8.4,MySQL启动报错:io_setup() failed with EAGAIN
数据库·mysql·adb
weixin_446122461 小时前
JAVA内存区域划分
java·开发语言·redis
火龙谷2 小时前
【nosql】有哪些非关系型数据库?
数据库·nosql
TT哇2 小时前
JavaEE==网站开发
java·redis·java-ee
焱焱枫2 小时前
Oracle获取执行计划之10046 技术详解
数据库·oracle
qq_392397124 小时前
Redis常用操作
数据库·redis·wpf
一只叫煤球的猫5 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
一只fish6 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(17)
数据库·mysql
花好月圆春祺夏安6 小时前
基于odoo17的设计模式详解---装饰模式
数据库·python·设计模式
A__tao6 小时前
SQL 转 Java 实体类工具
java·数据库·sql