欢迎关注专栏:CSDN:AI 开发技术
- 上一篇:Redis 多环境安装部署与网络排错实战
- 下一篇:大模型 Agent 开发实战:Redis 缓存与锁的高阶应用
Redis 核心数据结构速查与终端演练
- Redis 核心数据结构速查与终端演练
- 1. 业务背景 / 核心问题
- 2. 全局键值管理 (Global Keys)
- 终端实操演练
- 3. 字符串 (String)
- 终端实操演练
- 4. 列表 (List)
- 终端实操演练
- 5. 集合 (Set)
- 终端实操演练
- 6. 有序集合 (ZSet / Sorted Set)
- 终端实操演练
- 7. 哈希 (Hash)
- 终端实操演练
- 8. 消息与流处理 (Pub/Sub & Stream)
- 8.1 传统发布订阅 (Pub/Sub)
- 8.2 数据流 (Stream)
- 终端实操演练
- 9. 扩展结构:空间、位图、事务
- 9.1 地理空间 (Geospatial)
- Geospatial 演练
- 9.2 位图 (Bitmap) 与 位域 (Bitfield)
- 9.3 弱事务机制 (Transactions)
Redis 核心数据结构速查与终端演练
关键词:命令速查, String, List, Set, Hash, ZSet, Stream, 终端回显
阅读耗时:约 25 分钟
1. 业务背景 / 核心问题
Redis 提供了多种数据结构,不同结构对应不同的访问模式。本文按照“概念速查 → 命令表格 → 终端演练”展开,重点说明命令用途以及容易被忽略的生产边界。
前置说明:Redis 键区分大小写,字符串是二进制安全的。使用
redis-cli --raw可以让客户端直接按原始形式显示中文等内容。
2. 全局键值管理 (Global Keys)
| 场景 | 命令语法 | 示例说明 |
|---|---|---|
| 渐进式扫描键名 | SCAN [cursor] MATCH [pattern] COUNT [count] | 生产环境优先使用,按游标分批遍历 |
| 一次性匹配键名 | KEYS [pattern] | 仅建议在小型测试数据集或调试场景使用 |
| 判断键是否存在 | EXISTS [key] | 返回 1 表示存在,0 表示不存在 |
| 删除指定键 | DEL [key] | DEL session:01 |
| 危险操作 (清空全库) | FLUSHALL | 清空实例中的全部数据库;不要在共享或生产实例演练 |
| 查看过期时间 | TTL [key] | -1 (无过期), -2 (已过期), 正数 (剩余秒数) |
| 设定过期时间 | EXPIRE [key] [seconds] | EXPIRE token 3600 |
| 清空屏幕输出 | clear | 仅清理终端显示 |
终端实操演练
- 检索与判断:使用
SCAN 0 MATCH user:* COUNT 100分批扫描键,再用EXISTS判断目标键是否存在。 - 过期管理:使用
EXPIRE为测试键设置过期时间,并用TTL检查剩余时间。
KEYS *会一次性遍历当前数据库的键空间,数据量大时可能阻塞 Redis。FLUSHALL会删除整个实例的数据,本文不把它列为常规练习步骤。更多说明可参考 Redis 键空间操作文档。
3. 字符串 (String)
最基础的数据类型,适用于普通键值缓存和计数器。字符串也可作为分布式锁的底层原语,但正确实现还需要唯一锁值、过期时间和原子校验释放,不能只依赖一个SET NX。
| 场景 | 命令语法 |
|---|---|
| 创建/更新键值 | SET [key] [value] |
| 获取键的值 | GET [key] |
| 创建/更新并设置过期时间 | SETEX [key] [seconds] [value] |
| 原子创建防重复 | SET [key] [value] NX EX [seconds] |
终端实操演练
- 基础写入与读取:
SET keyname test0425->GET keyname。 - 结合过期机制:使用
SETEX keyname 20 test0425一步完成写入与超时配置。
4. 列表 (List)
List 在命令层表现为有序字符串序列,支持从头尾两端插入、读取和弹出。它可用于简单的先进先出队列,但需要消费确认、重试或消费者组时,应优先评估 Redis Stream 或专业消息队列。
| 场景 | 命令语法 |
|---|---|
| 头部 (左侧) 插入 | LPUSH [key] [value1] [value2]... |
| 尾部 (右侧) 插入 | RPUSH [key] [value1] [value2]... |
| 弹出头部并删除 | LPOP [key] [count] |
| 弹出尾部并删除 | RPOP [key] [count] |
| 截取指定范围 (保留) | LTRIM [key] [start_index] [stop_index] |
| 查看全部列表元素 | LRANGE [key] 0 -1 |
| 查看列表长度 | LLEN [key] |
终端实操演练
- 元素插入:
- 使用
LPUSH从左侧压入,若是多个元素会依次压入导致逆序。 - 使用
RPUSH从右侧追加,保持顺序列队。
- 使用
- 范围读取与修剪:
LRANGE listname 0 -1查看所有内容。LTRIM listname 1 3实现只保留索引 1 到 3 的元素(即截断滑动窗口)。
- 元素弹出机制:
- 使用
RPOP和LPOP弹出并消耗列表两端的元素。
- 使用
- 获取队列长度:
LLEN返回当前剩余数量。
5. 集合 (Set)
无序不可重复的集合,适合做好友关注、抽奖人员去重、以及高阶的交并差集运算。
| 场景 | 命令语法 |
|---|---|
| 添加元素 | SADD [key] [member1] [member2]... |
| 获取集合所有元素 | SMEMBERS [key] |
| 删除特定元素 | SREM [key] [member] |
| 判断元素是否存在 | SISMEMBER [key] [member] |
| 求交集 (共有元素) | SINTER [key1] [key2] |
| 求并集 (融合元素) | SUNION [key1] [key2] |
| 求差集 (A 有 B 无) | SDIFF [key1] [key2] |
终端实操演练
- 基础去重插入与判断:重复的插入操作(如再插一次
setnum1)将返回0。 - 删除单个元素:使用
SREM setname member。 - 高级集合运算:
- 寻找共同好友(交集):
SINTER - 汇总所有标签(并集):
SUNION - 过滤掉已读名单(差集):
SDIFF
- 寻找共同好友(交集):
6. 有序集合 (ZSet / Sorted Set)
在集合的基础上为每个元素关联一个浮点类型的分数 (score),Redis 会根据分数从小到大自动排序。适合处理积分排行榜、优先级队列。
| 场景 | 命令语法 |
|---|---|
| 添加元素及分数 | ZADD [key] [score] [member] |
| 升序获取元素 (带分数) | ZRANGE [key] 0 -1 WITHSCORES |
| 查看成员分数 | ZSCORE [key] [member] |
| 获取升序排名 (从0算起) | ZRANK [key] [member] |
| 获取降序排名 | ZREVRANK [key] [member] |
| 为指定成员加分 | ZINCRBY [key] [increment] [member] |
| 删除成员 | ZREM [key] [member] |
终端实操演练
- 批量添加并查看顺序:注意
ZADD的语法是先分数后元素名。 - 积分查询与排名:
- 查询
num1的绝对分数。 - 查询排名,
ZRANK结果从 0 开始;ZREVRANK是反向的高分第一名。
- 查询
- 动态加分与减分:使用负数即可实现减分操作。
- 移除成员:使用
ZREM leaderboard user:1。
7. 哈希 (Hash)
键值对的嵌套字典结构,特别适合用来存储对象(如用户详情的属性)。
| 场景 | 命令语法 |
|---|---|
| 添加单个/多个字段 | HSET [key] [field] [value] |
| 获取特定字段值 | HGET [key] [field] |
| 获取对象所有字段名 | HKEYS [key] |
| 提取对象全部键值对 | HGETALL [key] |
| 删除特定字段 | HDEL [key] [field] |
| 判断字段是否存在 | HEXISTS [key] [field] |
终端实操演练
- 设置对象属性:使用
HSET person name Y age 36记录属性。 - 提取对象数据:
- 只看字段名列表。
- 读取单个字段的值。
- 一键提取所有数据。
- 字段删除与校验:使用
HDEL删除字段,再用HEXISTS验证。
8. 消息与流处理 (Pub/Sub & Stream)
8.1 传统发布订阅 (Pub/Sub)
Pub/Sub 用于实时广播,不持久化消息;订阅者断线期间的消息无法在重连后补收,因此不适合作为要求可靠交付的任务队列。
| 场景 | 命令语法 |
|---|---|
| 订阅频道 (阻塞接收) | SUBSCRIBE [channel] |
| 发布消息 | PUBLISH [channel] [message] |
8.2 数据流 (Stream)
Redis 5.0 引入了 Stream,支持保留消息、范围查询和消费者组。消息能否在故障后恢复仍取决于 Redis 持久化、复制及确认处理配置。
| 场景 | 命令语法 |
|---|---|
| 发送新消息 (* 为自动ID) | XADD [stream_key] * [field] [value] |
| 查看队列范围消息 | XRANGE [stream_key] - + |
| 阻塞轮询读取新消息 | XREAD COUNT [num] BLOCK [ms] STREAMS [key] 0 |
| 创建消费者组 | XGROUP CREATE [stream_key] [group_name] 0 |
| 组内消费者抢占消息 | XREADGROUP GROUP [group_name] [consumer] STREAMS [stream_key] > |
| 处理完毕后 ACK 确认 | XACK [stream_key] [group_name] [message_id] |
终端实操演练
- 消息生产与基础查询:
- 自动生成 ID 发送与自定义 ID 发送。
- 长度与内容检索。
- 消息的删除与截断清空(
XTRIM MAXLEN 0)。
- 基础读取阻塞模型:阻塞 1000ms 等待读取队列内容。
- 高级特性:消费者组处理流程
- 消费者 A (ConsumerA) 首先使用
XREADGROUP ... >抢占到最新的多条未读消息。 - 消费者 A 处理完成后,必须发送
XACK通知服务器该消息已完结,防止消息变成长期 Pending 状态。 - 此时同组的另一个消费者 B 将无法再次读取到这些已被消费过且 ACK 的消息。
- 消费者 A (ConsumerA) 首先使用
9. 扩展结构:空间、位图、事务
9.1 地理空间 (Geospatial)
基于经纬度的高级结构,适用于外卖骑手位置、附近的人等距离计算业务。
| 场景 | 命令语法 |
|---|---|
| 添加位置坐标 | GEOADD [key] [lon] [lat] [member] |
| 获取成员坐标 | GEOPOS [key] [member] |
| 计算两地直线距离 | GEODIST [key] [member1] [member2] [unit] |
| 圆形半径搜索 | GEOSEARCH [key] FROMMEMBER [member] BYRADIUS [radius] [unit] |
| 矩形区块搜索 | GEOSEARCH [key] FROMMEMBER [member] BYBOX [w] [h] [unit] |
Geospatial 演练
- 写入坐标:批量录入中国核心城市的经纬度。
- 信息提取与距离计算:查询坐标和计算“北京”到“上海”的绝对距离。
- 附近范围检索:
- 搜索上海周边 300km 的城市圈(圆形搜索)。
- 搜索坐标系中的矩形框块。
9.2 位图 (Bitmap) 与 位域 (Bitfield)
- Bitmap:基于 String 的位级操作。一位占 1 bit(0 或 1),适合高密度的签到、布尔状态记录。
- Bitfield:允许在一段二进制数据中读写不同位宽的整数字段,可用于紧凑状态编码。
| 场景 | 命令语法 |
|---|---|
| 签到打卡 (写比特位) | SETBIT [key] [offset] [0/1] |
| 查询签到状态 | GETBIT [key] [offset] |
| 统计总签到次数 | BITCOUNT [key] |
| Bitfield 整段写入 | BITFIELD [key] set i8 [offset] [value] |
9.3 弱事务机制 (Transactions)
利用MULTI开启命令队列,EXEC让队列中的命令连续执行,不会被其他客户端命令插入。注意:如果某条命令在执行阶段出错,Redis 不会像关系型数据库那样回滚已经执行的命令,后续合法命令仍可能继续执行。