目录
1、Redis 是什么
2、对比 MySQL
3、单机架构与分布式架构
3.1 引入分布式架构
3.2 引入负载均衡
3.3 数据库读写分离
3.4 引入缓存服务器
3.5 数据库分库分表
3.6 引入微服务
4、Redis 的一些特性
4.1 基于内存 + 高性能
4.2 可编程性
4.3 可扩展性
4.4 持久化
1、Redis 是什么
Redis(Remote Dictionary Server)是一个开源的、在内存使用键值对存储数据的系统,常被称为“数据结构服务器”。
它的核心特点:
基于内存:数据主要存放在内存中,读写速度极快(微秒级),通常能达到 10万+ QPS。但仍然比直接在内存中定义和访问变量要慢。
丰富的数据结构:不只是简单的 key-value,支持 String、Hash、List、Set、ZSet(有序集合)、BitMap、HyperLogLog、Stream 等。
持久化可选:提供 RDB(快照)和 AOF(追加日志)两种方式,可以把内存数据落盘,但持久化不是它的强项。
单线程模型(核心命令处理):避免锁竞争,配合 I/O 多路复用,性能极高。Redis 6.0 后网络 I/O 引入多线程。
常用作缓存:这是它最广泛的用途,也用于分布式锁、计数器、排行榜、消息队列、会话存储等。
2、对比 MySQL
| 维度 | Redis | MySQL |
|---|---|---|
| 存储介质 | 内存为主,可持久化到磁盘 | 磁盘为主,内存做缓存 |
| 数据模型 | Key-Value + 多种数据结构,非关系型数据库 | 关系表(行/列),Schema 固定,关系型数据库 |
| 查询方式 | 命令式 API(GET/SET/LPUSH…) | SQL |
| 读写速度 | 极快(微秒级,10万+ QPS) | 较慢(毫秒级,千级 QPS 常见) |
| 容量 | 受内存限制,通常 GB 级 | 受磁盘限制,可 TB/PB 级 |
| 事务 | 支持简单事务(MULTI/EXEC),无回滚 | 完整 ACID 事务,支持回滚 |
| 一致性 | 最终一致(主从异步复制) | 强一致(可配置隔离级别) |
| 复杂查询 | 不支持 JOIN、聚合等 | 支持 JOIN、GROUP BY、子查询 |
| 持久化 | 可选,可能丢数据 | 默认强持久化 |
| 典型用途 | 缓存、计数器、排行榜、分布式锁、队列 | 业务主数据、订单、用户、交易 |
| 成本 | 内存贵,单位容量成本高 | 磁盘便宜,单位容量成本低 |
3、单机架构与分布式架构
3.1 引入分布式架构
注意:下面的演化过程只是一个粗略的过程,真实的商业项目演化与业务密切相关,业务比技术更重要,技术只是给业务提供支持。
单机架构:所有组件(应用、数据库、缓存)都跑在一台机器上,或者每个组件只部署一个实例。
分布式架构:多个节点协同工作,对外表现为一个整体,解决单机在容量、性能、可用性上的天花板。
单机的瓶颈通常有三个:
CPU/内存上限:一台机器再强也有上限
单点故障:机器挂了,服务就没了
扩展困难:只能垂直升级(换更好的机器),成本高且有极限
分布式就是为了突破这三点。但是分布式也有缺点:增加代码的复杂度,容易出现 BUG。
3.2 引入负载均衡
负载均衡:把大量并发请求,按照某种策略分发到多个服务器上,让每台机器都不至于过载,同时提升整体吞吐和可用性。
常见负载均衡算法
| 算法 | 说明 | 适用场景 |
|---|---|---|
| 轮询(Round Robin) | 依次分发 | 后端性能相近 |
| 加权轮询 | 按权重分发 | 机器配置不同 |
| 最少连接 | 发给当前连接最少的 | 请求耗时差异大 |
| 加权最少连接 | 连接数 + 权重 | 综合场景 |
| IP Hash | 同一 IP 固定到同一后端 | 需要会话保持 |
| 一致性 Hash | 节点增减时影响小 | 缓存类场景 |
| 随机 | 随机选 | 简单场景 |
| 响应时间最短 | 选响应最快的 | 对延迟敏感 |
3.3 数据库读写分离
上面的分布式架构中,多个应用服务器都读写一台存储服务器,而大多数互联网业务是读多写少,典型比例 10:1 甚至 100:1。
单库面临的问题:
读请求太多,CPU 和连接数被占满
写请求和读请求互相争抢资源
单机容量和性能有上限
解决方案:建立两个数据库,一个主库和从库,主控负责写请求,从库负责读请求。再定期的将主库和从库的数据进行同步
3.4 引入缓存服务器
存储服务器存储的大概 20% 的数据,可以满足大概 80% 的访问请求。如果将所有数据都放入 MySQL,用户的请求都要读取 MySQL 的数据,而 MySQL 的访问速度远小于 Redis 的访问速度。所以我们可以把那大概 20% 的热点数据存储在 Redis,Redis 所在的服务器称为缓存服务器。MySQL 仍然存储所有数据。
3.5 数据库分库分表
有时候数据多到一台存储服务器都存储不下的情况,这时候就需要多台存储服务器,既然有了多台服务器,之前都是将用户表、商品表、交易表存储在同一个数据库服务器的不同数据库,那么现在可以将这些分别存储在不同的数据库服务器上。即一个数据库服务器只存储一个或一部分数据库。如果一个数据库太大,一台数据库服务器都存不下,我们可以对该数据库进行拆分,比如拆成 5 部分,分别用 5 台数据库服务器存储。
3.6 引入微服务
之前应用服务器,一个服务器程序里面做了很多的业务.这就可能会导致这一个服务器的代码变的越来越复杂,为了更方便于代码的维护,就可以把这样的一个复杂的服务器,拆分成更多的,功能更单一,但是更小的服务器。这样做虽然更方便于代码的维护,更方便于代码复用。但代价是
- 系统性能的下降,因为不同的微服务之间需要网络进行通信,网络传输的速度很可能比读取硬盘的速度都还要慢。但是现在的万兆网卡读写的速度已经超过硬盘的读写速度了。
- 系统复杂程度提高,系统可用性下降(可用性 = 系统实际运行时间 / 总时间)这就需要一系列的手段,来保证系统的可用性,比如更丰富的监控系统,以及配套的运维人员。
4、Redis 的一些特性
4.1 基于内存 + 高性能
数据放内存:读写延迟微秒级,单机可达10万+ QPS
单线程处理命令:避免锁竞争和上下文切换,命令原子执行。(多线程提高效率的前提是 CPU 密集型任务,此时使用多线程可以充分利用 CPU 的多核资源,而 Redis 的主要任务是操作内存的数据结构,不会占用很多 CPU 资源)
I/O 多路复用:epoll/kqueue 处理海量连接
Redis 6.0 后:网络 I/O 引入多线程,命令处理仍是单线程
4.2 可编程性
针对 Redis 的操作,可以直接通过简单的交互式命令进行操作.也可以通过一些脚本的方式,批量执行一些操作(可以带有一些逻辑)。Redis 的可编程性主要经历了三个阶段:Lua 脚本、Redis Functions,以及更进一步的触发器和函数
4.3 可扩展性
Redis 的可扩展性,核心在于Modules(模块)系统。如果说 Lua 脚本和 Functions 是让你在 Redis 提供的“积木”上搭东西,那 Modules 就是让你自己造积木,甚至改造积木的材质。它的目标很明确:让开发者能够以接近 Redis 原生命令的速度,去扩展全新的数据结构和命令
4.4 持久化
Redis 是内存数据库,但提供两种持久化方式:
RDB(快照)
某一时刻把内存数据全量写入磁盘
优点:文件小、恢复快、适合备份
缺点:两次快照之间宕机会丢数据
AOF(追加日志)
记录每条写命令,重启时重放
优点:丢数据少(可配置每秒同步)
缺点:文件大、恢复慢
混合持久化(4.0+)
RDB 全量 + AOF 增量结合
兼顾恢复速度和数据安全
实际生产中常用RDB + AOF 混合,并配合主从复制做冗余。