Redis的使用
Redis 全面介绍与 API 使用示例
一、Redis 核心概念
Redis(Remote Dictionary Server) 是一款开源的、高性能的键值对(Key-Value)数据库,由 Salvatore Sanfilippo 开发,基于内存运行且支持持久化,常用于缓存、消息队列、会话存储等场景。其核心特点可概括为:
| 特点 | 说明 |
|---|---|
| 高性能 | 基于内存操作,单节点 QPS 可达 10 万+,延迟通常在微秒级。 |
| 多数据结构支持 | 不仅支持字符串(String),还支持哈希(Hash)、列表(List)、集合(Set)等复杂结构。 |
| 持久化 | 提供 RDB(快照)和 AOF(日志)两种持久化方式,避免内存数据丢失。 |
| 高可用与分布式 | 支持主从复制、哨兵(Sentinel)机制实现高可用,通过 Redis Cluster 实现分布式存储。 |
| 丰富功能 | 内置发布订阅、Lua 脚本、事务、过期淘汰等功能,满足多样化业务需求。 |
二、Redis 核心数据结构与 API 示例
Redis 的 API 与数据结构强绑定,每种结构都有专属命令。以下以 Redis 6.x 版本为例,结合 redis-cli 命令行工具演示常用 API(注:示例中 -> 后为命令返回结果)。
1. 字符串(String):最基础的键值类型
String 是 Redis 最常用的结构,可存储文本、数字(整数/浮点数),最大容量为 512MB,适用于缓存单个值(如用户信息、计数器)。
| 命令格式 | 功能说明 | 示例 | 返回结果 |
|---|---|---|---|
| `SET key value [NX | XX]` | 设置键值(NX:键不存在时才设;XX:键存在时才设) | SET username "zhangsan" |
GET key |
获取键对应的值 | GET username |
"zhangsan" |
MSET key1 val1 key2 val2 |
批量设置键值 | MSET age 20 gender "male" |
OK |
MGET key1 key2 |
批量获取键值 | MGET username age |
["zhangsan", "20"] |
INCR key |
键值为整数时,自增 1(常用于计数器) | INCR age |
21 |
DECR key |
键值为整数时,自减 1 | DECR age |
20 |
INCRBY key num |
键值自增指定整数 num |
INCRBY age 5 |
25 |
EXPIRE key seconds |
设置键的过期时间(秒) | EXPIRE username 3600 |
1(成功) |
TTL key |
查看键剩余过期时间(-1:永不过期;-2:已过期) | TTL username |
3590(剩余秒数) |
2. 哈希(Hash):适合存储对象
Hash 是“键值对中的键值对”,可将多个字段(Field)和值(Value)关联到一个 Redis 键,适用于存储对象(如用户信息、商品详情),避免单个 String 存储大 JSON 的冗余。
| 命令格式 | 功能说明 | 示例 | 返回结果 |
|---|---|---|---|
HSET key field value |
给哈希键设置一个字段和值 | HSET user id 101 name "lisi" |
2(新增字段数) |
HGET key field |
获取哈希键中指定字段的值 | HGET user name |
"lisi" |
HMSET key f1 v1 f2 v2 |
批量设置哈希字段和值 | HMSET user age 22 city "Beijing" |
OK |
HMGET key f1 f2 |
批量获取哈希字段的值 | HMGET user id city |
["101", "Beijing"] |
HGETALL key |
获取哈希键的所有字段和值 | HGETALL user |
["id", "101", "name", "lisi", "age", "22", "city", "Beijing"] |
HKEYS key |
获取哈希键的所有字段 | HKEYS user |
["id", "name", "age", "city"] |
HLEN key |
统计哈希键的字段数量 | HLEN user |
4 |
HDEL key field1 [field2] |
删除哈希键中的指定字段 | HDEL user city |
1(删除字段数) |
3. 列表(List):有序可重复的“链表”
Redis List 基于双向链表实现,元素有序且可重复,支持从两端插入/删除元素,适用于实现消息队列、最新消息排行、栈/队列等场景。
| 命令格式 | 功能说明 | 示例 | 返回结果 |
|---|---|---|---|
LPUSH key value1 [val2] |
从列表左侧插入元素(左进) | LPUSH fruits "apple" "banana" |
2(列表长度) |
RPUSH key value1 [val2] |
从列表右侧插入元素(右进) | RPUSH fruits "orange" |
3 |
LRANGE key start end |
获取列表中 start 到 end 的元素(0 开始,-1 表示最后一个) |
LRANGE fruits 0 -1 |
["banana", "apple", "orange"] |
LPOP key |
从列表左侧弹出元素(左出) | LPOP fruits |
"banana" |
RPOP key |
从列表右侧弹出元素(右出) | RPOP fruits |
"orange" |
LLEN key |
统计列表长度 | LLEN fruits |
1(剩余 "apple") |
LTRIM key start end |
截取列表,保留 start 到 end 的元素 |
LPUSH nums 1 2 3 4 5 → LTRIM nums 1 3 |
OK → LRANGE nums 0 -1 得 ["4", "3", "2"] |
4. 集合(Set):无序不可重复的“集合”
Redis Set 是无序的字符串集合,元素不可重复(自动去重),支持交集、并集、差集等数学运算,适用于标签管理、好友关系(如共同好友)、去重场景。
| 命令格式 | 功能说明 | 示例 | 返回结果 |
|---|---|---|---|
SADD key member1 [mem2] |
向集合中添加元素(重复添加会忽略) | SADD tags "java" "python" "go" |
3(新增元素数) |
SMEMBERS key |
获取集合中的所有元素(无序) | SMEMBERS tags |
["go", "java", "python"](顺序不固定) |
SISMEMBER key member |
判断元素是否在集合中 | SISMEMBER tags "python" |
1(存在);SISMEMBER tags "c++" 得 0(不存在) |
SCARD key |
统计集合元素数量 | SCARD tags |
3 |
SREM key member1 [mem2] |
从集合中删除元素 | SREM tags "go" |
1(删除元素数) |
SINTER key1 key2 |
求两个集合的交集(共同元素) | SADD set1 1 2 3 → SADD set2 3 4 5 → SINTER set1 set2 |
["3"] |
SUNION key1 key2 |
求两个集合的并集(所有元素去重) | SUNION set1 set2 |
["1", "2", "3", "4", "5"] |
5. 有序集合(Sorted Set / ZSet):有序不可重复的“加权集合”
ZSet 是 Set 的“升级版”:元素不可重复,但每个元素关联一个分数(Score,浮点数),Redis 按分数对元素排序,适用于排行榜(如销量排行、积分排行)、带权重的消息队列。
| 命令格式 | 功能说明 | 示例 | 返回结果 |
|---|---|---|---|
ZADD key score1 mem1 [s2 m2] |
向 ZSet 中添加元素及分数(重复元素会更新分数) | ZADD rank 95 "Alice" 88 "Bob" 92 "Charlie" |
3(新增元素数) |
ZRANGE key start end [WITHSCORES] |
按分数升序获取 start 到 end 的元素(WITHSCORES 显示分数) |
ZRANGE rank 0 -1 WITHSCORES |
["Bob", "88", "Charlie", "92", "Alice", "95"] |
ZREVRANGE key start end [WITHSCORES] |
按分数降序获取元素(适合做排行榜) | ZREVRANGE rank 0 1 WITHSCORES |
["Alice", "95", "Charlie", "92"](取Top2) |
ZSCORE key member |
获取元素的分数 | ZSCORE rank "Bob" |
"88" |
ZINCRBY key incr member |
增加元素的分数 | ZINCRBY rank 3 "Bob" |
"91" |
ZCARD key |
统计 ZSet 元素数量 | ZCARD rank |
3 |
ZCOUNT key min max |
统计分数在 min 到 max 之间的元素数量 |
ZCOUNT rank 90 100 |
2(Alice 和 Charlie) |
三、Redis 高级功能 API 示例
1. 事务(Transaction):批量执行命令
Redis 事务通过 MULTI(开始事务)、EXEC(执行事务)包裹命令,事务内命令要么全部执行,要么全部不执行(但不支持回滚,若中间命令语法错误,后续命令仍会执行)。
127.0.0.1:6379> MULTI # 开始事务
OK
127.0.0.1:6379(TX)> SET a 10
QUEUED # 命令入队
127.0.0.1:6379(TX)> INCR a
QUEUED
127.0.0.1:6379(TX)> GET a
QUEUED
127.0.0.1:6379(TX)> EXEC # 执行事务
1) OK
2) (integer) 11
3) "11"
2. 发布订阅(Pub/Sub):消息通信
Redis 支持“发布者-订阅者”模式:发布者(Publisher)向指定频道(Channel)发送消息,所有订阅该频道的订阅者(Subscriber)会收到消息,适用于简单的消息通知场景。
步骤1:订阅者订阅频道
# 终端1(订阅者)
127.0.0.1:6379> SUBSCRIBE news # 订阅 "news" 频道
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1 # 订阅成功
步骤2:发布者发布消息
# 终端2(发布者)
127.0.0.1:6379> PUBLISH news "Redis 发布订阅测试" # 向 "news" 频道发消息
(integer) 1 # 有1个订阅者接收
步骤3:订阅者接收消息
# 终端1(订阅者)会立即收到消息
1) "message"
2) "news"
3) "Redis 发布订阅测试"
四、Redis 应用场景总结
结合上述 API 特性,Redis 典型应用场景包括:
- 缓存:用 String/Hash 存储热点数据(如商品详情),通过
EXPIRE设置过期时间,减轻数据库压力。 - 计数器:用
INCR/INCRBY实现页面访问量、商品销量统计。 - 排行榜:用 ZSet 的
ZREVRANGE实现实时积分排行、销量排行。 - 消息队列:用 List 的
LPUSH(生产)+RPOP(消费)实现简单队列;用 ZSet 实现带优先级的队列。 - 好友关系:用 Set 的
SINTER求共同好友,SUNION求所有好友。 - 会话存储:用 String/Hash 存储用户 Session,替代传统的服务器内存存储,支持分布式部署。
通过掌握上述核心数据结构与 API,可满足大多数 Redis 基础应用需求。实际开发中,还需结合编程语言客户端(如 Java 的 Jedis、Python 的 redis-py)调用这些 API,语法与 redis-cli 命令高度一致。