过去的几年里,随着大数据的进一步发展,现代数据栈的生态愈加丰富完善,而数据湖在这期间几乎已成为现代数据栈的必备品,它的出现大大简化了用户管理数据的难度,让用户更加关心于数据本身,而非组件本身。T3 出行在数据湖基础上,对现代数据栈进行了一些探索,并初步打造了特征平台。在本文中,我将给大家分享下 T3 出行结合公司业务场景,在现代技术栈这方面,做的一些探索于与实践,以及在此基础上打造的特征平台。
一、什么是 Modern Data Stack
现代数据栈是最近几年出现的一个新名词,其本质是一系列构建在数据仓库周围的工具。其主要出发点是给公司内部,如算法、数据处理、数据分析等团队提供一个更简单易用的产品,提升公司整体的运营决策效率。
1、Modern Data Stack 的特点
从字面上分析,Modern 译为现代化,寓意简单通用,Data Stack 就是围绕数据而展开的各种技术组件的组合。现在数据处理的领域有着丰富且复杂的业务场景,我们需要从这些场景里面,通过大数据技术把有价值的数据给提取出来。而界内并没有一个技术或者产品能够把数据处理的各个环节都做好,因此这就涉及到大数据技术组件组合的问题,如何把现代的这些大数据技术组件更好地组合起来,就是现代数据栈要解决的命题。
2、为什么要有 Modern Data Stack
为什么会有现代数据栈概念,这其实是技术发展的一个演变过程。十几年前,那时都是以传统数据库为主,都是从 Oracle、IBM 这类数据库厂商中做选择,选择不多,定好数据库后,公司的技术架构也只能根据厂商的意见来打造。
而现在随着企业数据规模、应用数量增长,以及应用技术组件丰富完善,云计算的产生和推广,进一步推动了数据库领域的发展。这使得现在数据软件价格和使用门槛大幅降低,企业有了更多的选择,可以根据具体的数据业务场景,来选择最合适的技术组件,从而围绕企业自身业务需求,量身打造一个足够低廉、性能足够优秀的架构。
当然现代数据栈的目的,依旧是从数据中提炼出有价值信息,为业务提供决策支撑,推动公司的业务发展。
3、Modern Data Stack 组成
现代数据栈主要分为数据统一存储、数据处理、数据分析、数据智能这四个部分,每个组成部分解决的问题如下所示:
统一存储:解决数据孤岛、降低数据环境的复杂度。
数据处理:原始数据加工、转换、ETL、任务调度。
数据分析:提取有用信息和形成商业结论。
数据智能:大规模机器学习和深度学习等技术对数据价值信息提取。
二、T3 出行的业务场景
T3 出行是一家基于车联网驱动的智慧出行平台,拥有海量且丰富的数据源。因为车联网数据多样性,随着业务发展,数据的增多,最初的传统数仓架构,遇到了诸多挑战,亟需新的架构迭代升级,更好的支撑公司业务发展。
通过归纳总结,T3 原来数仓架构面临挑战的业务场景分为三个点:支持长尾、非结构化的数据和小文件、算法业务场景。
1、支付长尾
T3 是一个出行企业,所以有很多的订单场景,而出行订单场景,在传统数仓里面临一个支付长尾的问题,业务层面订单支付周期可能长达数月,会存在长达数月的超长业务闭环窗口,同时也带来了冷热数据的更新问题。在长尾订单支付后,很久之前的数据需要做一些更新,在传统数仓里面去做很麻烦,要做级联更新,链路长,成本高。
2、非结构化数据和大量小文件
T3 出行的数据除了结构化数据之外,还有很多非结构化数据,比如说出行产生音视频数据,还有车联网相关的信号数据。同时,之前的数仓架构,因为数据更新太多,产生了很多小文件。另外 T3 的业务还有一些低延迟的场景,会实时产生结构化的小文件,比如车联网的雷达点云数据和日志打点数据。
3、算法业务场景
T3 的算法业务场景,主要分为三块:
营销业务:需要用户画像、广告推广。
风控业务:主要是保证出行安全,以及一些判责处理。
运力调度:车辆运力管理,智能调度。
三、T3 出行的 MDS 初步打造
围绕 T3 出行业务场景的特性,我们进行了现代技术栈的一个初步的打造,主要是围绕 Apache Hudi 和 Apache Kyuubi 展开。
1、Apache Hudi 体系
为了解决前面说的支付长尾和大量小文件的问题,我们引入了 Apache Hudi 这个组件。Hudi 是一个流式湖仓一体的平台,支持海量数据块的更新,它保证在时间轴上执行操作都是原子性的,这样保证了事物,适合 T3 订单类数据存储。
同时 Hudi 为了更好的支撑数据分析场景,支持了两种表模式,写时复制(Copy on Write,COW)表和读时合并(Merge On Read,MOR)表。
以及还支持了三种查询模式,包括快照查询、增量查询还有读优化查询。Hudi 通过上述特性支持,让业务根据不同的场景,选择最合适的表模式和查询方式,更好地支撑了业务分析。
另外 Hudi 支持对象存储,如阿里云的 OSS、AWS S3、华为的 OBS。T3 出行在将部分对象数据从 HDFS 迁移到 OBS 后,一定程度上降低了存储的成本。
2、Apache Kyuubi 体系
为了更好地支撑 T3 内部数据分析的场景,我们引入了 Apache Kyuubi 作为统一的网关。
Kyuubi 是一个 Thrift JDBC/ODBC 服务,由网易数帆发起,具备多租户和分布式等特性,为大数据查询引擎如 Spark、Flink 等提供 SQL 等查询服务。它最早是对 Spark Thrift Server 做加强,弥补了 Spark Thrift Server 多租户授权、高可用性特性的缺失,并在此基础上做了相关的拓展。后续 Kyuubi 开始演化精进,向统一网关的场景发展,以满足企业内诸如 ETL、BI 报表等多种大数据场景的应用。
T3 出行对于 Kyuubi 的使用除了在 ETL 和 OLAP 场景以外,还做了以下应用与拓展:
- 在开源的版本基础上做了些拓展功能,添加了监控管理页面。
- 最新的开源版本 Kyuubi 除去支持 Spark,还支持了 Doris 、Trino、Presto 以及 Flink,公司会更新使用版本,引入新特性。
- 监控和配置进行持久化存储,引擎配置可以在线更新。
- 在 Kyuubi 引擎管理的基础上,加强一些更细粒度的管理,如用户的流量管控、查询频次等,希望基于这个统一网关做更多的拓展。
3、T3 数据分析处理流程
基于 Hudi 和 Kyuubi,T3 的数据分析和处理流程的设计,也变得简单清晰,下面逐一道来。
(1)数据分析流程
对于数据分析场景,主要是使用 HUE Web UI 和 BI 分析工具(帆软),二者连接Kyuubi 这个统一网关。
HUE 一般是数据开发时候使用,通过 Kyuubi 连接 Spark 引擎,去执行 Spark SQL ,然后加工 Hudi 的数据,获得计算结果,从而完成整个开发。
BI 分析工具也是通过 Kyuubi,连接 Presto Engine 引擎后,查询加工好的 ODS 层数据后,通过 BI 报表进行可视化的展示。
整体的流程大致如下图所示:
T3 通过接入 Kyuubi 网关,收敛了数据分析入口,从而可以更好地管控用户使用。当然这也简化了用户的使用成本,毕竟用户不需要关心 Kyuubi 后面的引擎,不需要对接各种引擎的驱动,只需要对接 Kyuubi 即可,做到了开箱即用。
(2)数据处理流程
关于数据处理的场景,T3 在通过 Dolphin schedule 对处理任务进行调度,它通过 Kyuubi,对接 Spark 引擎,Spark 再对 Hudi 的数据进行加工处理。通过 Dolphin schedule 多租户管理,再结合 Kyuubi 的租户管理能力,T3 实现了 Spark 资源隔离,让不同的租户,即不同业务部门,连接不同的资源池,使用不同的资源配置。目前 T3 的任务日调度量大概是5万多,已经平稳运行了大半年,可以说这个架构还是很稳定的。
4、T3 整体的数据湖架构
基于 Hudi 和 Kyuubi 的一个基座,T3 搭建的数据湖架构,整体的形态如下图所示:
基于上图架构设计,逐个简单介绍下:
一站式平台的入口:这个主要是对接不同的平台,比如帆软、特征平台、算法平台等。
计算中间件:主要是用到 Kyuubi ,它作为统一网关,来支撑各类分析场景。
任务调度:主要通过 Dolphin Scheduler 来进行任务调度。
资源编排层面:目前是在 Yarn 上进行,后面会逐步迁移到 K8S 上进行资源编排,目前算法平台的一些开发场景已经迁移,后面所有的 Spark 和 Flink Job 也会陆续迁移。
数据存储管理:表的元数据存储主要还是使用 Hive Metastore;业务结构化数据,则是用 Hudi 的表来管理,数据则是存储在华为云的 OBS 上;非结构化数据,也是存在 OBS。相比于早期的 HDFS 存储,大大降低了存储成本。
数据接入层:主要是通过 Kafka 和 Canal 的订阅数据,然后入湖,持久化到 OBS。
四、特征平台 On MDS
1、模型开发流程
基于数据湖的架构,T3 打造了一个特征平台,在描述特征平台之前,先介绍模型开发的一个大致流程,大致如下图所示:
模型研发流程始于数据采集,大数据工程师利用采集的原始数据,通过 Spark 离线计算,加工生成算法需要的特征数据集,从而给到算法工程师用来训练模型,调参,等模型稳定后,就可以把训练好的模型部署上线,交付给到业务使用。业务方则通过传入特征数据给到模型,让模型实现在线推理计算,产生业务效果。
2、特征平台作用
从模型研发流程图中,可以看到线上线下都会用到模型的特征数据,这中间的特征加工过程,特征元信息,需要一个平台来统一管理。
而且有一些特征加工,比如说一些 ETL 的任务,可能是需要写 Spark 任务,这样对算法工程师不太友好,需要一些迭代,以及跨团队的沟通,效率很低,这也需要系统化的解决。
另外正常的特征计算一般是轻量级的任务,如果没有做好特征统一管理,可能就下推到了在线模型服务,里面会再做一些前置处理,以及特征转化。这样预处理被留在模型服务里面,甚至模型内部去进行,这增大模型在线推理的一个时延,这个代价还是比较大的。
基于以上几点原因,T3 需要打造特征平台,将人和人之间的沟通,变成人和平台之间的交互。将特征控制权交还给算法工程师,提高特征开发迭代的一个效率。通过特征管理,将权重更高的特征工程,放在那个特征加工的前面,尽可能地减少在线模型的时延,提高在线推理的一个效率。
3、特征平台的整体流程
整体来说,特征平台在算法加工的流程中,扮演着数据集的提取、加工和管理的角色,它将加工好的样本提供给模型开发和使用。训练好的模型部署在模型服务后,模型服务也会直接去特征平台去拿加工好的特征数据,然后统一提供给业务服务。
4、特征平台技术栈选型
在特征平台的流程中,涉及到数据集的管理,因此在技术栈选项上,需要一个数据集定义指标工具,作为特征数据的 Datasource。以及也需要一个特征存储管理组件,保证能够跟数据湖架构很好的组合对接。
(1)Metricflow
我们经过调研,选择了 Metricflow 这个开源组件,这是一个在国外比较流行的指标管理组件。它可以将简单的度量定义转化为一个可用的 SQL,并针对选择的 SQL 引擎去执行。另外它可以连接数据仓库,构建一个度量逻辑。同时也提供 Python SDK ,可以让用户在 Python 环境下进行分析,比如在 Jupyter 上直接运行分析指标。同时它能物化一些指标,根据定义好的指标和维度,能够将一些非规范化的数据集进行一个快速存储,背后实现是基于 Yarn 语义,按照它的一个规范定义一个数据源还有指标,然后Metricsflow 内部会解析语义文件,按照各个步骤生成 Dig,Dig 的表述会传递给选择的 SQL 优化器,然后生成对接的数据源所需要的 SQL 语义,并进行执行。
当然 Metricflow 主要支持是在连接数仓数据库这块,对一些非结构化数据存储,它不太能很好的支撑,所以基于它的语义层,T3 做了一些拓展。
(2)数据集语义
下图是一个数据集语义 Demo,可以在该语义中设置数据集的名称,Owner、所属项目、数据集的描述。除此之外,它可以定义数据集的查询逻辑。比如说查询的主表,Demo 中主表是 test 表,它关联到某个 DIM 层的一个维度表,然后进行了 left join 操作。通过将查询配置化管理,它会根据所选择的数据源 Hive 或 Kyuubi,转化成对应的 SQL 然后进行执行。
参考 Metricflow 对指标语义的定义,T3 对它做了一些拓展,以支撑非结构化数据集定义。比如一些非结构化的 OBS 数据,通过定义其 OBS 文件路径,就可以查询获取。另外拓展后还支持自定义数据属性,比如针对视频文件,在 CV 的训练场景,算法需要的一些像素级别、地理位置、时间场景等属性,这些也都可以在语义中定义,后续使用时可以直接获取。
(3)Feast-特征存储管理
上面提到了特征存储管理模块,T3 选择了 Feast。Feast 是一个用于机器学习的开源特征存储组件,对管理现有的技术架构,以产生用于模型训练和在线推理的分析数据提供了便捷。Feast 是 Tecton(一个美国机器学习数据平台)提供的一个开源版本特征管理模块,它支持离线特征存储,也支持在线特征管理,保证了特征的一致性。
Feast 通过统一的 Feast Server,对外提供了 Restful Api,供 Python SDK 或 Java SDK 调用,提供了统一的输出。
总的来说,Feast 通过提供从特征检索中抽象出特征存储的单一访问层,将算法开发和数据基础设施进行了分离,并提供了离线特征可以发布为实时特征的能力,让离线加工好的特征可以直接提供给在线模型推理使用,保证了特征加工的一致性和时效性。同时针对特征数据字段较多,数字化的特性,存储会进行定制化的序列化压缩,在有限影响性能基础上大大节省了存储空间。
(4)元数据管理
特征平台在 Metricflow 和 Feast 的基础上,进行了封装和二次开发,实现了元数据的管理。
对应像视频数据,车辆网数据,这些非结构化的数据,T3 参考了 Metricflow 的语义层,对非结构化数据存储的一些目录,以及自定义属性做了拓展,把它们都作为一个数据集来进行管理。
而对于业务结构化数据,则是存储在 Hudi 或者 Hive 的表里面。表的 Meta 信息则是使用 Hive Metastore 来这些存储管理。
通过上述操作,特征平台完成了对元数据、数据集的定义和管理。
5、特征平台内部架构
特征平台的内部架构,主要分为两块:离线数据的处理架构和实时数据处理架构。
离线数据处理架构,以数据源为出点,根据数据源的定义,通过 Spark 进行数据集的清洗提取,再进行特征的视图封装,然后进行特征加工,加工好的特征视图数据会存储到Feast,进行特征的统一管理。最后则是通过一个 UI 界面的方式,来提供不同团队使用。
另外加工好的特征,用户可以在特征平台上,看到它的数据集来源,特征加工的逻辑。特征平台会对这些特征进行一些权限管理,让特征尽可能复用,这大大提高了特征使用的效率。
实时数据处理架构,则是通过 Kafka 消息队列,根据消息里面封装好的特征视图的,进行逻辑加工后,再通过 feature transform,最后进行一个存储。
所有经过处理的特征数据都会以 Data frame 的方式,提供给模型训练,比如在算法平台的 Jupyter 上面进行开发和模型训练,或者是提供给模型服务,通过 feature vector 特征向量的方式,传递给在线模型服务。整个过程都是通过特征平台这个统一的出口,做了统一的管理。这让整个特征加工模型训练,形成一个闭环。
6、特征平台 On MDS 架构
总的来说,特征平台的整体架构,是使用数据湖,以及一些在线数据源,通过大数据清洗提取数据集,再通过数据集进行离线或者实时的特征工程处理,加工成为特征数据,并对特征数据进行统一管理,统一对外部业务算法团队使用。
而特征任务计算流程,以及其血缘关系,都会通过任务调度 Dolphin schedule 进行统一管理,它负责和任务流的源数据,以及上下游任务进行打通,并且能够看到每个特征加工的任务情况。
特征平台则会对特征的元数据,比如特征名字、特征来源、特征的 schema 等进行管理,以及对整个链路,也是做了完善的监控,做到了任务全流程的数据源管理。另外特征平台离线和实时计算产出的特征数据,会提供到模型服务使用。
当然特征计算是需要用户自行开发一个调度任务,并进行维护,特征平台会提供一个 SDK 给到算法工程师,他们可以通过 Python SDK 和特征平台进行数据交互。
基于以上设计,就形成了当前 T3 出行现代技术栈的整体架构。
总结
回顾主题,现代数据栈的目标是大大简化用户管理数据的难度,让用户更加关心于数据本身,而非组件本身。T3 出行是在数据湖基础上,所打造的特征平台。希望能和大家进一步交流,通过现代数据栈更好的推动业务,同时降低开发和维护成本。也希望现代数据栈能在国内有更好的发展。
六、问答环节
Q1:特征计算是在什么样的团队,是业务团队还是数据团队?
A1:特征工程是算法团队做的,而打造特征平台主要是为算法团队提供辅助,比如说数据提取,原始数据加工。如果没有特征平台,那会给公司增加沟通成本,增加一些跨部门沟通,比如说算法同学找数仓团队要数据,甚至于可能一些工程团队需要他们跨部门进行协助。而有了特征平台后,绝大多数场景,比如像数据集的一个提取,算法同学可以直接通过封装好的 Python SDK,外加一些必要的配置文件,直接去调用获取加工好的数据集,整个过程算法团队可以自助完成。
Q2:风控是自研的还是组件?有什么组件可以推荐。
A2:不同公司的风控场景一般不一样,不过主要都是基于策略和算法进行配合着来做,这个没有什么特定的组件,需要公司先根据业务定制风控策略,然后在策略的基础上开发算法,进行过滤,二者相辅相成。
Q3:特征工程有哪些基本的组件?
A3:特征工程主要是对原始数据集进行算法处理,例如通过 bagging 算法,是一些统计类的操作。算法加工完之后,存储在 Feast,是做了向量序列化操作后存储的。这个跟 Hudi 是没有关系的,Hudi 存的是一些原始数据集的一个存储。
今天的分享就到这里,谢谢大家。