找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

5025

积分

1

好友

696

主题
发表于 3 天前 | 查看: 18| 回复: 0

根据官方数据,Redis 的每秒请求数(Qequests Per Second,QPS)可以达到 100000。

Redis QPS 性能折线图

01 基于内存实现

读、写操作都是在内存上完成的,内存直接由 CPU 控制,也就是由 CPU 内部集成内存控制器,所以说内存是直接与 CPU 对接的,享受与 CPU 通信的“最优带宽”。

Redis 将数据存储在内存中,读/写操作不会被磁盘的 I/O 速度限制。如下图是磁盘操作调用栈,每一次数据访问都需要穿越复杂的 系统调用 与驱动层,这自然无法与直接的内存访问速度相提并论。

磁盘 I/O 操作调用栈流程图

02 I/O 多路复用模型

Redis 采用 I/O 多路复用 技术并发处理连接,其核心是 epoll 加上自己实现的简单事件框架。

它将 epoll 中的读、写、关闭、连接都转化成事件,再利用 epoll 的多路复用特性,绝不在 I/O 上浪费一点时间。这里的“多路”指的是多个网络连接,“复用”指的是复用同一个线程。多路复用技术主要有 select、poll 和 epoll 三种,Redis 选择了性能更优的 epoll。

epoll 的基本原理是,内核不再轮询应用程序的所有连接,而是只监视应用程序关心的文件描述符上的事件。当客户端产生事件时,服务器端的 I/O 多路复用模块会将对应的 socket 放入队列,然后通过文件事件分派器将其转发到相应的事件处理器。

I/O 多路复用与事件分发架构图

正因如此,Redis 的主线程不会阻塞在某个特定的客户端连接上,从而可以高效地同时与多个客户端交互,极大地提升了 高并发 处理能力。想深入了解网络模型和性能优化,可以到 网络/系统 板块交流探讨。

03 单线程模型

你可能会问,为什么 Redis 不采用多线程来并行执行命令,以充分利用多核 CPU 呢?

这里需要明确:Redis 的单线程,指的是其核心的网络 I/O 以及键值对命令的读/写是由一个主线程串行执行的。而像持久化、集群数据同步、异步删除(惰性删除)等操作,则是由其他后台线程或子进程执行的。

需要注意的是,Redis 从 6.0 版本开始引入了 I/O 多线程,但这里的多线程仅用于处理网络数据的读和写,命令的解析与执行依然是单线程的。

使用多线程通常能提升系统吞吐量,但这并非没有代价。如下图,线程数增加到一定程度后,吞吐量可能不再增长,甚至因上下文切换开销而下降。

线程数量与系统吞吐量关系图

Redis 早期坚持核心路径单线程设计,主要基于以下几点考量:

  • 避免频繁创建、销毁线程的性能损耗。
  • 杜绝了线程间上下文切换带来的额外 CPU 开销。
  • 从根本上规避了多线程环境下的竞争问题,如加锁、解锁、死锁等,使得 数据结构 内部实现可以无锁化,代码更简洁高效。
  • 对于 Redis 而言,性能瓶颈往往在于内存大小和网络带宽,而非 CPU 计算能力。

04 高效的数据结构

除了内存和模型,速度也离不开精巧的底层数据结构。这里说的不是 Redis 对外提供的 String、List、Hash、Set、Sorted Set 这五种数据类型,而是它们内部的具体实现。

为了在性能和内存占用之间取得最佳平衡,同一种数据类型在不同条件下,底层可能会采用不同的数据结构。例如,新版本的 List 可能采用 quicklist 或 listpack,而 Hash 在元素较少时会使用更紧凑的编码。

Redis 数据类型与底层数据结构对应关系图

这些底层数据结构,如 SDS(简单动态字符串)、跳表(skiplist)、压缩列表(ziplist,已被 listpack 替代)等,都经过了极致优化,以实现高效的增删改查操作。关于更多 数据库 与中间件的底层奥秘,数据库/中间件/技术栈 板块有很多深度讨论。

05 全局散列表

Redis 使用一个全局的哈希表来管理所有的键值对。这个哈希表本质就是“数组 + 链表”的结构,数组中的每个槽位称为哈希桶,每个桶里的 entry 保存着指向实际键(key)和值(value)的指针。

键总是字符串类型,而值可以是五种数据类型中的任意一种。其结构如图所示:

Redis 全局哈希表结构示意图

全局哈希表使得根据键查找值的时间复杂度接近 O(1)。通过计算键的哈希值,可以直接定位到对应的哈希桶,进而找到数据,这是 Redis 响应迅速的另一个关键。

06 Redis I/O 多线程模型

我们已经知道,Redis 凭借全局哈希表、纯内存操作、高效数据结构、单线程命令处理及 I/O 多路复用模型,获得了卓越的性能。

但随着网络硬件性能的飞速提升,特别是在高并发场景下,单个线程处理网络读/写的速度开始跟不上网卡的数据吞吐能力。网络 I/O 的系统调用逐渐成为主要 CPU 消耗点。

因此,Redis 在 6.0 版本正式引入了 I/O 多线程模型核心要义是:这个多线程仅用于分担网络数据的读取和发送(即 socket 的读/写)负载,而命令的解析、执行依然由单线程负责,从而保证了原子性和无锁操作的 simplicity。

主线程与 I/O 线程协同工作的流程大致如下图所示:主线程负责接收连接、分发任务,I/O 线程并行进行网络读/写,最后由主线程串行执行命令并写回结果。

Redis 6.0 多I/O线程协作架构图

这个设计是对原有高性能架构的精妙扩展,旨在解决特定瓶颈,而非颠覆其核心设计哲学。




上一篇:Redis安装部署与五大核心数据结构详解(CentOS 7实战)
下一篇:Redis 面试题 2023 版|40+ 高频考点与原理图解(含线程模型、持久化、集群、缓存设计)
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-7 20:58 , Processed in 0.721865 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表