在分享数据服务中台建设之前,想从两个案例开始,从中可以感受传统数据获取过程中的一些痛点。
案例一:数据需求方A,需要获取每日up主的收入进行数据分析。首先,A需要向数据产品提取数需求,数据产品会与其沟通指标口径,如up主的范围,收入定义,还有没有其他要下钻的维度等等;口径定义清楚之后,数据产品把需求提给对应的数据分析师,分析师拿到需求和口径定义后,找数据源、手工SQL逻辑,从而拉取到对应的数据,最后提供给A。
案例二:数据需求方B,需要获取up主的收入数据,用于线上系统的展示。同样,也是需要提需求给数据产品,数据产品也是需要与其一起定义指标口径,确定好口径之后把需求提给数仓同学。数仓同学拿到需求及口径定义之后进行手工建模;建模完成后,与对应的业务系统开发进行沟通,因为对于数据量大小、性能要求、取数方式等不同,数据的出仓选型方案大不相同,所以需要与数据系统开发进行多次有效的沟通才能够确定存储选型。数据出仓完成后,系统开发需要手工编写API,经过联调测试发布到线上。
从这两个案例中,可以总结出两个问题:一、成本高,主要体现消费链路长、沟通成本高,不同需求可能会并造成模型重复建设;二、治理难,数据链路及血缘不清晰,上游数据发生了变更下游无法评估影响,另外,不同链路口径难以保障。
上面两个案例,也是烟囱式开发的典型场景。本身烟囱式开发会有比较多的弊端。弊端一:重复建设,包括重复计算、重复存储,造成资源浪费,同时功能上的重复建设也会造成人力资源浪费。弊端二:交付效率低,不同的系统、不同的开发同学对接不同的数据源,数据服务质量不可控,整个对接的标准也不够统一。
基于上述痛点,经过多次沉淀与总结,最终对数据服务中台有了一个清洗的定位,即能够一站式地完成数据的统一定义、统一生产和统一消费。
下图展示了B站数据服务中台的整体框架。可以看到整个中台是架构于数仓之上的,自下而上分为多个层次,包括数据构建层、数据查询层、服务接口层、服务网关,以及基于整个服务体系构建的产品体系,包括指标管理、模型管理、自助分析等等。
中台中,我们把用户定义为两大类角色,一类是数据生产者,另一类是消费者。数据构建层面向数据生产者,它的核心能力包括模型的定义、模型加速以及API的构建。
数据构建层:在维度建模思想中,数仓一般是分层分主题建设,可以快速地满足不同的业务场景的数据分析需求。那么在数据消费过程中,就需要多表关联形成分析视图进行数据分析。在平台上可以快速地通过自动化、半自动化方式构建出表与表之间的关系,生成一个逻辑模型,这个过程是数据模型的逻辑构建。我们知道,数仓中数据一般存储于冷引擎,对于线上系统的使用会有比较高的数据延迟,不具有可用性,那么平台上也实现了模型的自动的加速过程,让数据从冷引擎加速到热引擎,提升数据消费效率。构建层另外一块能力是API构建。API构建,主要是定义API 的请求参数、返回参数、数据源及数据的计算方式等等。单个的 API 就构成了一个标准的数据单位,经测试联调完成之后,即可发布到 API 的市场,供不同业务申请使用。
数据查询层:通过接口获取用户的请求参数,查询层经过解析、调度、翻译及计算后返回数据结果。查询层主要提供两种计算能力,原子计算及二次计算(复合计算)。原子计算主要处理的是格式相对单一,指标维度统一,引擎固定的场景,如些正查、反查、范围查等等。二次计算是在原子计算的基础上,采用一定的编排算法,去对于结果集进行二次加工。
服务接口层:接口形式分为同步接口和异步接口。请求方式包括DSL接口、模板接口、公共接口以及UDF接口等。同步接口主要是针对线上应用的一些查询场景,要求响应速度快,数据结果集相对较小,可直接快速地获取到数据并应用于系统。异步接口主要是针对于离线分析或者大数据量的文件下载的场景,对于响应速度要求不高,但是对于返回的数据量可能会要求比较大。
服务网关层:是提供给外部访问我们内部服务的一个统一入口,在数据服务中网关具备的核心能力主要是降级(如数据未就绪降级)、限流(流量峰值控制,保护服务稳定)、鉴权(屏蔽非法流量,保障数据安全)、缓存(热点数据,提升性能)。
主要是从两个核心角色看数据流转方式:数据开发和业务开发,数据开发即数据生产者,业务开发及数据消费者。数据开发在数据生产过程主要经历四个步骤:口径的定义、数据的构建、数据加速和API发布。
第一步:首先对指标进行定义,包括指标名称、指标领域、指标口径等信息。
第二步:构建数据模型,在平台上通过托拉拽的方式构建指标维度模型,以及定义模型中字段与指标维度的关系,计算方法,更新周期等技术口径。
完成了前两个步骤,基本实现了数仓开发同学对指标数据的定义与管理工作了。当有数据消费的需求时,则可以根据需求场景在平台做自动数据加速。
第三步:加速数据模型,根据消费场景,选择需求所需的指标维度信息,平台自动实现了目标表的DDL、SQL逻辑的自动生成、调度依赖配置、告警等过程。
第四步:构建API,根据业务数据请求及返回要求,选择数据源、定义字段的请求、返回参数属性,主备链路信息等,测试完成后即可完成一个API的市场发布。
在数据消费侧,当业务有数据需求时,去 API 市场里面找到数据生产者已经生产好的API,申请权限就可以使用了。如果API市场里面没有所需要的数据,就要走另外一条流程,提一个数据开发的需求给数据开发同学,然后数据开发同学增量地去构建一个数据结果到平台中去。当业务开发同学申请完这个API的使用权限之后,平台会授权给他一串密钥以及资源的标识。业务开发只需对接一次服务网关,即可重复利用。
把数据的生产与消费的开发流程解耦,数仓开发同学不用过多参与业务系统的开发过程,可以更加专注做指标的增量建设;对业务开发屏蔽了数据的加工处理过程,无需深入理解大数据知识,专注开发业务需求即可。
平台中对于模型的构建,支持多种构建方式,包括单例、星型、雪花以及星座模型等等。当模型构建完成后,平台支持支持的物化加速能力支持也表丰富。从性能及灵活度两个方便,对使用场景了做了划分。不同的使用场景,其加速方式及目标引擎有所不同。
明细加速:实现把逻辑模型中的数据从冷引擎到热引擎的镜像复制,极大保留了模型的原始数据的业务特性,可以更好的支持对模型中不同的维度及指标做多维分析或者范围查询,在热引擎中,加速数据的查询效率。
预计算加速:根据数据获取需求,从逻辑模型中的明细数据进行预计算及处理,直接聚合到所需粒度的数据,并将数据写入热引擎中。由于数据已经预计算处理,在数据查询时极大减少了引擎的计算,查询效率更高,但也损失了如多维分析及维度下钻查询的灵活性。
不同的场景有不同的加速方式及引擎选择的组合,针对四种类型的场景,推荐的组合如下:
在线场景:预计算+kv存储,一般应用于C端及B端的数据需求,有着极高的服务性能要求,且线上数据不会快速的变化,灵活度要求低。
准在线场景:预计算 + tidb/MySQL,一般应用于活动或者运营系统后台,服务性能要求不会同线上场景那么高,但同时要求支持范围查询,有一定的查询灵活度;对于数据量较大的查询场景,可以选择分布式数据库 Tidb,其他可以选择Mysql。
OLAP场景:明细+ ClickHouse/Iceberg,一般应用于数据分析系统,需要对数据进行多维分析,所以需要明细加速。ClickHouse 作为一款OLAP分析引擎,比较适合作为目标引擎,如果考虑到成本因素,也可以使用湖仓一体技术Iceberg,数据无需出仓既可在仓内完成数据的加速,性能虽不及ClickHouse,但也可以达到秒级的响应,特别是在使用成本及查询语法通用性上更有优势。
离线场景:离线数据获取,一般访问原始hive数据源即可。
API构建方式有两种:一种是通过模型构建,这是一种可视化的配置方式,用户已经明确知道要对某一个模型进行数据服务化,不需要用SQL编码,通过拖拉拽的方式就可以配置出来。另一种是基于指标维度的构建,指标维度构建是在模型构建的基础上的一种更高级模式,用户无需实现指定模型进行构建,可以先配置请求参数及返回参数,系统根据管理的模型元数据信息,按照一定的规则自动筛选出可以服务化的模型列表并给出推荐优先级。
下面介绍数据查询的能力,整体分为五个步骤。
步骤1:一个查询的DSL信息如下图图所示。解析的过程是把DSL信息与API配置进行匹配,并得出本次数据请求需要的模型。
步骤2:任务拆分是把解析的结果拆成子任务查询,解决异构数据源的结果获取问题。因为一次查询中可能会从多个模型中获取,模型也可以在多个引擎或集群中。为保证结果的的准确获取及查询效率,我们采用了拆分子任务的方式进行并发数据查询,子任务的查询结果经过二次加工处理返回。
步骤3:结果处理器是一个内存计算器,负责把子任务的查询结果进行拼接、排序、分页及格式转换等,返回统一格式的数据结果,让下游无感知数据的处理过程。
步骤3-1:翻译模块是把子任务的查询信息翻译成对应引擎可以识别的sql语法。AST是abstract syntax tree的缩写,也就是抽象语法树。翻译模块区别于引擎对执行SQL进行语法树解析的过程,而是逆向从构建AST开始,并最终翻译成SQL的过程。构建AST的算法如下图所示:
第一层AST从下面的"SELECT"开始,第一层语法树是构建出本次查询需要用的有效数据,包括构建模型关系、模型字段的筛选及数据范围的筛选
第二层AST从上面的"SELECT"开始,第二层语法树是基于第一层构建的有效数据,进行运算表达式计算,如 sum,count(distnct ..),sum(case when then end),sum()/count() 等其他一些自定义语法表达式。
通过两次的AST构建,可以完整表达一次原子计算所需的数据获取逻辑。根据构建的AST,系统会各个引擎的查询特性及方言,优化查询语法,提升查询性能,最终转化成可被引擎识别的查询SQL。
步骤3-2:引擎层负责执行各个子任务的查询SQL,系统适配了目前公司内部多种数据引擎,包括自研KV、TiDB、Mysql、ClickHouse、Iceberg等。除接入不同的引擎连接协议,在不同引擎的连接方式上也做了优化,如:mysql、tidb 由单次短连接改为连接池,减少连接的频繁创建及销毁带来的开销问题;自研KV多可用区连接,扩大在线服务可用的服务范围;OLAP引擎如ClickHouse、Iceberg的超时自取消功能,减少服务占用及降低引擎压力等。
在数据服务中台实践中,最重要的是实现全链路管控,让数据在服务化的过程中做到统一定义、统一生产、统一消费。
统一定义:口径不易维护的原因之一是管理不统一,散落在各个地方,导致大家没有统一的视角管理及查看口径。我们的的解决方案是口径统一在指标平台管理,其中把指标的定义及模型的定义解耦。指标定义是对分析对象的业务过程进行描述,计算方法的定义约束,可在数据模型建设之前确定,一般有数据产品角色实施;模型定义是根据数据需求及指标定义进行构建生产,模型中指定了模型字段与指标的关系,决定了模型中哪些字段可以生产哪些指标,一般有数仓开发角色实施。通过把指标定义与模型定义解耦,减少了不同角色间的沟通成本,让口径的定义可以延续到数据生产中。
统一出口:口径不易维护的另外的一个原因是定义与生产分离,出口不可控。我们打通了指标的定义及生产流程:模型的出仓可以自动化完成,出仓过程中的计算逻辑是基于指标平台中的定义自动生成的,减少了人工的干预,避免定义与生产的不一致;其次,API的取数逻辑非人工定义,也是基于指标定义,自动翻译取数逻辑及路由计算引擎,避免生产与消费过程中的不一致。通过定义与生产的打通,生产与消费的打通,数据流通过程中完全基于统一的定义,达到了最终的定义与消费的一致性。
全链路监控:数据从定义到生产到消费环节,有完整的监控链路,以此来确保口径的持续一致性。指标一致性监控:维度建模的数仓中,同一个指标由于分析思路或者需求场景,最终生产此指标的模型可能是多个,那么就需要保障指标在不同模型间的口径一致性。通过一致性对比或者闭环公式校验等手段,发现指标口径不一致,然后通过口径变更、模型换绑等治理方法来持续保障指标口径的一致;出仓一致性监控:出仓过程中数据集成工具保障了实时的一致性,这里需要保障的是,由于历史数据变更导致的出仓前后数据不一致的问题;服务质量监控:从数据出口监控数据的质量情况,主要包括阈值监控,波动率监控等,发现质量问题,保障出口的最终口径一致性。
中台的建设最终是要为企业降本增效的。过往中,不同业务线重复建设,垂直产品线烟囱式的开发,使得数据成为一个个孤岛,虽能满足单一业务场景,但是却增加了各个业务线的合作成本。
我们的建设思路是,首先将公共、通用的部分抽离出来,形成可复用服务,让业务可以快速完成数据链路的搭建,减少业务重复造轮子,降低研发成本;其次,统一服务标准,通过快速复用已建设的数据链路搭建的能力,让数据从定义-->生产-->消费的整个周期缩短,提升对接效率,为数据在不同部门间流转创造可能。
数据建设成本:通过模型、指标标准化的定义与管理,数据建设中的一个个表或者模型成为一个可以复用的标准数据资产,数据建设中只需增量建设,规避重复建设,降低数据的建设成本。
服务研发成本:服务通过标准化方式构建,下游使用无歧义,使得API复用成为可能,减少了服务研发成本,服务资源可以重复利用。
数据构建提效:数据构建时,通过元数据的管理,自动化及半自动化的构建出模型及指标,提高了数据构建效率;另外构建出的数据资产是标准化的,消除了数据格式、生产、存储等差异性,下游消费时不用关心底层的逻辑,提高了应用的效率。
服务使用提效:标准化的API,在系统对接时可以实现一次对接沟通,多次复用,提高了API的对接效率。
服务隔离:隔离是将服务或资源分割开。服务隔离是为了在服务发生故障时,能减少传播范围和影响范围,故障发生后不会发生滚雪球效应,从而保证只有出问题的服务不可用,我们根据服务的保障等级,划分为5个服务资源组,不同资源组相互独立,不会产生相互影响;存储资源隔离是通过资源隔离来减少资源竞争,保障服务间的相互不影响和可用性,我们将资源隔离做到API级别,不同API间及不同等级间做隔离,充分保障资源间的相互不影响。
异地双活:异地双活的目的也就是容灾,当某个地方服务出现了灾难性故障,而服务仍然能正常提供服务。我们根据业务的部署情况,选择距离业务较近的A、B两地机房部署服务,正常情况下同机房的请求链路为主链路,当某地服务宕机,则会自动降级到另外一地的服务。
最后分享我们的数据服务中台目前取得的成果,以及未来的建设规划。
B站数据服务中台上线一年左右,目前支持三大类数据使用场景,一种是API的使用场景,提供了API市场,包括在线、准在线、OLAP分析,以及实时的场景;第二块是支撑数据产品建设,包括业务分析产品、平台分析产品、主题分析产品等;第三是支持BI工具,比如自助取数、异动分析、下钻分析、自助报表等。
API的数量目前有600个以上,在性能和稳定性方面都有着不错的表现,数据开发周期从原来平均1周的时间,缩短到现在的1天左右。
未来我们会从五个方向去做数据服务中台建设:
第一个是服务治理方向,根据服务等级、服务监控、数据链路的信息,让服务能够高质量、低成本、强有效地运行。
第二个方向是支持更多的场景,比如推动一些平台类的产品接入,包括标签平台、AB 平台的等能够从服务中台管理及使用数据。
第三是服务编排,我们希望服务能够更加贴近于业务的需求,让数据能够做到即取即可用。
第四是降级容灾,希望能够做到日常的灾备演练、主备功能切换演练等。
最后就是持续的降本增效,在大数据计算资源效率、存储效率方面持续投入研发,向高效率、低成本更进一步。