sinter是唯一靠谱、原子、高效计算共同好友的方式,它在服务端基于内存做集合交集运算,自动选取最小集合优化性能,毫秒级返回结果,避免网络往返与客户端内存膨胀。

直接用 SADD 写入 + SINTER 计算,就是最简路径。但实际踩坑点不在命令本身,而在数据类型、集合规模和存储时机的选择上。
为什么不能直接用 SMEMBERS 拿出所有元素再内存里算交集?
看似简单,但会把 Redis 的压力转嫁到应用层,还容易爆内存。比如两个各含 50 万成员的集合,SMEMBERS 返回的数据量轻松超百 MB,网络传输 + 应用解析都慢,且失去 Redis 原生 O(N×M) 的底层优化(它会自动选最小集合做主扫描)。
- 必须用
SINTER key1 key2让 Redis 自己算,不要拉到客户端 - 如果 key1 和 key2 都是大集合,但你知道其中一个是小集合(比如用户标签只有 10 个),可以提前用
SCARD判断,确保小集合在前,提升性能 -
SINTER不会阻塞主线程,但耗时仍随最小集合大小线性增长,线上慎用于 >10 万成员的集合
SADD 去重生效的前提:值必须是字符串
Redis Set 的成员只能是字符串,哪怕你存的是数字 123,它也是字符串形式。如果你传入 JSON 或二进制数据,只要序列化后唯一,就能去重;但如果不同业务逻辑生成了语义相同但格式不同的字符串(比如 {"id":1} 和 {"id":"1"}),Redis 会当成两个不同成员。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 统一序列化方式:推荐用紧凑 JSON(不带空格)或固定格式的字符串拼接,例如
user:123:tag:news - 避免浮点数直存:
3.14和3.140是不同字符串,建议转成整数毫秒或固定精度字符串 - 注意编码:UTF-8 是默认,但如果你的应用用了 GBK 存入,
SISMEMBER查询时也得用同样编码,否则查不到
交集结果要持久化?优先用 SINTERSTORE 而不是先 SINTER 再 SADD
很多同学习惯先 SINTER 拿结果,再遍历用 SADD 写新 key,这既慢又不可靠——中间失败就丢数据,还多一次网络往返。
-
SINTERSTORE dest_key key1 key2是原子操作,结果直接落盘,无中间态 - 目标 key 如果已存在,会被覆盖(不是追加),注意别误删其他数据
- 如果 dest_key 是热 key,频繁写入可能引发单核瓶颈,可考虑加随机后缀分片,如
common_tags_v2
真正容易被忽略的是集合编码切换:当一个 Set 全是小整数且数量 ≤512 时,Redis 用 intset(省内存、快);一旦插入字符串或超限,立刻升级为 hashtable。这意味着你无法靠“只存数字”来长期维持高效,尤其在混合业务场景下,SCARD 返回值正常不代表底层还是 intset。










