Redis 数据结构
1. Redis 仅仅是缓存吗#
Redis 最广为人知的用途是缓存(Caching),它通过内存存储提供超高的读写性能,常用于减轻数据库压力(如 MySQL),尤其在以下场景:
- 缓存热点数据
- 会话存储(Session Storage)
- 页面缓存
但 Redis 的功能远不止缓存:
- 数据结构存储:支持字符串、列表、集合、哈希等,类似一个内存数据库
- 消息队列:通过 Pub/Sub 或 List 实现轻量级消息传递
- 分布式锁:在分布式系统中用于同步
- 高可用与分布式:通过主从复制、哨兵模式、集群模式支持分布式架构
2. String & Set#
注意这里的 String 就是一个数据结构, 而不是一个值的类型, Redis 中 Set 只能用来存储 String 类型的值, 这里的 String 指的只是单纯的字符串, 而不是数据结构,
2.1. String#
SET user:001 "Alice"
SET user:001 '{"name": "Alice", "age": 25}'
SET counter 10
注意看上面的这些, 都是 String 数据结构, 其中 user:001
和 counter
是 Key, 后面的 字符串 “Alice”, JSON 数据, 还有数字 是 Value,
可以看出, Redis 中的 String 有点像哈希表, 但不是, 因为它有一些更方便的操作, 比如:
GET user:001 # 获取 key user:001 值
INCR counter # 自增1
DECR counter # 自减1
INCRBY counter 5 # 自增5
2.2. Set#
Set 只能存储字符串, 且字符串不能重复:
["123", "456", "Jack", "Alice", ...]
3. String 使用场景#
3.1. 缓存热点数据#
SET user:1001:name "Shaowen Zhu" EX 3600
(存储用户名称,设置过期时间 1 小时)
GET user:1001:name
(获取用户名称)
通过 EX
选项设置过期时间,自动过期释放内存,避免缓存雪崩
3.2. 分布式锁#
场景: 在分布式系统中,多个进程可能会同时访问和修改共享资源,因此需要一个锁机制来避免并发冲突。
实现方式:
SETNX lock:order:12345 "locked"
(如果 key 不存在,则设置成功,表示获取到锁)EXPIRE lock:order:12345 10
(设置超时时间,防止死锁)- 操作完成后
DEL lock:order:12345
(释放锁)
在 Redis 中,大部分单个命令都是原子操作,像
SET
、INCR
、SETNX
、DEL
是绝对原子的,因为 Redis 是单线程执行命令的,这意味着 不会有其他操作在命令执行的过程中打断它。当然也有不是原子操作:GETSET
,MGET / MSET
,
3.3. 计数器#
场景: 需要对某个值进行频繁的递增或递减操作,比如访问量统计、点赞数、库存管理等。
实现方式:
INCR page:view:article:1001
(文章 1001 的浏览量 +1)DECR product:stock:2001
(商品 2001 的库存 -1)INCRBY user:1001:points 50
(用户 1001 的积分增加 50)
3.4. 短链接存储#
场景: 实现短链接功能,如 https://tinyurl.com/abcd
映射到 https://example.com/long-url
。
实现方式:
SET short:abcd "https://example.com/long-url"
GET short:abcd
(通过短链接获取原始 URL)
可以发现 Redis 中习惯在 KEY 中通过
:
连接字符串, 这样可以清晰的表达出含义, 如:page:view:article:1001
, 这就是一个字符串, 不是什么高级的东西,
4. Set 使用场景#
4.1. 数据去重与快速查重#
利用 Set 元素不允许重复的特性,可以用来存储用户访问记录、去重 URL、或防止重复投票等场景。
例如:记录某个用户访问过的页面,避免重复统计。
# 添加用户访问记录(每个页面仅记录一次)
SADD user:123:visited "page1"
SADD user:123:visited "page2"
SADD user:123:visited "page1" # 重复添加不会生效
# 判断用户是否已访问某个页面
SISMEMBER user:123:visited "page1" # 返回 1 表示存在,0 表示不存在
# 获取该用户所有访问过的页面
SMEMBERS user:123:visited
4.2. 标签管理和推荐系统#
在内容推荐场景中,可以使用 Set 来存储用户或内容的标签,然后利用集合的交集或并集进行推荐匹配。例如,根据用户关注的标签推荐相似内容。
# 给文章添加标签
SADD article:100:tags "tech" "ai" "redis"
# 用户兴趣标签
SADD user:123:tags "ai" "machine learning" "tech"
# 计算用户与文章标签的交集,判断兴趣匹配度
SINTER article:100:tags user:123:tags
SINTER
可计算出用户与文章之间的标签交集,判断用户对该文章的兴趣匹配情况,从而辅助推荐算法。
4.3. 黑名单/白名单管理#
Set 常用于存储黑名单或白名单数据,由于其快速的查找特性,可以高效判断某个元素是否被列入名单,适用于安全控制、IP 屏蔽、广告过滤等场景。
# 添加IP到黑名单
SADD blacklist:ips "192.168.1.100" "10.0.0.5"
# 检查IP是否在黑名单中
SISMEMBER blacklist:ips "192.168.1.100" # 返回 1 表示IP被屏蔽
# 移除IP
SREM blacklist:ips "10.0.0.5"