其他
数仓服务平台建设实践
01背景介绍
广告人群 USP、DMP 系统每天需要通过 HiveServer 以流的方式从数仓导出数据到本地,每个人群的数据量从几十万到几个亿,人群数量 2w+,每个人群运行时间在 30min +,部分大人群的运行直接超过 1h,在资源紧张的情况下,人群延迟情况严重。 数仓的数据在被数据产品使用时,需要为每个表新生成一个单独的接口,应用端需要为每一种访问方式(如 Presto、ClickHouse)区分使用不同的接口,导致数据产品接口暴涨,不方便维护,影响开发及维护效率。数据在不同的存储时,需要包含 clickhouse-client,presto-client 等等第三方 jar 包。 不同数据产品中都需要使用一些常用的数据指标,如销售额、订单数、PV、UV 等,而这些数据在不同数据产品的实现口径、实现方式都不一样,无法形成数据共享,每个数据产品都重复进行相同的指标建设。因此,在不同数据产品查看相同指标却发现数值不同的情况下,难以判断哪个数据产品提供的数据是准确的。
02架构设计
应用接入层:业务申请接入时,可以根据业务要求选择数据服务 API(TCP Client),HTTP 以及 OSP 服务接口(公司内部 RPC 框架)。 数据服务层:主要执行业务提交的任务,并返回结果。主要功能点包括:路由策略,多引擎支持,引擎资源配置,引擎参数动态组装,SQL Lispengine 生成,SQL 自适应执行,统一数据查询缓存,FreeMaker SQL 动态生成等功能。 数据层:业务查询的数据无论在数仓、Clickhouse、MySQL 还是 Redis 中,都可以很好地得到支持,用户都使用同一套 API。
Master:负责管理所有的 Worker、TransferServer、AdhocWorker 节点,同时负责调度分发作业; Worker:负责执行 ETL 和数据文件导出类型的作业,拉起 AdhocWorker 进程(Adhoc 任务在 AdhocWorker 进程中的线程池中执行),ETL 类型的作业通过子进程的方式完成; Client:客户端,用于编程式地提交 SQL 作业; ConfigCenter:负责向集群推送统一配置信息及其它运行时相关的配置和 SQLParser (根据给定的规则解析、替换、生成改写 SQL 语句,以支持不同计算引擎的执行); TransferServer:文件传输服务。
03主要功能
多队列调度策略
多引擎查询
多任务类型
文件导出
资源隔离(Worker 资源和计算资源)
引擎参数动态组装
自适应 Engine 执行
SQL构建
单表模型:一张事实表,一般为 DWS 或者 ADS 的汇总事实表。 星型模型:1 张事实表(如 DWD 明细事实表)+ N 张维表,例如订单明细表 (事实表 FK=商品 ID) + 商品维表 (维度表 PK=商品 ID) 。 雪花模型:1 张事实表(如 DWD 明细事实表)+ N 张维表+M 张没有直接连接到事实表的维表,例如订单明细表 (事实表 FK=商品 ID) + 商品维表 (维度表 PK=商品 ID,FK=品类 ID) + 品类维表(维度表 PK=品类 ID)。
任务调度
多队列+多用户调度
每个队列都有自己的权重,同时会设置占用整个集群的资源总量,如最多使用多少内存、最多运行的任务数量等。 队列中的任务也有自己的权重,同时会记录这个作业入队的时间,在排序当前队列的作业时,利用入队的时间偏移量和总的超时时间,计算得到一个最终的评分。 除了调度系统本身的调度策略外,还需要考虑外部计算集群的负载,在从某个队列中拿出一个作业后,再进行一次过滤,或者是先过滤,再进行作业的评分计算。
SQL作业流程
Metrics 采集
解决的性能问题
人群计算任务的数据本地性不好; HDFS 存在数据热点问题; HDFS 读写本身存在长尾现象。
计算与存储同置,这样数据就不需通过网络反复读取,造成网络流量浪费。 减少 HDFS 读写长尾对人群计算造成的额外影响,同时减少人群计算对于 HDFS 稳定性的影响。 广告人群计算介于线上生产任务跟离线任务之间的任务类型。这里我们希望能保证这类应用的可靠性和稳定性,从而更好地为公司业务赋能 通过数据服务执行人群计算。
基于 Alluxio 的缓存表同步
定时任务发起轮询,检测源表是否有新增分区。 发起一个 SYN2ALLUXIO 的任务由数据服务执行。 任务执行脚本为将 Alluxio 表添加与 HDFS 表相同的分区。 分区添加完成之后,Alluxio 会自动从 mount 的 HDFS 路径完成数据同步。
人群计算任务
04总结
不同 engine 存在同一个含义函数写法不一致的情况。这种情况在 Presto 跟 ClickHouse 的函数比较时尤为突出,如 Presto 的 strpos(string, substring)函数,在 Clickhouse 中为 position(haystack, needle[, start_pos]),且这些函数的参数顺序存在不一致的情况,如何更优雅地支持不同 engine 的差异情况还需要进一步思考。
人群计算采用业界通用的 ClickHouse BitMap 解决方案落地,提升人群的计算效率同时扩展数据服务的业务边界。