
Redis 之所以被称为“高性能数据结构服务器”,是因为它不仅提供了简单的键值对存储,更在于它针对不同的应用场景,在底层设计了多种极度精巧的数据结构。
本文将针对 Redis 的 5 大基础数据结构 和 4 大高级数据结构 进行全方位的拆解。
String 是 Redis 中最简单、也是最常用的类型。它是二进制安全的,意味着你可以存储任何数据(JSON、图片、序列化对象)。
SET key value / GET key
MSET k1 v1 k2 v2 / MGET k1 k2
INCR key(原子加1)、DECR key、INCRBY key increment
SETEX key seconds value(设置值的同时设置过期时间)
SETNX key value(分布式锁的核心)
Redis 没有使用 C 语言传统的字符数组(以 \0 结尾),而是自己实现了 SDS:
len 属性,不需要像 C 字符串那样遍历。
len 判断结束,而不是 \0,所以可以存二进制图片。
Hash 类似于 Java 的 HashMap,特别适合存储对象,因为它不需要序列化整个对象就能修改其中的某个字段。
HSET user:100 name "Tom" age 18
HGET user:100 name
HGETALL user:100
HINCRBY user:100 age 1
HEXISTS user:100 name
以用户 ID 为 Key,商品 ID 为 Field,商品数量为 Value。这比用 String 存储整个序列化对象效率高得多。
List 是简单的字符串列表,按照插入顺序排序,支持从两端插入或弹出。
LPUSH key value(左插)、RPUSH key value(右插)
LPOP key、RPOP key
LRANGE key start stop(例如 LRANGE key 0 -1 查看全部)
BLPOP key timeout(队列为空时阻塞,直到有数据,消息队列神技)
LTRIM key start stop(只保留指定区间,常用于保留最新动态)
现在的 Redis List 统一采用 QuickList 结构。
Set 存储不重复的元素,并提供了极其强大的集合运算(交、并、差)。
SADD key member / SREM key member
SISMEMBER key member
SMEMBERS key
SRANDMEMBER key count(不删除)、SPOP key(删除)
SINTER k1 k2(交集)、SUNION k1 k2(并集)、SDIFF k1 k2(差集)
利用 SINTER 命令,可以瞬间算出两个用户的共同好友;利用 SADD 可以轻松实现抽奖逻辑。
ZSet 在 Set 的基础上增加了一个 score(分数),使得元素可以按分数排序。
ZADD rank 100 "Tom" 90 "Jerry"
ZRANGE rank 0 -1(从小到大)、ZREVRANGE rank 0 -1(从大到小)
ZRANGEBYSCORE rank 80 100
ZINCRBY rank 10 "Tom"
ZCARD rank
ZSet 的核心是跳表。
ZRANGE 这种范围查询时,跳表通过底层的双向链表横向遍历,效率远超红黑树。
SETBIT key offset value / GETBIT key offset
PFADD key element / PFCOUNT key
GEOADD city 116.40 39.90 "beijing" / GEODIST 计算距离 / GEORADIUS 附近的人。
XADD / XREAD / XGROUP
需求场景 | 推荐结构 | 理由 |
|---|---|---|
单值缓存/计数器 | String | 简单、原子性高 |
存储对象信息 | Hash | 节省内存,灵活修改字段 |
消息队列/时间轴 | List | 双端操作,有序 |
去重/社交关系 | Set | 集合运算强大 |
排行榜/延迟任务 | ZSet | 自动排序,范围查询快 |
海量状态统计 | Bitmap | 极致节省空间 |
博主寄语:
选择 Redis 数据结构时,不仅要看它的基础用法是否满足业务功能,更要关注其底层编码和时间复杂度。在大数据量下,一个 O(N) 命令(如 HGETALL 或 SMEMBERS)可能会导致整个 Redis 实例阻塞。
希望这篇深度解析能帮你在面试和实战中游刃有余!如果你有任何疑问,欢迎在评论区留言讨论。