Redis 数据库介绍
Redis 是一个开源的、基于内存的键值KV(Key-Value)存储系统,通常被称为 数据结构服务器。它由 Salvatore Sanfilippo 开发,目前由 Redis 社区和 Redis 公司维护。与 MySQL 将数据组织成表不同,Redis 将数据存储为 键 与 值 的映射,并且值可以是多种数据结构(字符串、哈希、列表、集合、有序集合等)。
- Redis 支持数据持久化(可将内存数据写入磁盘),但本质上是 以内存为核心 的数据库。
- 所有操作通常都是 原子性 的,并且 Redis 提供了多种原子操作命令,非常适合高并发场景。
Redis 最流行的应用场景是 缓存、会话存储、计数器、消息队列 和 实时排行榜。在 WEB 开发中,Redis 常常与 MySQL / PostgreSQL 搭配使用:Redis 负责高速读写,MySQL 负责持久化存储和复杂查询。
Redis 核心术语
| 术语 | 描述 |
|---|
| 键(Key) | 唯一标识一个值的字符串。类似于 MySQL 中的主键,但 Redis 的键是直接访问值的唯一方式。 |
| 值(Value) | 与键关联的数据。值可以是字符串、哈希、列表、集合、有序集合等 数据结构,而不是 MySQL 中的一行记录。 |
| 数据库(Database) | Redis 支持多个逻辑数据库(默认 16 个,编号 0-15),每个数据库是独立的键空间。与 MySQL 的数据库概念类似,但 Redis 的数据库之间没有表隔离。 |
| 内存存储(In-Memory Storage) | Redis 将所有数据存储在 RAM 中,因此读写速度极快(微秒级),但内存容量有限且价格较高。 |
| 持久化(Persistence) | 将内存中的数据保存到磁盘的机制,防止进程退出后数据丢失。Redis 提供 RDB(快照)和 AOF(操作日志)两种方式。 |
| 原子操作(Atomic Operation) | Redis 的单个命令(如 INCR、SETNX)是原子的,多个命令可以通过 事务 或 Lua 脚本 实现原子性。这与 MySQL 的 ACID 事务不同(Redis 事务不支持回滚)。 |
| 过期时间(TTL, Time To Live) | 可以为键设置存活时间,到期后 Redis 自动删除该键。常用于缓存场景。 |
| 管道(Pipeline) | 客户端将多个命令一次性发送给 Redis,减少网络往返时间,但不保证原子性。 |
| 发布/订阅(Pub/Sub) | 一种消息通信模式:发布者向频道发送消息,订阅者接收消息。Redis 提供轻量级的实时消息通知。 |
Redis 与 MySQL / SQLite 的核心区别
| 维度 | Redis | MySQL / SQLite |
|---|
| 数据位置 | 主要在内存,可选持久化到磁盘 | 磁盘为主,内存缓存为辅 |
| 数据模型 | 键值 + 多种数据结构(无表、无 SQL) | 关系型表 + SQL,支持复杂查询和 JOIN |
| 读写速度 | 极高(微秒级),适合高 QPS | 中等(毫秒级),受磁盘 I/O 限制 |
| 数据容量 | 受限于内存大小(通常 GB ~ TB 级别) | 受限于磁盘大小(可达到 PB 级别) |
| 事务支持 | 有限支持(MULTI/EXEC 保证原子性但不支持回滚;不支持隔离级别) | 完整 ACID 事务(InnoDB) |
| 持久化保证 | 可配置(RDB 可能丢失最近数据,AOF 性能稍降) | 写入即持久化(配合 WAL 日志),数据安全性高 |
| 查询能力 | 只能通过键或数据结构的特定命令查询(如 HGET、ZRANGE),无 SQL | 完整 SQL 支持,复杂过滤、聚合、子查询 |
| 典型场景 | 缓存、会话、计数器、排行榜、分布式锁、轻量消息队列 | 业务主存储、报表系统、需要事务和复杂查询的系统 |
title:Summary
**工程结论**:Redis 不替代 MySQL,而是 **互补**。在你的图书管理系统中,SQLite 负责持久化存储(图书信息、借阅记录),Redis 可用于缓存热门图书详情、记录借阅排行榜、实现分布式锁防止超借等。
Redis 适用场景
适合的场景
| 场景 | 原因 |
|---|
| 缓存热点数据 | 内存读写快,TTL 自动过期,减轻后端数据库压力。 |
| 高并发计数器 | INCR 命令原子操作,无需加锁,性能远高于 MySQL 的行锁。 |
| 会话存储(Session) | 读写频繁,数据量小,过期时间天然支持。 |
| 实时排行榜 | 有序集合(Sorted Set)提供 O(log N) 的插入和按分数排序能力。 |
| 分布式锁 | SETNX + 过期时间可实现简单的跨进程锁(结合 Lua 保证原子性)。 |
| 消息队列(轻量) | 列表(List)的 LPUSH / RPOP 或发布/订阅模式。 |
不适合的场景
| 场景 | 原因 |
|---|
| 需要复杂查询(如多条件过滤、JOIN) | Redis 无 SQL 引擎,只能通过键或数据结构命令访问。 |
| 数据量超过可用内存 | 内存比磁盘昂贵,且 Redis 全量加载到内存,超出部分会导致性能骤降或 OOM。 |
| 需要强 ACID 事务 | Redis 事务不支持回滚,不保证隔离性。 |
| 长期冷数据存储 | 持久化机制不如 MySQL 可靠,且内存成本高。 |
| 复杂的报表统计分析 | 无聚合函数、分组、子查询,需应用层处理。 |
Redis 的定位
- C++ 负责主体框架:可以用 C++ 连接 Redis(如 hiredis 库),实现缓存读写、分布式锁、会话管理等。
- Python 负责原子操作:利用 Python 脚本调用 Redis 的原子命令(如
INCR、SETNX)处理高并发的借书/还书计数器。
- SQLite 负责持久化存储:图书信息、用户信息、借阅历史等核心数据存入 SQLite。
- Redis 作为 加速层:存放热门图书的详情(避免频繁读 SQLite)、记录图书借阅排行榜(有序集合)、临时存储用户登录状态。
工作分工示例:
- 用户查询热门图书 → C++ 先读 Redis,若命中则直接返回;若未命中,则查询 SQLite 并将结果写入 Redis(设置过期时间)。
- 用户借书 → Python 脚本收到请求后,先用 Redis 的
INCR 记录借阅次数(原子更新排行榜),再向后面的大型数据库写入借阅记录。