10 月 23 - 25 日,QCon 上海站即将召开,现在购票,享9折优惠 了解详情
写点什么

数据仓库解决方案——ODPS 组件化改造之路

  • 2020-09-12
  • 本文字数:3250 字

    阅读完需:约 11 分钟

数据仓库解决方案——ODPS组件化改造之路

ODPS 简介:ODPS(Open Data Processing Service),是阿里巴巴通用计算平台提供的一种快速、完全托管的 GB/TB/PB 级数据仓库解决方案,现在已更名为 MaxCompute,MaxCompute 向用户提供了完善的数据导入方案以及多种经典的分布式计算模型,能够更快速的解决用户海量数据计算问题,有效降低企业成本,并保障数据安全。

场景还原

不知道你是否在写离线代码时遇到过以下几种情况:


  • 相同的业务代码逻辑分散在各个地方,需要维护多份相似功能代码;

  • 存在多张相同结构的表输入,需要经过相同或相似的逻辑计算加工,并输出给下游表;

  • 有一个计算逻辑非常复杂,需要经过多个子流程或多个节点处理,如何理清楚这些这些节点的逻辑和层次关系?


这里举几个场景,好让你更形象地理解。


  1. 在某个系统中,数据分大促活动数据和日常数据。大促活动数据优先级较高,需要每小时地调度计算,日常数据优先级较低,只需要天级调度。PS:在这个场景中,我们处理这些数据的逻辑高度地相似甚至相同,并且输入表和输出表的 schema 也是一样的,唯一不同的是调度周期。

  2. 在某系统中需要统计分析不同维度下的销售数据,比如城市、省份、时间段(天、周、月)、区域等等

  3. 某平台需要给多个业务输出数据,希望不同业务间的数据做隔离,一个业务只能读取本业务范围内的数据。


不知道现在有没有体感了,如果有了,请继续往下看。

解决思路

其实以上问题归根结底,我们需要有一套代码模板来实现代码的复用,我们可以通过参数的控制实现差异化的功能。


开始,笔者想到的是通过 Java 后台来生成这套模板代码,然后在 ODPS 上创建 Python 脚本,通过 Http 请求 Java 后台的服务,以动态脚本的方式离线调度执行。


但很快发现这种方式存在诸多问题:


  • 代码在 JAVA 侧,JAVA 侧拼接 SQL 极易出错,需要经常发布 JAVA 应用来实现某个离线小功能的迭代,并且离线代码侵入后台系统本身也不太合理。

  • SQL 是动态生成的,缺少代码格式化,只能通过运行日志找到实际运行的代码,可读性差。

  • 代码存在两个系统中,较为黑盒,代码测试和 debug 都较为困难。


最后,在翻阅 ODPS 的官方文档后发现,其实这些问题 ODPS 平台上已经具备相应的解决方案了——ODPS 组件。

初识 ODPS 组件

组件的定义

组件是一种带有多个输入参数和输出参数的 SQL 代码过程模板, SQL 代码的处理过程一般是引入一到多个源数据表,通过过滤,连接,聚合等操作,加工出新的业务需要的目标表。

组件的价值

如上,在实际业务实践中,有大量的 SQL 代码过程很类似,过程中输入的表和输出的表的结构是一样的或者是类型兼容的,仅仅是名字不同而已。这个时候组件的开发者就可以将这样的一个 SQL 过程抽象成为一个 SQL 组件节点,将里面可变的输入表抽象成输入参数,把里面可变的输出表抽象成输出参数,就可以实现 SQL 代码的复用。


组件的使用者在使用 SQL 组件节点的时候,只要从组件列表中选择和自己业务处理过程类似的组件,为这些组件配置上自己业务中特定的 输入表和输出表,不用再重复复制代码,就可以直接生成新的组件 SQL 节点 从而极大提高了开发效率,避免了重复开发。


SQL 组件节点生成后的发布,调度的操作方法都和普通的 SQL 节点的操作方式是一样的。

组件的结构

一个组件就像一个函数的定义一样,由输入参数,输出参数和组件代码过程构成。


组件的输入参数

组件的输入参数具有参数名,参数类型,参数描述,参数定义等属性, 参数类型有两种:一个是表类型 table,一种是字符串类型 string。


✎ 表类型的参数


指定组件过程中要引用到的表,在使用组件的时候,组件的使用者可以为该参数填入其特定业务需要的表。


✎ 字符串类型的参数


指定组件过程中需要变化的控制参数,比如指定过程的结果表只输出每个区域的头 N 个城市的销售额,这个 n 是 1 还是 3 就可以通过字符串类型的参数进行控制;另一个例子,要指定过程的结果表输出那个省份的销售总额,可以设置一个省份字符串参数,指定不同的省份,就能获得指定省份的销售数据。

✎ 组件的输出参数

组件的输出参数具有参数名,参数类型,参数描述,参数定义等属性,参数类型只有一种:表类型 table。字符串类型的输出参数没有逻辑意义。

✎ 组件的过程体

在过程体中参数的引用格式为:@@{参数名}


过程体通过编写抽象的 sql 加工过程,将指定的输入表按照输入参数进行控制加工出有业务价值的输出表。


PS:其实作为码农,我们能很好地理解组件的概念,因为即使你没写过 ODPS 代码,不知道 ODPS 的组件,但你一定在你曾经用过的语言里找到类似的概念,例如,前端领域中的 UI 组件,移动 Android 开发中的组件,Java 开发中的各种框架,Jar 包等等都是一些组件。

牛刀小试

作为初识 ODPS 组件的小白,我们先尝试写一个 helloword,实现从一张大表中按业务拆分出多张子表,分别给到各自业务各自的表。

创建组件

过程体开发


PS: 组件过程的开发具有一定的技巧,组件过程的代码需要巧妙的利用输入参数和输出参数,使得组件过程能够在使用的时刻填入不同的输入参数和输出参数也能生成正确的可运行的 sql 代码。

填写输入输出参数

调试 &运行

在做完以上两步后,我们可以直接在组件开发的界面点击运行,输入测试的参数进行调试运行。


发布


组件具有版本号的功能,每次发布,版本号会自增,后面组件使用的地方会用到。

组件引用

在数据开发页面,在文件夹目录先右键选择创建 SQL 组件节点。




使用组件节点与 SQL 节点,大部分开发使用习惯都是一样的,包括调度配置也都一样,唯独不同的是组件节点关联了一个组件,如果需要更新节点,需要先更新组件的代码,然后更新节点的代码版本。


进阶使用

进阶思考

笔者在项目开发过程中,碰到一个问题,项目开始的时候给很多离线节点设置了小时级调度,但随着项目的数据日益增长,离线节点的调度时长很快接近一小时,离线调度很快将达到瓶颈。比较自然地想到的解决方法是,将每小时调度改为每 2 小时调度一次,或者将小时级调度切换成天级调度,但明显不是一种根本的解决方案。


能不能根据数据的重要程度,分配不同的调度优先级呢?想到这,立马有了灵感~


经过分析后,我们系统中存在两种类型的数据,大促数据和日常数据。大促数据由于具有时效性,过期的数据往往会进行清理,因此大促数据随时间不会大幅增长;而日常数据由于具有长期有效,随时间必然会持续的上涨。


另外大促数据时效性要求较高,日常数据变更频率慢时效性低。


通过以上分析,可以看出大促优先级较高,而日常优先级较低。因此我们可以将数据切分为大促数据和日常数据,大促走小时级调度链路,日常走天级调度链路。



通过统计可以看出数据分布大约为日常:大促=10:1

按需调度,省时又省力

下面举一个已优化过后的例子:


  • 优化前,整个节点调度周期平均为:20 分钟

  • 优化后,日常天级调度周期平均为:15 分钟

  • 大促小时级调度周期平均:2 分钟





可以看出,经过改造后,大幅节省了原来小时级调度的计算资源和存储成本。

感想

  1. 遇到一个问题,经过思考后往往有不止一种方案可以去解决它,也许我们最终只会采用其中的一种方案,而被采纳的方案一定是经过仔细地比较优缺点,衡量投入产出成本等多方面评估之后才做的决定。在本文中,笔者也不是一开始就知道可以通过 ODPS 的组件来解决问题,而是经过反复地查资料,咨询 ODPS 平台的同学等方式后才行成通过 ODPS 组件化的方式来解决问题。

  2. 开发中我们会遇到各式各样的问题,但很多问题,很多知识,我们可以做到融汇贯通,举一反三。就像本文的案例中,组件这一概念,其实我们在其他领域中已经接触过,如果我们能做到融会贯通,我们是不是一开始就会联想到在 ODPS 里会不会有组件(或者模板)呢?


参考文献


1、什么是 ODPS


https://www.alibabacloud.com/help/zh/doc-detail/27800.htm?spm=ata.13261165.0.0.664b57baosPRBJ


2、什么是 DataWorks


https://www.alibabacloud.com/help/zh/doc-detail/73015.htm?spm=ata.13261165.0.0.664b57baosPRBJ


3、ODPS 组件


https://www.alibabacloud.com/help/zh/doc-detail/137562.htm?spm=ata.13261165.0.0.664b57baosPRBJ


本文转载自公众号淘系技术(ID:AlibabaMTT)。


原文链接


数据仓库解决方案——ODPS组件化改造之路


2020-09-12 14:002598

评论

发布
暂无评论
发现更多内容

golang中的map

六月的

Go map

遮罩和蒙版有什么区别,视频遮罩怎么用

懒得勤快

数字云栖,邀您共享极致计算与创新进化的科技盛宴

阿里云CloudImagine

阿里云 边缘计算 云栖大会

担时代任务 与国家同频 | 九科信息创始人万正勇:自主可控是中国超级自动化技术发展的必要条件

九科Ninetech

RPA 信创

Mysql数据库基础之数据库的安装与配置

渔戈

MySQL 数据库 10月月更

自主创新、领先一代,星环科技成功登陆科创板

星环科技

大数据 开源

途游游戏 DevOps 实践|都说「单元测试」好,「AAAC四步法」少不了

极狐GitLab

DevOps 运维 单元测试 CI/CD 代码安全

分布式事务-CAP理论

zarmnosaj

10月月更

ERP到底是自研还是外采好????

CTO技术共享

10月月更

一文彻底搞懂前端缓存机制

hellocoder2029

JavaScript

为什么vue3要选用proxy,好处是什么?

hellocoder2029

JavaScript

驾考宝典携手HMS Core统一扫码服务,构建复杂场景中的流畅扫码体验

HarmonyOS SDK

扫码

前端懒加载和预加载

hellocoder2029

JavaScript

“程”风破浪的开发者|OpenHarmony应用开发环境搭建

技能实验室

OpenHarmony “程”风破浪的开发者

常见恶意软件类型及危害

郑州埃文科技

网络安全 恶意软件 办公安全

强烈推荐!腾讯T8架构师手写的SpringBoot分布式架构笔记

小小怪下士

Java 分布式 后端 springboot

Go语言入门03—条件语句

良猿

Go golang 后端 10月月更

Go语言入门04—循环语句

良猿

Go golang 后端 10月月更

生产环境P0级事故,整个项目组被罚

CTO技术共享

uniapp打开地图选择位置

源字节1号

软件开发 前端开发 后端开发 小程序开发

不可错过!14位安全大拿齐聚!AMD、Arm及Intel等技术专家解读系统安全 | 2022云栖大会

OpenAnolis小助手

开源社区 系统安全 云栖大会 龙蜥安全专场 操作系统峰会

企业级开发平台的演进

世开 Coding

软件开发 低代码 快速开发平台 少代码

【10.14-10.21】写作社区优秀技术博文更新啦!

InfoQ写作社区官方

优质创作周报

原来Vue3的computed属性还能这么用啊🔥

渔戈

Vue 前端 10月月更

BH1750 光照传感器文档详解 及 驱动设计

矜辰所致

传感器 stm32 I2C协议 10月月更 BH1750

pt尾递归优化

hellocoder2029

JavaScript

秒杀活动!!!! 如何撑住10W QPS

CTO技术共享

10月月更

node+express操作cookie

木偶

前端 Node Express 10月月更

Paddlenlp之UIE模型实战实体抽取任务【打车数据、快递单】

汀丶人工智能

nlp

鸿蒙开发入门 | 开发第一个鸿蒙应用+页面跳转

TiAmo

华为 鸿蒙开发 10月月更

如何进行企业数字化转型?传统企业数字化转型的3大底层逻辑

优秀

企业数字化转型

数据仓库解决方案——ODPS组件化改造之路_移动_曹丽杰(通草)_InfoQ精选文章