单线程 Redis 的高性能之道

引言

Redis 以单线程模型处理网络请求与命令操作,却能在高并发场景下保持惊人的吞吐能力。这背后离不开三大基石:全内存存储 、高效数据结构 (哈希表、跳表等)以及 epoll 多路复用机制 ,让单线程能够高效处理海量连接。

随着 Redis 6.0 引入多线程 IO,网络读写被拆分给多个线程并行处理,进一步突破了网络瓶颈;而命令执行依然坚守单线程,避免了复杂并发控制,确保 Lua 脚本和事务的原子性。本文将从单线程的设计精髓,到主线程与 IO 线程的协作流程,深入浅出地解析 Redis 为何"又快又稳"。

单线程的Redis为什么这么快?

Redis 的单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。

并发访问设计困难

并发访问控制一直是多线程开发中的一个难点问题,如果没有精细的设计,比如说,只是简单地采用一个粗粒度互斥锁,就会出现不理想的结果:即使增加了线程,大部分线程也在等待获取访问共享资源的互斥锁,并行变串行,系统吞吐率并没有随着线程的增加而增加。

内存设计

Redis 所有数据都存储在内存中,相比于传统的基于磁盘的数据库,内存的读写速度非常快。

高效的数据结构

Redis 采用了高效的数据结构,如哈希表、跳表等,确保了数据操作的快速性。

避免了上下文切换

多线程编程往往会带来线程切换的开销,而线程切换不仅消耗 CPU 资源,还可能带来数据一致性问题。

多路复用机制

使用epoll去监控FD,一旦监测到 FD 上有请求到达时,就会触发相应的事件。这些事件会被放进一个事件队列,Redis 单线程对该事件队列不断进行处理。

Redis6.0多线程处理

Redis 的多线程只是用来处理网络请求的,对于读写命令,Redis 仍然使用单线程来处理。这是因为,Redis 处理请求时,网络处理经常是瓶颈,通过多个 IO 线程并行处理网络操作,可以提升实例的整体处理性能。而继续使用单线程执行命令操作,就不用为了保证 Lua 脚本、事务的原子性,额外开发多线程互斥机制了。这样一来,Redis 线程模型实现就简单了。

主线程和 IO 线程如何协作完成请求处理?

阶段一:服务端和客户端建立 Socket 连接,并分配处理线程

当有客户端请求和服务端建立 Socket 连接时,主线程会创建和客户端的连接,并把 Socket 放入全局等待队列中。紧接着,主线程通过轮询方法把 Socket 连接分配给 IO 线程。

阶段二:IO 线程读取并解析请求

主线程一旦把 Socket 分配给 IO 线程,就会进入阻塞状态(因为没有新的建立Socket请求所以阻塞),等待 IO 线程完成客户端请求读取和解析。因为有多个 IO 线程在并行处理,所以,这个过程很快就可以完成。

阶段三:主线程执行请求操作

等到 IO 线程解析完请求,主线程还是会以单线程的方式执行这些命令操作。

阶段四:IO 线程回写 Socket 和主线程清空全局队列

当主线程执行完请求操作后,会把需要返回的结果写入缓冲区,然后,主线程会阻塞等待 IO 线程把这些结果回写到 Socket 中,并返回给客户端。等到 IO 线程回写 Socket 完毕,主线程会清空全局等待队列,等待客户端的后续请求。

主线程分配socket给IO线程后以及IO线程把结果返回给客户端前主线程都会阻塞,那怎么提升性能?

主线程会一次性将多个接收请求分配给多个IO线程,然后一个死循环等待IO线程全部处理完毕,多个IO线程并发处理网络操作可以提升性能。


感谢您的阅读!如果文章中有任何问题或不足之处,欢迎及时指出,您的反馈将帮助我不断改进与完善。期待与您共同探讨技术,共同进步!

相关推荐
特立独行的猫A12 分钟前
用仓颉语言 cj-tauri 框架,五分钟给娃做了个鸿蒙形近字游戏
java·后端·python
码事漫谈3 小时前
我花了一周时间,看AI公司怎么"管"AI,结果越看越后背发凉
后端
爱学习的程序媛6 小时前
Python常用框架梳理
开发语言·后端·python·ai·web·后端框架·python框架
GISer_Jing6 小时前
Agent核心内容
后端·ai·langchain
时间的拾荒人6 小时前
Redis 主从复制详解:配置实操 + 原理机制
数据库·redis·面试
budingxiaomoli7 小时前
Spring统一功能处理
java·后端·spring
某鹏8 小时前
网关选型:Go、Java、Graal 谁都不能完胜
后端
用户0247836530978 小时前
从屎山到防线:14 行状态迁移表,给任务系统装上防瞎跳闸门
后端
CQU_JIAKE8 小时前
11.13[体系结构】指标,五级流水线,八级流水线,虚实地址思考
后端
panbook10 小时前
从0到1实现一个分布式时序数据库(三):主从复制、故障检测与切换
后端