Redis线程模型讨论

  很多人常说,因为 Redis 是单线程的,所以它的操作就快、性能就好。但其实这个表述并不完全准确,因为 Redis 作为一个成熟的分布式缓存框架,它由很多模块组成,如网络请求模块、数据操作模块、存储模块、索引模块、高可用集群支撑模块等,除了网络请求模块和数据操作模块是单线程处理,其他模块都是多线程的,比如,Redis 中会有很多后台进程异步处理一些耗时较长的操作,如处理关闭文件、AOF 刷盘等。

  并且在 Redis 6.0 版本开始,网络请求模块也被设计成了多线程。

  也就是说,Redis 6.0 之前,Redis 中只有网络IO、读写命令的执行是单线程的(主线程),其他的处理操作都是多线程。

 

  在了解了上述知识后,接下来就对以下问题展开谈论。

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

  一个计算机程序在执行的过程中,主要需要进行两种操作分别是读写操作、计算操作。其中读写操作主要是涉及到的就是I/O操作,其中包括网络I/O和磁盘I/O;计算操作主要涉及到CPU。

  而对于 Redis 来说,其操作都是基于内存的,所以 CPU 并不是制约其性能的瓶颈,更多情况下是受到内存大小和I/O操作的限制。因此,要想提高 Redis 的性能,就必须提升 Redis 对 I/O 的利用率。

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

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

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

小结:

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

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

二、I/O多路复用技术

  Redis 通过I/O多路复用技术来监听大量的客户端连接,以此提升网络I/O的利用率,而且这种方式可以避免使用多线程来监听客户端连接,降低了资源的消耗。

  Redis 基于 Reactor 模式开发了自己的网络事件处理器:这个处理器被称为文件事件处理器(file event handler)。文件事件处理器使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。

  当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

  虽然文件事件处理器以单线程方式运行,但通过使用 I/O 多路复用程序来监听多个套接字,文件事件处理器既实现了高性能的网络通信模型,又可以很好地与 Redis 服务器中其他同样以单线程方式运行的模块进行对接,这保持了 Redis 内部单线程设计的简单性。

  可以看出,文件事件处理器(file event handler)主要是包含 4 个部分:

  • 多个 socket(客户端连接)
  • IO 多路复用程序(支持多个客户端连接的关键)
  • 文件事件分派器(将 socket 关联到相应的事件处理器)
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

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

  通过上述分析,我们得出 Redis 基于单线程使用I/O多路复用技术大大提升了网络I/O利用率,使得 Redis 命令执行快,但远不止这个原因。

  Redis 之所以如此快,主要有以下几个方面的原因:

  • 基于内存:Redis 是一种基于内存的数据库,数据存储在内存中,数据的读写速度非常快,因为内存访问速度比硬盘访问速度快得多。
  • 单线程模型:Redis 使用单线程模型,这意味着它的所有操作都是在一个线程内完成的,不需要进行线程切换和上下文切换。这大大提高了 Redis 的运行效率和响应速度。
  • 多路复用 I/O 模型:Redis 在单线程的基础上,采用了I/O 多路复用技术,实现了单个线程同时处理多个客户端连接的能力,从而提高了 Redis 的并发性能。
  • 高效的数据结构:Redis 提供了多种高效的数据结构,如哈希表、有序集合、列表等,这些数据结构都被实现得非常高效,能够在 O(1) 的时间复杂度内完成数据读写操作,这也是 Redis 能够快速处理数据请求的重要因素之一。
  • 多线程的引入:在Redis 6.0中,为了进一步提升IO的性能,引入了多线程的机制。采用多线程,使得网络处理的请求并发进行,就可以大大的提升性能。多线程除了可以减少由于网络 I/O 等待造成的影响,还可以充分利用 CPU 的多核优势。

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

  虽然 Redis 的主要工作(网络 I/O 和执行命令)一直是单线程模型,但是在 Redis 6.0 版本之后,也采用了多个 I/O 线程来处理网络请求,这是因为随着网络硬件的性能提升,Redis 的性能瓶颈有时会出现在网络 I/O 的处理上。

  所以为了进一步提高网络 I/O 的利用率,Redis 6.0 对于网络 I/O 采用多线程来处理,但是对于数据的读写命令,仍然是单线程处理的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/2692.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Spring Boot实现中医医学处方管理实践

基于Spring Boot实现中医医学处方管理 以下是基于Spring Boot实现中医医学处方管理的相关示例和资源整理,涵盖基础架构、功能模块及实际应用案例: 基础项目结构 Spring Boot中医处方系统通常采用MVC分层设计: 实体类:定义处方、药材、患者等JPA实体 @Entity public clas…

中宇联:以“智云融合+AI”赋能全栈云MSP服务,深化阿里云生态合作

作为国内领先的全栈云MSP服务商,中宇联依托自主研发的“智云融合AI”服务平台,为企业提供涵盖云架构设计、迁移实施到云优化服务等内容的端到端解决方案,助力客户高效利用云端资源、实现业务创新。一、中宇联云MSP服务能力全景中宇联以混合云…

分布式微服务--万字详解 微服务的各种负载均衡全场景以注意点

前言:1. 使用方式分类总览序号使用形式是否基于服务名调用是否需 LoadBalanced备注1RestTemplate 自定义负载均衡❌ 否(手动拼接URL)❌ 否手动选择服务实例2RestTemplate Ribbon(非服务名)❌ 否(手动拼接…

Netty的Http解码器源码分析

一、HTTP协议简介HTTP(HyperText Transfer Protocol,超文本传输协议)是一种基于 请求-响应模型 的无状态应用层协议,广泛用于客户端(如浏览器)和服务器之间的数据通信。其主要特点包括:基于 TCP…

磁盘io查看命令iostat与网络连接查看命令netstat

1. iostat的使用场景首先iostat命令隶属于sysstat软件包。iostat专门用来查看主机上每个磁盘设备的io情况,包括像每秒的读写数据情况,磁盘平均io时间,设备io繁忙情况等等。1.1 iostat的普通输出解释首先是主机的架构,主机名&#…

Linux ps -ef 命令解析

ps 是 Linux 系统中用于查看进程状态的标准命令,-ef 是其参数组合,用于输出系统范围内所有进程的完整信息。以下是对该参数的详细解析: 1. 核心参数含义-e表示显示所有进程(包括系统进程和用户进程),相当于…

2025年湖北中级注册安全工程师报考那些事

2025年湖北中级注册安全工程师报考那些事各位从事建筑安全的人员看过来,注册安全工程师是你们行业认可度较为高的证书。关于报考无论是安全相关专业跟不相关的专业都是可以报考的。只是年份要求不同。 本科:相关专业3年,不相关专业4年。 专科…

容器与虚拟机的本质差异:从资源隔离到网络存储机制

目录 专栏介绍 作者与平台 您将学到什么? 学习特色 容器与虚拟机的本质差异:从资源隔离到网络存储机制 一、容器与虚拟机的本质区别 1.1 资源抽象层次差异 1.2 资源消耗与性能对比 1.3 隔离性深度差异 二、容器网络基础架构 2.1 Docker网络模型…

FPGA实现SRIO高速接口与DSP交互,FPGA+DSP异构方案,提供3套工程源码和技术支持

目录1、前言:SRIO在FPGADSP架构中的作用工程概述免责声明2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目我这里已有的FPGADSP异构方案我这里已有的 GT 高速接口解决方案3、工程详细设计方案工程设计原理框图FPGA端工程源码FPGA端SRIO从…

网络安全第15集

前言: 挖不到一点,又来学习了 内容: 1、根据端口扫描可以得到相关的信息 端口扫描,根据扫描的端口, 可以得到目标服务器开启的应用服务器,的具体相关信息,数据库的相关信息 web服务器&…

【Linux】重生之从零开始学习运维之Mysql事务

事务开启事务begin;提交事务commit;select * from stu;事务回滚begin; select * from stu; update stu set age100 where id10; select * from stu; rollback;事务保存点rollback to p2; rollback to p1;因回到p1,无后面记录,所以无法回到p2、p3保存点。…

深入理解Java Map的entrySet()方法

文章目录深入理解Java Map的entrySet()方法一、entrySet()方法概述二、为什么需要entrySet()三、entrySet()的核心特性四、Map.Entry接口详解五、entrySet()的典型使用场景1. 遍历Map2. 批量修改值3. 过滤Map4. 并行处理六、性能考虑七、Java 8的增强八、注意事项九、总结深入理…