当前位置:首页 > 文章列表 > 数据库 > Redis > Redis Set 去重统计不准怎么办:从 SADD 返回值到 Key 粒度一步步排查

Redis Set 去重统计不准怎么办:从 SADD 返回值到 Key 粒度一步步排查

来源:17golang原创 2026-06-15 12:58:44 0浏览 收藏

一个活动报名页显示“已报名 1250 人”,运营同学却说后台订单只有 1178 条。第一眼看像是缓存延迟,但我们不能直接下结论。Redis Set 做去重统计时,数量不准通常藏在三个地方:返回值理解错、Key 粒度混在一起、过期时间没处理好。

这篇文章我们从一个很小的现场开始,一步一步把问题拆开,看清楚 `SADD`、`SCARD` 和 Key 设计到底应该怎么配合。

摘要

Redis Set 适合保存“不重复成员”,常用于报名用户、接口请求编号、当天访问用户等场景。要让统计稳定,写入时要看 `SADD` 的新增结果,读取时用 `SCARD` 回查数量,同时按业务维度设计 Key,并给临时统计设置合理过期时间。

适合人群

适合正在用 Redis 做去重、UV、活动参与人数、幂等请求记录的后端同学。文章示例使用 Redis 命令和少量伪代码,不依赖特定语言框架。

目录

  • 问题现场:为什么显示数量比订单多
  • 先验证 SADD:它返回的不是总人数
  • 继续定位:Key 粒度混乱会把数据串起来
  • 修复方案:写入、统计、过期分开处理
  • 常见坑和最终检查

问题现场:为什么显示数量比订单多

我们先复现一个简单场景:活动 ID 是 9001,同一个用户可能重复点击报名按钮。业务希望“一个用户只算一次”,于是代码把用户 ID 写进 Redis Set。

SADD activity:join:9001 10001
SADD activity:join:9001 10002
SADD activity:join:9001 10001
SCARD activity:join:9001

按 Set 的语义,用户 `10001` 第二次写入不应该增加人数。如果页面仍然变多,我们就要先看写入逻辑是不是把每次点击都当成新增了。

Redis Set 去重统计问题现场:重复点击、SADD 写入、统计偏高、开始排查

先验证 SADD:它返回的不是总人数

第一轮猜测是:代码是不是误解了 `SADD` 的返回值?`SADD` 返回的是本次真正新增的成员数量,不是 Set 里的总成员数。

127.0.0.1:6379> SADD activity:join:9001 10001
(integer) 1
127.0.0.1:6379> SADD activity:join:9001 10001
(integer) 0
127.0.0.1:6379> SCARD activity:join:9001
(integer) 1

这段结果说明了两件事:第一次写入返回 `1`,代表新增成功;第二次写入返回 `0`,代表成员已经存在。要展示当前总人数,应该用 `SCARD`,不能把每一次请求都累加到一个普通数字字段里。

如果业务同时维护了一个 `join_count`,就很容易出现偏差:重复点击让计数器增加了,但 Set 实际人数没变。此时应以 Set 的数量为准,或者只在 `SADD` 返回 `1` 时再更新其他统计。

继续定位:Key 粒度混乱会把数据串起来

如果 `SADD` 返回值没用错,我们继续看 Key。很多统计不准不是命令错了,而是 Key 粒度太粗。比如把所有活动都写到同一个 Key:

SADD activity:join 9001:10001
SADD activity:join 9002:10001

这能去重,但统计某一个活动时就不方便,还容易在读取时切错维度。更清晰的做法是把活动 ID 放到 Key 里,把用户 ID 当成员。

SADD activity:join:9001 10001
SADD activity:join:9002 10001
SCARD activity:join:9001

这一步我们能定位到第二个常见原因:成员内容和 Key 维度混在一起,导致后续统计、清理、对账都变复杂。Key 负责业务范围,成员负责唯一对象,职责分开后排查会轻很多。

Redis Set Key 粒度排查:粗粒度 Key、活动维度、用户成员、单活动统计

修复方案:写入、统计、过期分开处理

现在我们把方案收拢。写入时只关心成员是否新增,统计时用 `SCARD`,临时活动结束后让 Key 自动过期。

SADD activity:join:9001 10001
EXPIRE activity:join:9001 604800
SCARD activity:join:9001

在业务代码里,可以把逻辑拆成三个动作:

added = SADD activity:join:{activityId} {userId}
if added == 1:
    写入报名记录或发送首次报名消息
count = SCARD activity:join:{activityId}

注意:如果活动 Key 已经存在,反复设置过期时间可能会延长活动窗口。更稳的写法是创建 Key 后设置一次过期,或者按活动结束时间计算剩余秒数,避免每天访问都把 Key 往后顺延。

Redis Set 修复流程:SADD 判断新增、SCARD 读总数、EXPIRE 管生命周期、对账验证

常见坑和最终检查

第一个坑是把 `SADD` 的返回值当总人数。它只能告诉你本次新增了几个成员,总人数要用 `SCARD`。

第二个坑是成员值不稳定。比如有的地方写用户 ID,有的地方写手机号,有的地方写 `user:10001`,这些在 Redis 看来都是不同成员,去重自然会失效。成员格式要统一。

第三个坑是大 Set 直接拉全量成员。统计人数用 `SCARD` 即可,不要为了数数量去读出所有成员。需要抽样排查时再用少量扫描,不要把全部成员一次性取回应用层。

最终检查可以按这四步走:

TYPE activity:join:9001
SCARD activity:join:9001
SISMEMBER activity:join:9001 10001
TTL activity:join:9001

如果类型是 `set`,数量和业务记录能对上,关键用户存在性正确,生命周期也符合活动结束时间,这个去重统计就基本稳住了。

总结

Redis Set 去重统计不准时,不要只盯着“Redis 有没有问题”。我们按现场一步步看,真正容易出错的是业务使用方式:把 `SADD` 返回值当总数、Key 粒度不清、成员格式不统一、过期策略顺延。

推荐落地规则很简单:Key 表示业务范围,成员表示唯一对象;新增看 `SADD`,总数看 `SCARD`,生命周期交给明确的过期策略。这样再遇到重复点击、重复请求或活动统计,就能少很多对账麻烦。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
前端详情页返回列表丢失滚动位置怎么办:从复现到恢复一步步排查前端详情页返回列表丢失滚动位置怎么办:从复现到恢复一步步排查
上一篇
前端详情页返回列表丢失滚动位置怎么办:从复现到恢复一步步排查
Linux crontab 定时任务不运行怎么办:从时间表达式到环境变量一步步排查
下一篇
Linux crontab 定时任务不运行怎么办:从时间表达式到环境变量一步步排查
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • MiMo Code - 小米大模型团队开源的新一代 AI 编程助手
    MiMo Code
    MiMo Code 是小米大模型团队开源的新一代 AI 编程助手,面向开发者提供代码理解、生成与辅助开发能力,适合作为 AI 编程工具收藏和体验。
    42次使用
  • TRAE Work - 字节跳动推出的 AI 原生工作台
    TRAE Work
    TRAE AI IDE | 国内首款 AI 原生集成开发环境,深度集成 Doubao-1.5-pro 与 DeepSeek 模型,支持中文自然语言一键生成完整代码框架,实时预览前端效果并智能修复 BUG。首创 Builder 模式实现需求到代码的自动化开发,兼容 Windows/macOS 系统,官网下载即用。
    63次使用
  • MeloLab - 一站式 AI 音乐生成与编辑平台
    MeloLab
    MeloLab 是一款 AI 音乐生成工具,可根据文本创意生成歌曲、人声、混音、分轨和背景音乐,适合创作者快速制作音乐素材。
    52次使用
  • ChatExcel酷表:告别Excel难题,北大团队AI助手助您轻松处理数据
    ChatExcel酷表
    ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
    8706次使用
  • Any绘本:开源免费AI绘本创作工具深度解析
    Any绘本
    探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
    9115次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码