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子线程来处理,极大减少主线程阻塞时间,从而减少删除导致性能和稳定性问题。

相关推荐
jamesge20109 分钟前
如何构建SAAS项目
数据库
Mr数据杨44 分钟前
解决整合Django与Jinja2兼容性的问题
数据库·django·sqlite
Adolf_199344 分钟前
Django中 model 一对一 一对多 多对多关系 关联
数据库·django·sqlite
ueanaIU潇潇子1 小时前
idea根据实体类生成数据库表
数据库·mysql·intellij-idea·实体类生成数据库
爱读源码的大都督1 小时前
PostgreSQL数据库中Sequence的使用详解
数据库·后端·架构
呆呆小雅6 小时前
C# 可空类型
数据库·oracle·c#
Duck Bro7 小时前
MySQL:常用数据类型
java·数据库·c++·mysql·java-ee
z千鑫7 小时前
【C/C++】数据库链接入门教程:从零开始的详细指南!MySQL集成与操作
c语言·数据库·c++
开敲7 小时前
【MySQL】MySQL数据库基础
数据库·mysql
痞老板A小安装C47 小时前
Redis 过期策略和内存淘汰策略
数据库·redis·缓存