Redis里怎么简单搞定集合去重,分享几个实用小技巧和思路
- 问答
- 2026-01-11 22:07:32
- 1
说到Redis里给集合去重,这其实是Redis最拿手的本事之一,因为它天生就是干这个的,咱们不整那些复杂的概念,就聊几个实实在在、上手就能用的方法和思路。
最直接的家伙:Set(集合)
首先出场的是Redis自带的Set数据结构,你可以把它理解成一个放东西的袋子,但这个袋子有个特点:同一样东西只能放一次,你往里扔再多个重复的值,它最终也只保留一个,这简直就是为去重量身定做的。
怎么用呢? 假设你有一批用户ID,想看看有哪些是唯一的,操作非常简单:
SADD key member [member ...]:这个命令是核心。SADD user_ids 1001 1002 1003 1001,执行完后,Redis的user_ids这个Set里,只会有1001, 1002, 1003这三个值,那个重复的1001自动就被过滤掉了。SMEMBERS key:用这个命令可以取出这个Set里的所有成员,得到的就是去重后的结果。
小技巧: Set不仅能去重,还能玩出花来,比如你有两个集合,想知道他们之间共同的部分(交集)、所有的部分(并集)或者不同的部分(差集),Redis提供了直接的命令:
SINTER key1 key2:取交集。SUNION key1 key2:取并集(并集本身也去重)。SDIFF key1 key2:取差集(在key1里,但不在key2里的成员)。
这在处理多组数据对比时非常方便,找出同时关注了A和B两个博主的用户(交集),或者找出所有至少关注了A或B其中之一的用户(并集去重)。
需要注意的点:
Set虽然简单暴力,但它有个小缺点:当成员数量非常非常大时(比如上亿),直接使用 SMEMBERS 命令可能会比较慢,因为它会一次性把所有成员都拉取到客户端,对于海量数据,可以考虑用 SSCAN 命令来分批遍历,避免阻塞Redis服务。
对付超大规模数据:HyperLogLog
你并不关心具体是哪些值重复了,你只想知道大概有多少个不重复的值,你想统计一个热门网页一天内有多少独立访客(UV),这个量级可能达到百万甚至千万,如果用Set把每个访客的ID都存下来,会非常消耗内存。
这时候,Redis的另一个神器就登场了:HyperLogLog,它的特点就是极其节省内存,只需要12KB的内存,就能统计最多2^64个不重复元素的基数(cardinality,即去重后的个数),并且误差率不到1%。
怎么用呢?
PFADD key element [element ...]:添加元素。PFADD daily_uv user_ip_1 user_ip_2 user_ip_1。PFCOUNT key:获取去重后的基数估算值,执行PFCOUNT daily_uv,返回的结果大概是2(因为user_ip_1重复了)。
小技巧:
HyperLogLog还支持合并,如果你统计了每天的数据,想算出一周的UV,可以用 PFMERGE destkey sourcekey [sourcekey ...] 命令把7个HyperLogLog合并成一个,然后计算合并后的基数,合并后的结果同样是去重且估算的。
重要提醒: 一定要记住,HyperLogLog不存储具体的元素,你无法像Set那样列出所有的成员,它就像一个只能显示数字、但看不到里面有什么的魔法黑盒,它只适用于那种“只要总数,不要明细”的场景。
高级玩家:布隆过滤器(Bloom Filter)
这是一个更进阶的思路,虽然Redis原生不完全内置一个叫“Bloom Filter”的数据结构,但我们可以用Redis的Bitmap和一些哈希函数自己实现,或者使用RedisModules(如RedisBloom)来直接使用。
布隆过滤器的核心作用是:用极小的空间代价,快速判断一个元素“一定不存在”或者“可能存在”于某个集合中。
这有什么用呢?一个经典的场景就是缓存穿透的防护,有人恶意请求一个数据库中根本不存在的数据ID,如果没有防护,每次请求都会打到数据库上,造成压力,我们可以在Redis里用一个布隆过滤器,把所有存在的数据ID标记进去,当收到请求时:
- 先用布隆过滤器查这个ID。
- 如果过滤器说“一定不存在”,那就可以直接返回空结果,不用查数据库了。
- 如果过滤器说“可能存在”,那我们再去查Redis缓存或者数据库。
为什么是“可能存在”? 因为布隆过滤器有极小的误判率(False Positive),它可能会把不属于集合的元素误判为属于,但反过来是确定的:如果它说不存在,那就一定不存在,这个特性对于防护缓存穿透已经足够了。
小技巧: 如果你使用的是云服务商(如阿里云、腾讯云)的Redis,或者自己可以安装RedisModules,强烈推荐直接使用官方或第三方提供的布隆过滤器模块(如RedisBloom),它提供了现成的命令,比自己用Bitmap实现要方便和稳定得多。
- 要精确去重,并且需要知道具体有哪些值:用 Set,简单可靠,还能做集合运算。
- 海量数据,只关心去重后的数量,不关心具体内容:用 HyperLogLog,省内存到极致。
- 需要判断某个值是否存在,以应对缓存穿透等场景,可以接受极小的误判:用 布隆过滤器,空间效率高,查询速度快。
选择哪个工具,完全取决于你的具体业务场景和需求,希望这几个小技巧能帮你简单搞定Redis里的去重问题。

本文由酒紫萱于2026-01-11发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/78938.html
