利用布隆过滤器设计亿级用户视频浏览历史过滤系统:方案详解与内存预估
在短视频推荐系统中,如何高效过滤用户已看过的视频,避免重复推荐,是提升用户体验和系统性能的关键难题。本文以一个虚构的大小视频推荐APP为示例,APP规模为:1亿日活跃用户(DAU)和千万级视频池为例,结合布隆过滤器(Bloom Filter)技术,详细介绍一种可行的分层过滤与稀疏存储方案,涵盖方案实现、使用流程及内存预估,帮助读者快速理解并应用于实际系统。
一、布隆过滤器简介
布隆过滤器是一种基于位数组和多个哈希函数的概率型数据结构,用于判断某元素是否存在于一个集合中。它具有:
- 高空间效率:比传统哈希结构节省内存数十倍。
- 查询速度快:时间复杂度为O(k),k为哈希函数个数。
- 误判率可控:存在假阳性(误判存在),但无假阴性(漏判)。
- 不支持删除:标准布隆过滤器无法删除元素。
布隆过滤器广泛应用于缓存穿透防护、去重、推荐系统等场景。
二、系统规模与挑战
指标 | 数值 |
---|---|
用户规模 | 1亿日活跃用户(DAU) |
视频池规模 | 1000万视频 |
用户平均浏览量 | 约1000个视频/用户 |
误判率 | 0.1%(0.001) |
挑战:
- 每个用户维护完整浏览历史布隆过滤器,存储压力极大(数十TB甚至PB级,本例中需要约180T)。【具体分析过程参见附录1】
- 需要快速判断用户是否看过某视频,避免重复推荐。
- 保证系统高并发下的查询和更新效率。
对于每个用户都维护一个布隆过滤器的方案,对系统的存储需要和压力过大,常用的优化方案主要有以下三种:分时间窗口分片、分层过滤和稀疏存储,具体介绍如下:
1. 分时间窗口分片(Time-Window Sharding)
核心思想
将用户的浏览记录按时间划分为多个时间窗口(如天、周、月),为每个时间窗口单独维护一个布隆过滤器。过了时间窗口后,旧的布隆过滤器可以过期删除或归档,避免历史数据无限增长。
1.1 按时间窗口划分布隆过滤器
- 将用户浏览历史按固定时间粒度(如天、周、月)切分,每个时间窗口对应一个独立的布隆过滤器。
- 例如,用户2025年7月1日的浏览记录存储在
user_bf:<user_id>:20250701
,7月2日的存储在user_bf:<user_id>:20250702
。
1.2 维护机制
- 写入时:用户观看视频时,写入当前时间窗口对应的布隆过滤器。
- 查询时:推荐时查询最近N个时间窗口的布隆过滤器(如最近30天),判断视频是否看过。
- 合并查询:为了减少查询次数,可以将多个时间窗口的布隆过滤器合并(位或操作),得到一个综合过滤器用于快速判断。
1.3 过期数据清退
- 自动过期策略:利用Redis等存储系统的TTL(过期时间)机制,为每个时间窗口的布隆过滤器设置合理的过期时间(如30天或更长),过期后自动删除。
- 定期批量清理:后台定时任务扫描历史时间窗口的布隆过滤器,主动删除超过保留期限的过滤器。
- 归档与压缩:对于需要长期保存的历史数据,可将旧时间窗口的布隆过滤器导出归档,或做压缩处理,减少在线存储压力。
优势
- 限制存储规模:只保存最近一段时间的浏览历史,避免无限累积导致存储爆炸。
- 方便过期清理:可以直接删除过期时间窗口对应的布隆过滤器,简化数据管理。
- 支持时间维度查询:可以根据时间窗口灵活调整过滤策略。
应用示例
- 只保存用户最近30天的浏览历史,30个布隆过滤器轮换使用。
- 推荐时先查询最近窗口的布隆过滤器,若误判率允许,也可合并多个窗口的结果。
2. 分层过滤(Hierarchical Filtering)
核心思想
设计多个层级的布隆过滤器,先用一个全局或粗粒度的过滤器快速排除大部分未看过的视频,再用更精细的用户级布隆过滤器做最终判断。
层级结构示例
- 全局过滤器:存储所有用户看过的视频集合,快速过滤掉绝大多数未看视频,减少用户级过滤器的查询压力。
- 用户过滤器:存储单个用户看过的视频,精确判断是否重复。
优势
- 降低单个布隆过滤器的大小和查询压力。
- 减少用户过滤器的误判率和存储需求。
- 提升系统整体性能和响应速度。
应用示例
- 推荐系统先用全局布隆过滤器过滤掉大部分新视频,再用用户布隆过滤器过滤掉用户已看视频。
- 全局过滤器更新频率低,用户过滤器实时更新。
3. 稀疏存储(Sparse Storage)
核心思想
不是为所有用户都维护布隆过滤器,而是针对活跃用户或重点用户单独维护,非活跃用户可以合并处理或不维护,节省存储资源。
实现方式
- 活跃用户优先:只对活跃用户建立布隆过滤器,非活跃用户使用共享或全局过滤器。
- 用户分组合并:将用户分组,组内用户共用一个布隆过滤器,降低存储开销。
- 冷数据清理:定期清理或压缩非活跃用户的过滤器数据。
优势
- 大幅减少布隆过滤器数量和存储空间。
- 集中资源保障重点用户的过滤效果。
- 降低系统维护和更新成本。
应用示例
- 对日活跃用户(DAU)维护独立过滤器,对月活跃用户(MAU)使用合并过滤器。
- 结合用户画像和行为动态调整过滤器维护策略。
总结表格
优化方案 | 核心思路 | 优势 | 典型应用场景 |
---|---|---|---|
分时间窗口分片 | 按时间划分布隆过滤器,定期清理 | 控制存储规模,方便过期管理 | 只保留最近30天浏览记录 |
分层过滤 | 多级过滤器先粗后精 | 降低单个过滤器压力,提升查询效率 | 全局过滤器+用户过滤器组合 |
稀疏存储 | 只维护活跃用户或合并用户过滤器 | 节省存储,聚焦重点用户 | 活跃用户单独过滤器,非活跃用户合并 |
这些优化方案可以单独使用,也可以组合使用,帮助在海量用户和视频规模下,平衡存储压力、查询效率和误判率,提升推荐系统的整体性能和用户体验。
三、方案设计核心:分层过滤 + 稀疏存储 + 时间窗口分片
3.1 分层过滤(Hierarchical Bloom Filter)
- 全局过滤器:存储所有用户看过的视频ID集合,快速排除未被任何用户观看的视频,减少用户过滤器查询压力。
- 用户过滤器:存储单个用户看过的视频ID,精确判断该用户是否看过候选视频。
查询流程:
- 推荐系统先查询全局过滤器,若视频不存在,直接过滤。
- 若视频存在,再查询用户过滤器,判断该用户是否看过,决定是否推荐。
全局过滤器维护:
- 每当任一用户观看视频,视频ID加入全局过滤器。
- 误判率低且数据量大,内存约170GB,适合分布式部署。
3.2 稀疏存储(Sparse Storage)
- 用户分层:根据活跃度划分用户,重点维护高活跃用户的个人过滤器。
- 合并过滤器:中低活跃用户按组合并维护过滤器,降低存储和计算压力。
- 非活跃用户:不维护个人过滤器,使用全局过滤器或合并过滤器。
动态调整:
- 根据用户活跃度动态调整过滤器分配,保证资源合理利用。
3.3 时间窗口分片(Time-Window Sharding)
- 用户过滤器按时间窗口(如天)分片,保留最近N天数据(如30天)。
- 过期时间窗口的布隆过滤器自动清理,避免数据无限增长。
- 支持按时间灵活调整过滤策略。
四、内存使用预估
组件 | 参数与计算 | 内存估算 | 说明 |
---|---|---|---|
全局过滤器 | 元素数约 10111011,误判率0.1% | 约170GB | 存储所有用户看过视频ID |
用户过滤器 | 单用户1000视频,误判率0.1%,位数组约14,370位(1.8KB) | 1亿用户全量约180TB | 只对高活跃用户维护,实际更低 |
稀疏存储优化 | 高活跃用户20%(2千万)独立过滤器,合并过滤器覆盖中低活跃用户 | 高活跃用户约36TB,合并过滤器节省大量空间 | 动态调整用户分类和过滤器分配 |
时间窗口分片 | 保留30天,单日过滤器大小乘以30 | 乘以时间窗口系数 | 定期清理过期数据,控制规模 |
五、方案实现与使用流程
5.1 用户观看视频时
- 视频ID加入用户个人或合并过滤器(根据用户活跃度)。
- 同时加入全局过滤器,确保全局数据同步。
5.2 推荐候选视频过滤时
- 步骤1:查询全局过滤器,快速排除未被任何用户观看的视频。
- 步骤2:对剩余视频查询用户过滤器,判断该用户是否看过。
- 步骤3:过滤掉用户已观看视频,剩余视频进入推荐池。
5.3 维护与清理
- 利用Redis等支持TTL的存储系统,为时间窗口过滤器设置过期时间,自动清理。
- 定期批量合并更新合并过滤器,动态调整用户分类。
- 监控误判率和存储使用,调整哈希函数数量和位数组大小。
六、示例说明
假设用户A是高活跃用户,用户B是中低活跃用户:
- 用户A观看视频X,视频X加入全局过滤器和用户A个人过滤器。
- 用户B未观看视频X,视频X存在于全局过滤器,但不在用户B的合并过滤器中。
- 给用户B推荐时,查询全局过滤器发现视频X存在,继续查询用户B合并过滤器,发现视频X不存在,允许推荐。
- 这样避免了误将用户A看过的视频"屏蔽"给未看过的用户B。
七、总结
优点 | 说明 |
---|---|
存储效率高 | 结合分层过滤和稀疏存储,避免为所有用户维护完整过滤器,节省大量内存。 |
查询效率快 | 全局过滤器快速排除绝大多数视频,用户过滤器精细过滤,减少查询压力。 |
可控误判率 | 通过参数调整保证误判率在可接受范围内,平衡准确性和存储。 |
易于维护和扩展 | 时间窗口分片支持过期清理,动态用户分层支持弹性扩容。 |
本方案结合布隆过滤器的概率特性和系统设计最佳实践,适用于大规模视频推荐系统的用户浏览历史过滤,帮助开发者在保证性能和用户体验的同时,控制存储成本,实现高效推荐。
附录1
按上表中相关指标的系统,如果按为每个用户设计一个布隆过滤器的方案,需要的内存大小推导过程如下: 布隆过滤器中位数组大小 mm 和哈希函数个数 kk 的计算,是基于预期插入元素数量 nn 和允许的误判率 pp 通过数学公式推导得出的。
关键公式

对于1亿用户约180T,这对系统部署、存储方案以及成本上是一个大的挑战。
如果你希望深入了解布隆过滤器参数计算、分布式部署或具体代码实现,欢迎进一步交流。