Skip to content

Redis 基础与原理

Redis 是什么

Redis 是一个基于内存的高性能 Key-Value 数据库,常用于缓存、计数器、排行榜、分布式锁、限流、消息队列和会话存储。

它的核心特点是:数据主要放在内存里,读写很快;支持 String、Hash、List、Set、ZSet、Bitmap、HyperLogLog、Geo、Stream 等丰富数据结构;支持 RDB / AOF 持久化、主从复制、哨兵和 Cluster 高可用方案。

Redis 和 MySQL 有什么区别

MySQL 是关系型数据库,核心目标是可靠存储和复杂查询;Redis 是内存型 NoSQL 数据库,核心目标是高性能读写和灵活的数据结构。

对比项RedisMySQL
数据模型Key-Value,多种内置结构表、行、列、关系模型
主要存储内存为主,可持久化到磁盘磁盘为主,Buffer Pool 缓存热点页
查询能力按 key 访问,复杂查询弱SQL、JOIN、事务、索引优化
性能特点单 key 读写非常快更重视一致性、事务和复杂查询
典型场景缓存、锁、计数、排行榜、限流订单、用户、交易等核心业务数据

项目里通常是 MySQL 存最终数据,Redis 存热点副本、临时状态或高并发访问数据。Redis 不能直接替代 MySQL,因为它缺少完整关系模型、复杂查询能力和强事务能力。

项目中一般 Redis 用来做什么?什么业务场景会选择使用 Redis?为什么选择 Redis 而不是其他缓存

常见用途:

  • 缓存热点数据:例如用户信息、商品详情、配置字典,降低 MySQL 压力。
  • 分布式锁:例如防止重复提交、库存扣减串行化。
  • 计数器:例如浏览量、点赞数、接口调用次数。
  • 排行榜:用 ZSet 按 score 排序。
  • 限流:用计数器、滑动窗口或 Lua 脚本保证原子性。
  • 消息队列 / 延迟队列:List、Stream、ZSet 都可以做不同形态的队列。
  • 会话共享:多实例服务共享登录态或临时状态。

选择 Redis 的原因主要是性能高、数据结构丰富、生态成熟、支持持久化和高可用。相比本地缓存,Redis 能跨服务共享;相比 Memcached,Redis 数据结构更多,还支持持久化、复制、Lua 和更完整的集群方案。

Redis 是单线程,为什么还这么快

Redis 的“单线程”主要指命令执行线程是单线程,不代表所有工作都只有一个线程。它快的原因有四个:

  1. 基于内存:绝大多数操作不需要磁盘随机 IO。
  2. 单线程执行命令:避免多线程锁竞争和上下文切换。
  3. I/O 多路复用:一个线程可以同时处理大量客户端连接。
  4. 数据结构高效:SDS、dict、quicklist、skiplist 等结构针对常见场景做了优化。

不过 Redis 不适合执行耗时命令。比如大 key 的 hgetallsmemberskeys 都可能阻塞事件循环,导致其他请求排队。

Redis 的 I/O 多路复用原理是什么

Redis 使用 I/O 多路复用同时监听多个 socket。当某个连接可读或可写时,事件循环才处理对应事件,不需要为每个连接创建一个线程。

在 Linux 上常见实现是 epoll。它的思路是:Redis 把多个客户端连接注册给内核,内核发现某些连接有事件后通知 Redis,Redis 再依次读取请求、执行命令、写回响应。

这套模型的好处是连接数很多时也不需要大量线程,资源开销低。真正要注意的是命令执行本身仍然要快,否则一个慢命令会拖住后面的请求。

Redis 6.0 之后引入了多线程?一定比单线程快吗

Redis 6.0 引入的是网络 I/O 多线程,主要用于并行处理读写 socket、协议解析等网络相关工作。命令执行默认仍然是单线程,避免并发修改数据结构带来的锁复杂度。

它不一定比单线程快。只有在网络 I/O 成为瓶颈、实例 CPU 还有空闲、请求量足够大时,多线程才明显有收益。如果瓶颈在慢命令、大 key、持久化 fork、内存或业务访问模式,多线程 I/O 不能根治问题。