01
网易云音乐实时数仓架构
首先,从四个方面介绍云音乐的实时数仓架构:云音乐的实时场景、实时数仓架构、技术架构以及技术选型。
1.云音乐的实时场景
目前云音乐的实时场景主要分为以下三个部分,如图:
(1)实时特征
该场景主要是配合算法团队构建实时特征。实时数据作为推荐、搜索社区的数据输入,主要用于歌曲推荐、搜索热度、场景排序、新歌热歌推广等场景。其次,针对首页和搜索流量分发场景,为了提升流量的转化效率,可以对不同用户进行个性化的场景排序,如:偏向于听歌的用户会把推荐歌曲模块放在上面、偏向于听有声书的则将播客模块置顶等,从而提升用户的流量转化效率。
(2)场景监控
主要针对于资源投放效果和AB实时效果。实时和准实时的反馈可以尽早提醒业务运营或者业务中后台了解投放效果如何等。如果效果未达到预期,业务同学就有更充足的时间来分析其中的原因并进行调整。还有在针对机械刷歌和刷红心点赞的行为时,实时风控可以发现异常用户,并采取账号封禁或无效流量分流等策略,防止这类脏数据进入到业务数据,影响下游数据分析的准确性。
(3)数据产品
即实时大屏。通过实时大屏向管理层提供当天的流量转化和业务增长等最直观的数据表现。并且实时的用户分析、歌曲表现分析、活动分析、场景分析等特征数据作为业务输入,可以让运营有数据可依,从而更有效的进行精准推歌、活动运营,防止用户流失。
2.实时数仓架构
针对以上这些场景,云音乐构建了一套基于维度建模的实时数仓架构模型,如图:
(1)日志采集层(ODS):
接收来自日志服务器和业务服务器的原始流量数据以及业务数据库的binlog日志,作为实时数仓中间层的输入。
(2)数仓中间层(CDM):
实时数仓中间层根据日志采集层的数据进行清洗和解析形成流量中间层和业务明细中间层。目前流量中间层只对基于埋点的公共属性进行解析,而对于业务的个性化场景不会进行处理。原因在于实时数仓包含了主站所有的流量数据,业务直接使用的成本较高。即使流量中间层会基于各垂类场景进行分区分流,但例如会员这类横向业务场景仍然需要读取所有的垂类业务来获取全量数据。为了解决此类问题,云音乐构建了相应的业务明细中间层,进行个性化业务参数解析和流量聚焦。因此在基础流量中间层的基础上又构建了相关场景的业务明细中间层。比如:搜索中间层、直播中间层以及社区中间层等。
(3)数据应用层(ADS):
在离线数仓架构中,为了提升数据的复用度一般会构建DWS轻度汇总层,但在实时场景中因为流式计算的特性,轻度汇总层存在的意义就有待商榷了。
不过近些年来由于ClickHouse等OLAP引擎的兴起,部分实时场景为了高扩展性,更偏向于基于明细数据进行查询,而非直接查询计算结果。在这类场景下,通过OLAP引擎构建DWS表,则可以大大降低OLAP的存储量和前台业务的计算成本。应用层的数据基本上都是基于中间层聚合生成,应用服务可以直接读取这些数据,主要用于相关数据产品算法模型的输入、业务产品展示等。
(4)业务决策层:
基于构建的ADS表进行相关业务分析决策,并应用于推荐算法、实时风控和精准推歌等场景。
3.技术架构
云音乐的实时数仓技术架构基本上和目前大多数大厂的实时数仓技术架构类似,如图:
在离线场景下,基于Spark+Hive架构来实现。在实时场景中从ODS层到CDM层是通过Flink+Kafka的模式实现。从CDM层到ADS层,准实时场景是Impala+Kudu或者ClickHouse存储引擎,来支持OLAP即席查询。
4.技术选型
云音乐的实时数仓技术选型也是经过了场景适配、成本评估等一系列调研后才得出结论,主要有三条链路。这三条链路主要是基于业务对于时效性保障、稳定性、可扩展性和普适性的取舍。
(1)秒级实时需求
针对于大屏类和业务算法类需求,这部分场景对于更新频率、延时性要求极高。比如实时大屏要求看到秒级的数据变动、算法团队要求看到5分钟级别的用户特征更新。这类场景基本无法通过准实时链路来实现。因此这类场景的需求会通过Flink进行增量或全量计算,将结果数据写入Redis、HBase或MySQL等可以直接查询的业务数据源中。这类任务基本上都是优先级较高的实时任务,需要重点保障。因此还需要进行全链路多备份,防止由于集群问题对大屏数据或者业务数据产生影响。这类任务的消耗和异常的修复成本都是非常高的,所以需要尽量保证其高可用。
(2)准实时类数据产品
这类主要是5min以上的时效性需求,可以充分利用OLAP分析工具,通过Flink将明细数据写入到ClickHouse、Kudu或者Hive中。然后通过ClickHouse、Impala等OLAP引擎进行查询或者分钟级别的调度,实现数据计算。因为这套方案操作的是明细数据,因此较前一种场景的可扩展性会更强,但是由于需要通过OLAP引擎进行即席查询,这类产品一般需要进行新的技术栈探索,普适性比较弱,学习成本较高,分析师通常不会使用这种模式来进行数据分析。
(3)准实时类数据分析
这类场景对于时效性的要求会更低,一般是2小时以上的数据延迟。通过DS采集和Hive+Spark生成一套准实时的、小时级别的数据,通过批处理链路进行调度计算。该链路无其他特殊的技术栈,可以直接提供给分析师来使用,适配的分析场景也更多。并且可以将复杂的解析逻辑和清洗过程放到小时任务中,T+1的离线任务基于小时产出数据合并获取,可以大大提升离线基础表的产出效率。
02
网易云音乐流批模型一致性
1.Lambda架构
在构建实时数仓时,一般都会有相对应的离线数仓。主要用于历史数据的回刷以及更为复杂的场景支持,这样难免就会存在两条链路进行计算,流链路和批链路,这也就是我们常说的Lambda架构。
当天的数据会通过流计算任务处理生成实时表提供数据接口给数据应用。历史数据会通过批计算,生成离线表提供给数据服务。
实时和离线两套方案独立存在,这时可能会造成数据模型不一致的情况。云音乐大部分场景通过字段名称统一和表名统一来保证实时模型和离线模型的一致性。但是针对分区模型的话,实时场景比较难处理。
例如实时数仓中用户行为日志产生的信息通过DS采集写入到Kafka中,作为实时数仓的ODS层输入,并且还有一份会写入到HDFS中作为离线数仓的ODS层输入。通过实时数仓还有离线数仓的中间层解析操作生成流量中间层。
但是因为流量中间层的数据量过大,不可避免的需要对流量进行分区分流操作。在离线侧进行分区是比较容易的,可以通过Hive进行目录级别的分区,然后将数据文件动态的写入到分区目录中,通过Hive的元数据进行管理。而在实时侧则只能通过Kafkatopic进行物理分区,通过手工维护映射规则。这样会存在一些问题:第一,通过文档维护topic,维护成本非常高;第二,用户同样需要知道他们需要的信息是来自哪个topic,用户的开发成本和使用成本也非常高。
因此针对这个实时场景分区难维护的问题,网易云音乐搭建了一套Kafka的分区流表。具体模型如下图:
分区流表内部维护了一整套的分区字段到Kafka物理topic的映射规则。写入侧和读取侧是无需要