news 2026/5/30 17:40:45

美团二面挂了!问 “2亿日活怎么算”,我答 “Set集合”,面试官:你是想把 Redis 炸了吗?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
美团二面挂了!问 “2亿日活怎么算”,我答 “Set集合”,面试官:你是想把 Redis 炸了吗?

写在开头

昨天帮一位粉丝复盘美团二面,他说自己最委屈的是倒在了“Redis 海量数据统计”上。他在现场和面试官经历了这样一段“死亡对话”:

面试官推了推眼镜:“我们现在的 App 有 2 亿注册用户,大促期间预计有 1 亿用户登录。如何设计 Redis 存储方案来统计今天的日活(DAU),并支持快速判断某个用户是否登录?

老哥心里暗喜(这题我会啊): “这简单,用Set 集合!用户登录一个SADD一个,利用 Set 的去重特性,最后SCARD一下就是日活。”

面试官冷笑了一声: “那你知道存 1 亿个用户 ID(假设是 Long 类型),Set 需要消耗多少内存吗?Redis 单线程处理这么大的 BigKey,扩容和持久化时会发生什么?

老哥当场懵了,支支吾吾答不上来。

这一刻他才明白,面试官考的根本不是 API 怎么调,而是你对“底层成本”怎么算。

在小数据量下 Set 确实方便,但到了亿级流量,这简直是生产事故。

今天咱们就把这道题拆透,用“计算逻辑”“大厂架构视角”告诉你,为什么顶级架构师在这类场景下都不单纯用 Set。

第一步:算“笨办法”成本,揭露 Set 的致命陷阱

咱们先别急着写代码,先拿出计算器,算算朋友口中那个“简单”的 Set 方案。

假设用户 ID 是连续的 Long 类型,占 8 字节。

  • 你以为的内存:1 亿 × 8 字节 = 800 MB?错!大错特错!

  • 真实的 Redis 内存:Redis 的 Set 底层存储不仅存数据,还有dictEntryrobj等元数据开销,加上哈希表的负载因子导致的预分配。

在 64 位操作系统下,存储一个 Long 类型的字符串或数字,Set 内部每个元素平均大概需要50 - 64 字节的空间。

真实的账是这么算的:

结论:仅仅为了统计一天的日活,就要吃掉6.4G 内存

但这还不是最致命的。最致命的是你制造了一个核弹级的 BigKey:

  1. BigKey 阻塞:这是一个 6G 的巨型 Key,删除或过期时,主线程直接卡死;

  2. RDB 风险:生成快照时,fork 子进程复制页表,内存瞬间翻倍,甚至导致 OOM;

  3. 网络风暴:主从切换时,传输这个 6G 的 Key 会把网卡瞬间打满。

所以,Set 方案 = 生产事故

第二步:算“位图”优势,空间压缩 250 倍

看着面试官失望的眼神,这时候你必须祭出 Bitmap(位图)。

针对这种“只有 0 和 1 两种状态”(登录/未登录)的场景,Bitmap 是物理上的极致。它的底层是 String,但可以按 bit 操作。我们将用户 ID 作为 bit 的偏移量(offset),1 表示登录,0 表示未登录。

关键计算逻辑:

Bitmap 的大小不取决于“有多少人登录”,而取决于“最大的 UserID 是多少”。

题目中有 2 亿注册用户,假设 UserID 是连续的(1 ~ 200,000,000)。

对比冲击:

  • Set 方案:6.4 GB

  • Bitmap 方案:~24 MB

差距高达 250 倍以上!哪怕你要统计一整年的日活,Bitmap 加起来也不过 8GB 左右,完全在可控范围内。

第三步:生产环境的“进阶坑”,别忘分片

面试到这一步,如果你只答出 Bitmap,只能算“合格”。要拿“S card”,你得指出 Bitmap 的隐患:

单个 Bitmap 还是 BigKey 怎么办?

虽然 24MB 不算超大,但在高并发下,对同一个 Key 的频繁 SETBIT 操作(尤其是 Cluster 模式)会导致请求全部打向某一个分片(Slot),造成单点过热。

解法:分片(Sharding)。

将用户 ID 模 1000,拆分成 1000 个小的 Bitmap:

Key = dau:20251215:001

...

Key = dau:20251215:999

这样既打散了流量,又避免了单个 Key 过大。

注意:统计总数时,需要在应用层并发查询这 1000 个 Key 的 BITCOUNT 然后累加。

第四步:架构师视角(大厂是如何做日活统计的?)

如果面试官继续追问:“如果我的 ID 不是连续的数字,或者是雪花算法(Snowflake)生成的 19 位 ID 怎么办?老板想看北京地区的日活怎么办?”

这时候,Redis Bitmap 就不是银弹了。大厂通常采用“组合拳”

1. 稀疏 ID 场景 -> Roaring Bitmap

  • 痛点:如果 ID 是 19 位的,直接用 Redis Bitmap 会申请一段巨大的内存(PB级),中间全是 0,极度浪费。

  • 解法:使用Roaring Bitmap(压缩位图)。它在 Java 内存或大数据引擎中使用,对于稀疏数据,它使用数组存储;对于稠密数据,自动转换为位图。既省空间,又保留了位运算的高效。

2. 允许误差的大盘数据 -> HyperLogLog

  • 痛点:几千个业务线都要统计日活,内存还是不够用。

  • 解法Redis HyperLogLog。无论日活是 1 万还是 10 亿,固定只占 12KB 内存。虽然有 0.81% 的误差,但对于实时大盘展示完全够用。

3. 多维度 BI 分析 -> ClickHouse

  • 痛点:老板要看“北京地区、使用 iPhone、版本 v2.0 的日活”。

  • 解法:Redis 做不到多维交叉。这时候数据要清洗入库ClickHouseDoris,利用它们内置的bitmap函数进行 SQL 级的多维聚合分析。

面试标准答案模板:这样说,技术总监会觉得你是“自己人”

把上面的推导串起来,这就是可以直接输出的“专家级”回答:

“面试官您好,这道题不能直接拍脑袋选数据结构,需要结合数据基数、ID 特征和业务场景来分层设计。

  1. 在 C 端实时场景(如判断用户是否登录):

    我会排除 Set 方案,因为它有 6.4GB 的内存开销和 BigKey 风险。

    我会首选 Redis Bitmap。对于 2 亿用户,内存仅需 24MB。为了防止热点,我会按 UserID 取模进行 分片 处理。

  2. 针对特殊 ID 场景(如雪花 ID):

    如果 ID 极其稀疏,Redis Bitmap 会造成空间浪费。我会引入 Roaring Bitmap 算法,或者在 Redis 外部维护一套‘UserID -> 自增 ID’的映射表。

  3. 在 B 端分析场景(如多维统计):

    如果业务需要统计‘北京地区+安卓’的日活,Redis 很难胜任。我会建议将数据落入 ClickHouse,利用其内置的 Bitmap 类型进行多维交叉分析。

总结就是:实时查状态用 Redis 分片 Bitmap,多维分析用 ClickHouse,大盘估算用 HyperLogLog。”

写在最后

Redis 面试题从来不是考你“API 熟不熟”,而是考你“对资源的掌控力”

  • Set是逻辑上的集合。

  • Bitmap是物理上的极致。

  • Roaring BitmapClickHouse是架构上的宽深。

遇到海量数据,先拿出计算器算内存,这才是资深开发该有的本能。

https://mp.weixin.qq.com/s/jjIG8AkM3rN8YJHMKvnwqQ

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/27 6:29:28

别急着算距离——聊聊《最短单词距离 II》背后的工程思维

别急着算距离 ——聊聊《最短单词距离 II》背后的工程思维 作者:Echo_Wish 一、先说个扎心的现实: 这题考的不是算法,是“你会不会为未来买单” 第一次看到 Shortest Word Distance II,很多同学的反应是: “不就是算两个单词在数组里的最短距离吗?” 然后很自然地写出…

作者头像 李华
网站建设 2026/5/22 19:12:57

如何ping指定IP的端口号_ping 端口

如何 Ping 指定 IP 的端口号(检测端口是否开放) 普通的 ping 命令只能检测主机是否可达(基于 ICMP 协议),无法检测指定端口(如 80、443、3306 等)。要“ping 一个端口”,实际上是检…

作者头像 李华
网站建设 2026/5/28 6:23:59

计算机视觉项目首选环境:PyTorch-CUDA-v2.8镜像实测推荐

PyTorch-CUDA-v2.8 镜像:计算机视觉项目的高效开发利器 在现代深度学习项目中,尤其是计算机视觉方向,一个稳定、开箱即用的开发环境往往决定了从原型验证到生产部署的速度。尽管 PyTorch 因其动态图设计和强大生态广受青睐,CUDA 提…

作者头像 李华
网站建设 2026/5/22 22:02:00

终身学习:构建能持续进化的AI Agent

终身学习:构建能持续进化的AI Agent 关键词:终身学习、AI Agent、持续进化、机器学习、知识更新、元学习、强化学习 摘要:本文聚焦于构建能持续进化的AI Agent这一前沿主题,深入探讨了终身学习在AI领域的重要性。详细介绍了相关核心概念,如AI Agent和终身学习的原理与联系…

作者头像 李华
网站建设 2026/5/26 10:56:49

HuggingFace Trainer自定义训练循环:超越默认封装

HuggingFace Trainer自定义训练循环:超越默认封装 在深度学习的实际项目中,我们常常会遇到这样的场景:一个基于 BERT 的文本分类模型已经用 Trainer 快速跑通了 baseline,但接下来想要引入对比学习增强语义表示、或者同时微调多个…

作者头像 李华
网站建设 2026/5/23 4:14:21

长期投资在波动市场中的优势

长期投资在波动市场中的优势 关键词:长期投资、波动市场、投资优势、资产配置、复利效应 摘要:本文聚焦于长期投资在波动市场中的优势。通过深入剖析波动市场的特点以及长期投资的核心原理,从多个角度阐述了长期投资在应对市场波动时所展现出的独特优势。详细介绍了相关的数…

作者头像 李华