本次分享分为四大部分,第一部分总体介绍翼支付公司概况和业务,在数据治理过程面临的场景、目标、挑战;第二部分介绍数据开发与治理平台,其中涉及到的任务开发与双环境部署运行;第三部分介绍数据平台的架构,分享在系统架构、调度引擎选型、数据总线、质量监控与资源隔离、计算优化等实践经验;第四部分与大家共同探讨未来面临的问题和可以优化的方面,展望更优的平台目标。
一、翼支付公司与业务介绍
天翼电子商务有限公司(以下简称“翼支付”)是中国电信集团有限公司的成员企业,是国资委双百改革和发改委第四批混改“双试点”企业,也是“双试点”企业中唯一的金融科技公司。公司以翼支付 APP 为载体,面向 7000 万月活用户,提供民生缴费、消费购物、金融理财等服务内容,依托区块链、云计算、大数据、人工智能等技术,赋能超 1000 万家线下商户门店及 170 余家线上知名电商。秉持“响应监管、服务民生、资源共享、合作多赢”的理念,聚焦“开放、安全、便捷”的核心产品力,翼支付坚持通过服务投入与产品升级,构建贴合需求的管理与业务体系,以交流融合的业务实践,推动产业各方实现数字化转型。
构建数据开发与治理平台的业务场景:满足数仓、各业务部门快速开发、离线计算、数据集成、实时数据开发、数据服务等功能,提升数据开发与治理效率。
我们的目标:构建先枢-数据开发与治理平台,集成数据集成、离线计算、实时计算、数据服务,提供一个一体的集成化开发平台,一站式满足数据开发人员研发诉求。
我们所面对的挑战:海量数据处理、高并发请求、低延迟时效性、业务多样性、场景复杂性。
二、数据开发与治理平台介绍
1、任务开发流程
任务开发首先需要创建业务流程,这里的业务流程(Flow)用来管理一组任务,任务主要是数仓的离线调度,涉及到数据集成、发布以及 SparkSQL 的离线任务。在开发完任务脚本之后,再进行任务核心参数的设置,比如运行的优先级队列、任务的相互依赖关系、运行参数,在配置完参数后,接着对任务可以测试执行,测试运行通过后可以对任务进行上线。这里任务以业务流程(Flow)为单位进行上线,上线完成后,交给管理员的任务审核,审核主要检查任务消耗资源、并行度、开发规范等,审核通过后发布到生产环境中。发布到生产环境后,通过提交到调度引擎进行日常定时调度工作。
数据开发中包含了一些功能,在画布中新建业务流程,拖拽相关任务节点到画布上,进行任务节点依赖配置。根据业务分类,提供了一系列任务开发功能,包含了五种任务类型:
① 数据同步:包含像 Oracle、OceanBase、Mysql、SFTP、Hbase 的数据接入与发布;
② Spark任务:SparkSQL 的离线计算;
③ 机器学习:AI 模型任务;
④ Kylin 任务:调度 Kylin 数仓 job;
⑤ 触发型任务:满足外部平台的接口触发数据治理平台启动数据任务,比如外部系统进行人群圈选数据推送、其他数据加工相关工作。
SparkSQL 任务开发编辑器页面,包含的功能有:
① 新建 SparkSQL 任务:通过拖拽建立 SparkSQL 任务节点并编写脚本,完成编辑后,可通过语法校验,提示 SQL 编写报错问题;
② 单次执行:Spark 任务提交到集群运行,测试通过后,可以进行提交,最终保存,经过任务审核后,即可部署到生产进行运行;
③ 自动任务依赖配置:系统会自动通过 SQL 语法解析到任务来源表,数仓按照统一开发规范,每一个任务有唯一的去向表,做到任务之间最细粒度统一,便于管理,来源表可以有多个,通过 SQL 解析拿到对应源表,通过任务解析,找到上下游节点,自动生成边关系;
④ 手动添加依赖:通过手动搜索任务,添加任务到依赖上;
⑤ SparkSQL 权限解析:根据从元数据配置的用户相关权限,进行用户对应数据库表的操作权限;
⑥ 血缘关系:如图展示一个任务流程 Flow 下面的所有任务跨 Flow 血缘关系。
早期数据开发与治理平台是单环境架构,但在平台任务上线时,会遇到一些偶发问题,比如线上任务紧急修复上线时,SQL 脚本未经过审核,导致任务会占用过多资源,还有 SQL 相关代码不规范等问题,因此使用了双环境上线流程解决脚本流程规范。
所有的 Flow 在开发和生产各有一份,通过镜像的操作,每个 Flow 和 Task 有相关的 code 标识一一对应,唯一区别是开发环境的 Flow 的 code 有 dev 前缀,比如开发环境任务 code 为 dev0001,那么生产环境的任务 code 对应为 0001,方便系统和用户区分。
在调度层面,这样的区分方式可以避免底层调度引擎、数仓层感受到上层的变化,比如 dev 环境的 Flow 有相关任务在运行,而其对应的生产任务也在运行,但是通过唯一的任务 code 进行区分,能使这些任务同时运行在两个环境,生产正常调度,开发环境并行开发。
在底层设计层面,开发环境去掉前缀,即可映射到生产环境任务,同时在应用层可以统一存储,也就是生产环境和开发环境的 Flow 和 Task,可以分别在一张 Flow 表和 Task 表中进行存储,简化设计,令底层数仓和调度层无感知。
版本管理为了满足数仓开发脚本的、任务之间依赖、业务流程配置、调度更改的版本回溯的需求,针对所有 Task 和 Flow 进行版本管理,再发布到生产,生产同步到开发环境,都可选择任意版本进行发布和回滚。
三、平台技术架构实践
1、整体架构概述
上图展示了整体系统架构:上面模块是应用层,下面是调度层。
配置管理:包含业务空间管理、成员管理和库映射管理。空间、成员管理是对应部门人员之间的资源、数据权限隔离;库映射管理,适用于解决来源库与去向库映射关系,比如数据接入时,落到哪些仓库,可以通过配置进行管理;
数据开发:包含数据集成、离线开发、数据发布、实时作业和 FlinkSQL 指标开发。
任务管理:包含业务流程管理、任务上下线、任务重跑补数操作以及任务的血缘依赖管理。
外部服务:元数据功能,主要用于在用户创建表后,对表详情进行查看,以及从中获取所有表、库、权限;用户中心功能,主要用于配置相关平台用户账户管理和各子平台的权限管理;AI 服务功能,主要用于管理机器学习模型任务,通过接口调用该机器学习服务;质量作业功能,主要用于在数据任务开发完成后,核验数据的质量。
调度层:Airflow 是调度的核心模块,橙色部分为围绕 Airflow 扩展开发的组件,包括任务管理,自定义 Operator(支持 SparkSQL 和数据交换相关的任务提交)。
2、调度引擎
关于调度引擎,最初对比的有 Zeus、Airflow、Azkaban。Zeus 支持分布式调度,但对 Hadoop、Spark、数据交换调度不完善,社区活跃度下降;Airflow 的 Python 扩展方便,功能完善稳定,2.X 支持多 Master 分布式调度,社区活跃;Azkaban,由 Java 开发,但调度任务功能相对简单;最终选择 Airflow1.10(技术选型时 2.x 版本还未稳定)作为生产离线调度引擎。
Airflow 目前仅提供一些 Web 界面上的管理操作,没有提供相关 Rest 接口,用户将 Airflow 的 DAG 文件放在 DAG Directory,Scheduler 进行扫描,会把对应的 DAG 的元数据存储到 MetaData 的 DataBase,DAG 对应上层应用的业务流程 Flow,管理了一组任务。Workers 支持扩展,分布式部署多节点。在生产环境中 Airflow 主要适合使用 CalaryExector 部署,本地环境使用 LocalExector 进行任务的调度。在翼支付生产中使用 Redis 作为 Celery 任务缓存队列,来加速任务调度性能。
Airflow 1.10 提供的 WebApi 比较少,在原生功能中使用 Git 或 Ceph 进行 DAG 文件存储,用户需要自己生成 DAG 文件放到集群节点,从流程来看引入对应组件,复杂性会提高,用户侧需要涉及生成对应的 DAG,上层应用生成 DAG 及业务流程管理工作。为了解决这些问题,通过扩展开发 Rest 接口功能,管理 DAG 的生成和 DAG 任务元数据,上面应用层通过 Rest 参数传递,帮助屏蔽底层调度引擎相关工作。DAG 文件上传到对应 Scheduler 和 Worker 节点后,Scheduler 会以 5 分钟为周期扫描,扫描到任务 DAG,才能完成任务的上线,之后进行 Dag 上线的回调动作,通过底层完成上线回调上层应用,避免了上层应用对上线的任务定期轮询状态,DagWorker 等待 DAG 上线成功进行回调完成任务的上线。
对于 DAG 文件的生成如上图所示。
external_task:对应外部任务,task >> task2,表示任务 2 依赖任务 1,同时也依赖了外部任务 ExternalTask1。整个 Python 文件就是 Airflow 调度的 DAG,AirFlow 内部会解析其中的 DAG 及其依赖关系,生成调度的元数据。
3、数据总线
我们使用 Datax 作为数据总线的核心模块,基于以上模板文件来执行任务,其调度是单机运行,但是 Datax 扩展性很好,并且预留了任务调度器接口,扩展 Source、Sink 以及数据转换逻辑、过滤开发,基于 Datax 封装了数据总线的任务管理功能。用户在页面输入参数,通过 Reader、Writer 插件来渲染生成 Datax 模板文件,Datahub 模块将文件通过 Yarn api 提交给对应的 Yarn 集群,之所以选用 Yarn 调度,是因为 Datax 是单机运行,不能做好多节点任务的调度。对比了 YarnCluster 与 K8S,暂时离线计算任务没有完全 K8S 容器化,采用 Yarn 的统一大数据离线调度任务提交到 Yarn 集群离线计算。
4、资源隔离、计算优化
资源隔离主要是对实时离线、不同任务之间集群隔离,比如数仓之间的业务转换、推数、任务分发不同类型作业。
数仓核心任务置于一级队列,其他部门基于其上,划分了子任务队列,有核心、重要、普通,三级优先级队列的资源隔离。
动态限流低优先级任务保障核心任务并发,当任务队列满了,先不提交普通任务,普通任务大多凌晨调度,新任务的限流可以保障普通任务的并发限制,避免普通任务优先调度,占用资源,核心任务需要等待计算资源。
在凌晨之前做普通任务的监控,避免普通任务调度之前被其他日常任务运行资源占满。
Spark 任务的优化包括:小文件治理,任务优化主要是资源优化、数据倾斜、Join 优化,以及任务拆分。
5、数据质量监控
质量监控主要在五大方面:及时性、准确性、完整性、一致性以及数据有效性进行分析改进。
数据质量监控的架构如上图所示,上面会配置相关的质量监控规则以及监控任务,质量规则分为强规则和弱规则,针对强规则进行任务熔断,对于弱规则进行事后分析改进。规则通过 SQL 对任务的数据一致性校验,整个规则任务以 SparkSQL 作业提交上进行计算生成规则报告,最后进行分析改进任务。
上面是作业的运行详情,质量作业通过 SQL 模板生成任务、作业名称,每条模板生成一条规则与记录,针对单个表会启动多个规则进行校验,单表的多字段校验,输出规则。若针对一张表有十个规则,第一个优先规则不满足,就会中断校验,直接返回流程。
6、云原生实践
数据开发平台流程涉及到实时、离线、数据总线、质量作业、监控、先觉 AI 模型,平台服务基于微服务架构进行拆分到不同子服务,满足业务快速迭代,从开发初期一直到最后上线经过多版本开发,模块变动对其他服务影响比较大,传统的大后端服务开发模式进行开发,模块的耦合影响重,通过对各个服务的拆分很好的解决了这些问题。
通过公司 KCS 的 CI/CD 平台提供服务的快速测试,迭代,部署上线。基础设施配有统一监控告警功能及自动扩容能力,提升服务稳定性。
整个开发平台迭代中,也伴随着数据治理流程,工作成效比较显著。整体计算成本降低 87%,模型特征计算时效提前 7.5 小时,看板数据查询时效提升 40 倍。
四、未来展望
数据开发与治理平台拆分的服务较多,与离线调度紧密相关,需要更好的性能与扩展。
可观测性:可以及时发现服务的不稳定性问题。比如当任务越来越多,任务之间状态会有并发冲突,带来的性能问题需要及时解决。
计算效率:目前有比较多的 SparkSQL 作业,需要根据专家经验和实际场景针不断优化离线 SQL。
异地容灾:现在的大数据集群部署在同一个机房,包括离线、实时计算。单机房会有异地备份诉求,需要多机房进行数据灾备,以及实时计算跨集群、在线数据服务应用实现跨机房容灾。
五、问答环节
Q1:数据权限是怎样管控和实现的?
A1:数据权限分为两块,用户在平台所属组织的权限与空间管理的那块进行了部分绑定,用户所属部门的操作权限限定了平台的数据权限;在元数据模块有设置用户对库表的相关权限,UDF 的需要加解密的敏感数据也会关联到用户,用户新建任务,其 SQL 解析后会涉及相关的表,与相关表的操作权限进行校验绑定。
Q2:数据治理是怎样做的,如何提升效果?
A2:早期的烟囱式的开发,计算成本相对高,计算性能较低,数仓针对其任务,伴随着数仓数据治理过程的需求,平台迭代研发满足数仓的开发作业的流程,平台针对调度任务的性能以及计算任务的性能优化作了相关支持,整体计算资源可以达到更好的效果。