B站千亿级用户行为数据分析架构演进与实践

发布时间:2026/7/18 2:52:20
B站千亿级用户行为数据分析架构演进与实践 1. 项目背景与业务挑战B站作为国内领先的年轻人文化社区每天产生千亿级别的用户行为数据。这些数据蕴含着用户观看、互动、消费等关键行为信息对内容推荐、运营策略和商业变现具有重要价值。然而传统的大数据分析架构在面对如此海量数据时逐渐暴露出三大核心痛点首先是查询性能瓶颈。早期基于Spark的批处理架构单次事件分析需要3分钟以上漏斗分析甚至需要半小时才能返回结果。这种延迟使得数据分析结果失去时效性严重制约了业务决策效率。其次是资源消耗问题。实时处理链路需要维持1200core的计算资源Redis维表占用400G内存Kafka需要300个分区。随着数据量增长存储成本呈指数级上升到2021年底ClickHouse集群存储利用率已超过90%。最后是功能局限性。明细数据模型难以支持复杂的留存分析和路径分析30天的查询窗口无法满足长期趋势分析需求私有参数变更需要重构整个数据管道。2. 技术架构演进历程2.1 第一阶段Spark批处理架构2019-2020初期采用典型的Lambda架构离线和实时两条独立管道离线层Hive数仓存储历史数据通过Spark Jar作业进行预聚合实时层Flink处理Kafka流数据写入Redis和HBase该架构存在三个致命缺陷资源分配僵化每个查询启动独立的Spark作业无法根据查询复杂度动态调整资源模型扩展困难用户维度信息硬编码在模型中新增分析维度需要重构ETL流程并发能力受限共享的Spark Session导致查询排队高峰期成功率不足80%2.2 第二阶段ClickHouse明细方案2020-20212020年引入ClickHouse作为核心OLAP引擎架构实现三大突破实时明细写入Flink直接清洗原始数据写入ClickHouse端到端延迟控制在秒级位图计算优化使用RoaringBitmap实现用户分群的高效交并运算字典服务升级String类型ID转Bigint压测支持40万QPS的编码转换性能指标显著提升事件分析P90响应时间从3分钟降至5秒漏斗分析从30分钟缩短到30秒实时数据可分析窗口从T1缩短到T0但代价是资源消耗剧增到2021年集群扩容三次后仍面临存储瓶颈。2.3 第三阶段IcebergClickHouse混合架构2021至今当前架构实现降本增效四重优化全模型化聚合千亿明细压缩为百亿级聚合模型存储降低40%Kappa架构统一Iceberg作为唯一数据源消除实时离线口径差异批量导入优化自研BulkLoad工具实现千亿数据小时级导入计算下推设计80%的计算在ClickHouse分片本地完成关键性能对比指标第二代方案当前方案提升幅度事件分析耗时30-50s2.77s10-18x漏斗分析耗时30s0.58s50x存储成本100%60%40%↓计算资源1200core800core33%↓3. 核心技术创新点3.1 混合存储模型设计采用热温冷三级数据分层策略热数据7天ClickHouse明细表支持亚秒级响应温数据30天ClickHouse聚合模型秒级查询冷数据180天Iceberg归档存储分钟级分析关键技术实现-- ClickHouse表分区策略 PARTITION BY toYYYYMMDD(event_time) ORDER BY (event_id, user_id) SAMPLE BY cityHash64(user_id) -- Iceberg分区映射 ALTER TABLE iceberg_bdp.uba_events SET PARTITION SPEC (year INT, month INT, day INT)3.2 高效字典服务自研分布式编码服务解决String类型转换难题编码算法改进Snowflake算法支持63位有序ID多级缓存本地Cache → Redis集群 → RockDB持久化容灾方案小时级Hive备份 批量恢复工具压测表现单节点QPS50万缓存命中率70%故障恢复20亿数据40分钟重建3.3 批量导入优化演进三代导入方案对比JDBC直写优点实现简单延迟低缺点写放大严重merge压力大HDFS中转优点资源消耗降低50%缺点额外存储开销网络瓶颈直连DataReceive服务采用HTTP流式传输服务端磁盘负载均衡性能较HDFS方案提升100%关键配置参数yandex data_receive max_concurrent_connections100/max_concurrent_connections max_receive_bandwidth1GB/s/max_receive_bandwidth /data_receive /yandex4. 典型应用场景实现4.1 事件分析优化私有参数处理采用创新Map结构# Spark聚合逻辑示例 def aggregate_events(df): return df.groupBy(user_id, event_id).agg( collect_list(public_params).alias(public_params), map_from_arrays( collect_list(private_param_keys), collect_list(private_param_values) ).alias(private_params) )ClickHouse查询优化技巧-- 低效写法 SELECT count(DISTINCT user_id) FROM events WHERE arrayExists(x - x click, private_params) -- 优化写法使用物化视图 SELECT bitmapCardinality(click_users) FROM event_stats_mv WHERE date today()4.2 漏斗分析加速窗口函数下推实现-- 原始查询中心化计算 SELECT windowFunnel(3600)(event_time, event_id page_view, event_id add_cart, event_id checkout ) AS funnel_steps FROM distributed_events -- 优化版本计算下推 SELECT sum(funnel_steps) FROM cluster(default, SELECT windowFunnel(3600)(event_time, ...) AS funnel_steps FROM local_events GROUP BY user_id )性能对比用户规模原始方案优化方案100万12.3s2.1s1000万78.5s9.8s4.3 路径分析实现桑基图数据生成流程原始事件 → 按user_id聚合为事件链过滤干扰事件心跳、自动刷新等构建前缀树统计路径频次RBM压缩存储用户集合关键ClickHouse函数WITH paths AS ( SELECT sequenceMatch((?1).*(?2).*(?3))(event_time, event_id play, event_id like, event_id share ) AS matched FROM user_event_sequences ) SELECT sum(matched) FROM paths5. 集群运维实践5.1 数据平衡算法两种平衡策略对比装箱算法极致均衡时间复杂度O(n log n)适用场景100TB表平衡效果变异系数0.1贪心算法快速平衡时间复杂度O(n)适用场景100TB表资源消耗迁移数据量减少60%平衡执行流程预检查part是否需要merge目标节点fetch part文件源节点detach part目标节点attach part源节点清理detached part5.2 查询监控体系三级监控策略实时拦截限制超过5分钟的查询SET max_execution_time 300慢查询分析每日TOP100查询优化机器人巡检自动检测缺失的skip index5.3 压缩优化实践ZSTD压缩效果对比表类型LZ4大小ZSTD(1)大小压缩率事件明细1TB680GB32%↓聚合模型200GB120GB40%↓路径分析80GB45GB44%↓配置方式ALTER TABLE events MODIFY SETTING compression zstd, compression_level 16. 未来演进方向6.1 多模数据分析正在开发的ZOrder索引技术-- 实验性功能 ALTER TABLE events ADD INDEX zindex (user_id, event_time) TYPE zorder预期效果多维度查询性能提升3-5倍存储开销增加15%6.2 实时能力升级Hudi替代方案设计增量摄取分钟级延迟近实时分析10秒级响应资源隔离独立计算集群6.3 服务端日志整合通用映射规则示例mappings: - source_field: req.path target_dim: page_url type: regex pattern: /video/(\\w) - source_field: duration target_metric: view_duration unit: ms从实际效果来看这套架构最宝贵的经验在于OLAP系统的设计必须遵循数据特征决定技术选型的原则。B站用户行为数据具有明显的时间局部性新数据访问频繁和用户聚集性少数用户产生大量行为因此采用时间分区用户分片的混合分布策略配合多级聚合模型才能实现成本和性能的最佳平衡。