> 技术文档 > Redis 为什么那么快?_redis为什么快

Redis 为什么那么快?_redis为什么快

Redis 为什么那么快?_redis为什么快

前言:

本文从redis的架构设计、存储方式、数据类型、网络io模型等各个方面,分析描述了redis为什么那么快的原因,来帮助大家更好的了解与使用redis,而不仅仅只限于会用它。
------------------------------------------------空行------------------------------------
当我们更多的理解它的一些基础原理时,在实践中才能更好的应用它(当然了,遇到面试时也有一些谈论的基础)

Redis快的原因:

1. 纯内存存储

  • Redis把所有数据都存储在内存中,访问数据不需要磁盘IO(像MySQL那样需要磁盘寻址)。

  • 内存的访问速度通常是磁盘的10万倍以上。

  • 举例:MySQL 读写依赖磁盘;Redis 直接从内存中读写,访问延迟可以低至 微秒级(<1ms)。


2. 单线程+IO多路复用模型

  • Redis 使用单线程架构(从6.0开始支持多线程IO但核心处理仍为单线程),避免了线程切换和锁竞争。

  • 采用高效的事件处理机制(epoll/kqueue),一次监听多个事件。

  • 单线程并不慢,反而更稳定、预测性强,适用于内存型轻量任务。


3. 高效的数据结构

Redis 提供多种高性能内存数据结构:

String、List、Set、Hash、ZSet(有序集合)、Bitmap、HyperLogLog、Geo等。

这些结构针对特定场景高度优化,操作复杂度低(如 O(1)、O(logN))。

redis不同数据类型的使用场景讲解(点击跳转查看具体信息)

比如:Hash 类型支持超快速的键值对查找、更新,适合对象缓存

4. 使用高效的底层实现语言(C)

Redis 使用 C 语言开发,最大化发挥了系统资源性能。

对内存管理、数据结构优化非常深入。

5. 避免了 SQL 解析等复杂逻辑

Redis 使用命令行接口(RESP协议),如 GET key、HSET key field value,无需 SQL 解析器。

这使得命令处理更轻更快。

6. 流水线技术(Pipeline)

Redis 支持批量命令执行,多个命令一起发送,减少网络延迟成本。

7. 持久化策略灵活(RDB / AOF)

Redis 支持按需选择持久化方式:

  • RDB:快照方式,定期保存内存状态。

  • AOF:日志方式,记录操作命令。

主流程不会阻塞持久化操作,减少IO影响。

8. 优秀的缓存淘汰机制

支持多种淘汰策略(LRU、LFU、TTL、随机等),内存控制精准,避免OOM崩溃。

📊 Redis 相比 MySQL 等关系型数据库的优势

比较维度 Redis MySQL 等关系型数据库 存储方式 全内存存储 磁盘存储 访问速度 极快(微秒级) 较慢(毫秒级) 数据结构 丰富的结构,操作灵活 基本仅支持表结构 事务支持 基础事务支持(MULTI/EXEC) 完整的ACID事务 扩展性 原生支持集群、主从 横向扩展较复杂 使用场景 高速缓存、排行榜、会话、计数器、消息队列等 关系建模、复杂查询、强事务一致性 持久化 可选开启,轻量 默认强持久性 复杂查询 不支持SQL查询、多表 JOIN 强大的 SQL 支持,查询复杂业务逻辑 开发难度 使用简单,命令直接操作 SQL语法学习成本更高

✅ 总结

Redis 的快,来自它的架构设计:

“尽可能地少做事情,尽可能地用最快的方式做。”

适合场景:

  • 高并发读写

  • 缓存系统

  • 实时排行榜

  • 限流计数器

  • 消息队列

不适合场景:

  • 复杂事务

  • 大体量数据存储

  • 多表关联查询

✅ 简单的实践与使用

✅ 一、使用推荐:Go Redis 客户端

推荐使用(我们项目上也用这个):github.com/redis/go-redis/v9
想了解go中gorm适配各类国产数据库,再与redis一起封装成调用db包,可以看我另外一篇文章,点击跳转即可

安装:

go get github.com/redis/go-redis/v9

初始化客户端:

import ( \"context\" \"github.com/redis/go-redis/v9\")var ctx = context.Background()var rdb = redis.NewClient(&redis.Options{ Addr: \"localhost:6379\", Password: \"\", // 没有密码可以留空 DB: 0, // 默认 DB 0})

✅ 二、典型使用场景 + 实战示例(这个部分其实是不计划写的,因我我另外一篇文章已经详细的描述的 redis的各种数据类型与使用场景–点击)

🌟 1. 缓存系统(如用户信息缓存)

func SetUserCache(userID string, data string) error { return rdb.Set(ctx, \"user:\"+userID, data, time.Minute*30).Err()}func GetUserCache(userID string) (string, error) { return rdb.Get(ctx, \"user:\"+userID).Result()}

最佳实践:

  • key命名规范:模块:业务:ID

  • 设置合理 TTL

  • 优先缓存热点数据,非热点用懒加载

🔒 2. 分布式锁

func TryLock(key string, ttl time.Duration) (bool, error) { return rdb.SetNX(ctx, key, \"locked\", ttl).Result()}func Unlock(key string) { rdb.Del(ctx, key)}
进阶推荐:

使用 Redlock
分布式锁算法,保障多实例下的安全性。可以借助:github.com/bsm/redislock

📈 3. 计数器 / 限流器

func IncreaseCounter(key string) (int64, error) { return rdb.Incr(ctx, key).Result()}func ResetCounter(key string) error { return rdb.Del(ctx, key).Err()}
应用场景:
  • 接口限流
  • 活动 PV/UV 统计
  • 用户行为计数(点赞、浏览)

🧮 4. 排行榜(ZSet 有序集合)

func AddScore(user string, score float64) error { return rdb.ZAdd(ctx, \"leaderboard\", redis.Z{ Score: score, Member: user, }).Err()}func GetTopUsers(n int64) ([]string, error) { return rdb.ZRevRange(ctx, \"leaderboard\", 0, n-1).Result()}

📬 5. 消息队列(List 实现)

func PushMessage(queue string, msg string) error { return rdb.RPush(ctx, queue, msg).Err()}func PopMessage(queue string) (string, error) { return rdb.LPop(ctx, queue).Result()}

🧰 三、最佳实践建议总结(重点、重点、重点,我感觉这才是需要记忆的)

实践项 建议 命名规范 模块:业务:标识,如 user:info:123 避免缓存击穿 设置合理的过期时间 + 空值缓存 避免缓存雪崩 使用随机过期时间抖动 TTL 避免缓存穿透 对空数据设置短 TTL Redis降级 Redis 异常时,设置降级逻辑(如读数据库) 使用连接池 默认已内置连接池,无需手动管理 超时控制 上下文 context.WithTimeout 控制调用超时 序列化 结构体用 encoding/json 转换为字符串存储 使用封装函数 提高复用性,如 GetUserCacheTryLock

工程技术人才招聘求职网