Redis复习----------Redis超高性能的原因

Redis 之所以能达到十万级甚至百万级 QPS 的超高性能,是从架构设计、数据存储、执行模型、底层细节四个维度深度优化的结果,每一个环节都围绕 "减少开销、提升效率" 展开。

一、核心架构:单线程 + 非阻塞 I/O 模型,规避多线程性能损耗

Redis 的核心命令执行逻辑(redis-server 的主线程)是单线程 的,这是它高性能的基石,同时结合 I/O 多路复用 技术处理并发连接,完美解决了 "单线程并发低" 的问题。

1. 单线程的优势:无线程切换与锁竞争开销

(1)避免上下文切换:多线程模型中,CPU 需要在多个线程间切换,保存 / 恢复线程的寄存器、栈信息,这会消耗大量 CPU 资源。Redis 单线程全程只执行一个任务流,没有切换成本。

(2)无锁竞争问题:多线程操作共享数据时,需要加锁(如互斥锁、读写锁)来保证线程安全,锁的获取、释放会带来额外开销,甚至可能引发死锁。Redis 单线程天然保证命令的原子性执行,无需加锁。

注意:Redis 6.0 引入了多线程 I/O,但仅用于处理网络请求的读写(如 socket 的 read/write 操作),核心的命令执行逻辑仍然是单线程,目的是提升大报文场景下的网络吞吐量,而非改变单线程执行模型。

2. 非阻塞 I/O + 多路复用:单线程处理上万并发连接

Redis 基于 ae 事件驱动框架 (自主实现),整合了 epoll(Linux)、kqueue(BSD)、select 等多路复用技术,其核心原理是:

(1)主线程通过一个事件循环,同时监听多个客户端的 socket 连接的 "读事件""写事件";

(2)当 socket 有数据可读 / 可写时,才触发对应的处理逻辑,而非阻塞等待;

(3)多路复用技术可以让单线程高效管理数万甚至数十万的并发连接,且资源消耗极低(远低于多线程模型)。

二、存储层:纯内存操作,摆脱磁盘 I/O 瓶颈

这是 Redis 快的最根本原因 ------ 数据全部存储在内存中,内存与磁盘的读写速度差距达到千倍甚至万倍:

存储介质 读写延迟 带宽
内存 纳秒级(~10ns) GB/s 级别
机械硬盘 毫秒级(~10ms) MB/s 级别
SSD 硬盘 微秒级(~100μs) 数百 MB/s 级别

(1)内存操作的低延迟:

Redis 的所有命令(如 GET/SET/HGET)都是直接操作内存中的数据结构,无需磁盘寻址、磁头转动等耗时操作;

(2)持久化不影响性能:

1.RDB:通过子进程生成内存快照,主线程不参与;

2.AOF:写命令先写入内存缓冲区,再由后台线程异步刷盘;

3.持久化操作与核心命令执行完全解耦,不会阻塞主线程,虽然Redis 支持 RDB、AOF 两种持久化方式,但都是异步执行的:

三、数据结构:定制化高效实现,兼顾性能与内存

Redis 没有直接使用 C 语言的原生数据结构(如链表、哈希表),而是针对缓存场景定制了轻量化、高性能的专属数据结构,在时间复杂度和空间复杂度上做到极致优化:

1. 基础数据结构的定制优化
Redis 类型 底层数据结构 核心优化点
String 简单动态字符串(SDS) 1. 预分配空间:扩容时预留冗余空间,减少内存重分配次数;2. 二进制安全:支持存储图片、视频等二进制数据;3. 记录长度:O (1) 获取字符串长度,无需遍历。
Hash 压缩列表(ziplist)→ 哈希表 1. 小数据量用 ziplist:连续内存存储,减少内存碎片和指针开销;2. 大数据量自动切换哈希表:查询 / 插入 / 删除 O (1) 复杂度。
List 压缩列表(ziplist)→ 双向链表 1. 双向链表支持首尾 O (1) 插入 / 删除;2. 配合 ziplist 优化小数据场景的内存占用。
Set 整数集合(intset)→ 哈希表 1. 元素为整数且数量少时用 intset:紧凑存储,无需哈希表的指针开销;2. 元素复杂时切换哈希表:保证 O (1) 去重和查询。
ZSet 压缩列表(ziplist)→ 跳表 + 哈希表 1. 跳表:查询 / 插入 / 删除平均 O (log n) 复杂度,实现简单(比红黑树少了旋转操作);2. 哈希表:O (1) 获取元素的 score 值;3. ziplist 优化小数据场景。
2. 高级数据结构的针对性设计

(1)Bitmaps:基于 String 实现,用一个二进制位表示一个状态,1MB 内存可存储 800 多万个状态,极大节省内存;

(2)HyperLogLog:固定占用 12KB 内存,实现海量数据的基数统计,无需存储具体元素;

(3)Geo:基于 ZSet 实现,将经纬度编码为 52 位整数作为 score,复用跳表的有序性实现范围查询。

四、执行层:极简命令流程,减少不必要的开销

Redis 的命令执行流程被极度精简,从 "请求接收" 到 "响应返回" 的每一步都没有冗余操作:

1. 无内核态 / 用户态切换的额外开销(部分场景)

Redis 的网络模型基于用户态的 I/O 多路复用,无需频繁切换到内核态处理 socket 读写,减少了系统调用的开销。

2. 命令的高效解析与执行

(1)命令协议简单 :Redis 采用 RESP 协议(Redis Serialization Protocol),这是一种简单的文本协议,解析速度极快,相比 JSON、Protobuf 等复杂协议,CPU 开销更低;

(2)命令执行无复杂逻辑 :Redis 的命令大多是原子性的简单操作(如 INCR/HGET),没有事务回滚、复杂查询优化等耗时逻辑;

(3)避免数据拷贝:在处理命令时,Redis 尽量减少内存数据的拷贝(如使用指针直接操作数据)。

五、其他细节优化

  1. 批量操作支持 :提供 MSET/HMSET/PIPELINE 等命令,允许客户端一次性发送多个命令,减少网络往返次数(网络延迟是分布式场景的主要瓶颈之一);

  2. CPU 亲和性:Redis 支持设置 CPU 亲和性,将进程绑定到指定的 CPU 核心,避免 CPU 缓存失效(多核 CPU 中,进程切换核心会导致缓存数据丢失);

  3. 底层代码优化:Redis 核心代码用 C 语言编写,执行效率接近硬件原生性能,且代码精简(核心代码量不大),减少了不必要的函数调用和分支判断。

总而言之,Redis 的高性能是 "单线程非阻塞 I/O + 纯内存存储 + 定制化数据结构 + 极简执行流程" 四重优势叠加的结果。每一个设计决策都围绕 "减少开销、提升效率" 展开,最终实现了远超传统磁盘数据库的性能表现。

相关推荐
CJi0NG17 分钟前
【自用】MySQL-多表查询
数据库·mysql
smartpi_ai21 分钟前
51 单片机写好了,大模型语音怎么接?17T 全驱动的现成方案、双板串口分工的边界与画板前的三项硬件确认
单片机·嵌入式硬件·学习
雨落在了我的手上23 分钟前
MySQL数据库基础(12):事务
数据库·mysql
D姐聊门店26 分钟前
门店收银系统断网兜底怎么设计:本地账本、离线续传与日终对账的工程实现
数据库·saas
用户86629784800844 分钟前
抓包看 KingbaseES 内部协议?官方给了个现成工具
数据库
wefg11 小时前
【Redis】安装与启动
数据库·redis·缓存
大圣编蚕1 小时前
常见的 Redis 面试题(高频整理)
数据库·redis·缓存
辣知1 小时前
辣知·化智82 人类文明演化规律文化传承
学习
派小心.2 小时前
网站统计采样数据的误差核对
大数据·服务器·前端·数据库·人工智能·小程序·数据分析
龙腾AI白云2 小时前
数字孪生、具身智能、世界模型三者交叉
数据库·人工智能·机器学习·flask·pygame