摘要:一个使用过Hadoop的Hive框架的大数据开发工程师,往往基本掌握了阿里云的大数据计算服务MaxCompute的90%。本次分享主要通过详细对比MaxCompute和Hive各个方面的异同及开发使用的注意事项,方便用户来开发使用MaxCompute,实现从Hive秒速迁移到MaxCompute。
演讲嘉宾简介:刘建伟
以下内容根据演讲视频以及PPT整理而成。
本次分享主要围绕以下四个方面:
一、MaxCompute和Hive对比内容介绍
二、MaxCompute介绍
三、MaxCompute和Hive对比
四、MaxCompute注意事项及对比总结
一、MaxCompute和Hive对比内容介绍
本文主要从文件系统、调度系统、客户端、SQL、Web UI、界面化操作、权限等方面对MaxCompute和Hive进行对比。其中SQL对比中将分别介绍建表语句、分区分桶、数据上传下载、外部表、SQL函数、UDF、MapReduce、SQL调优、文件格式等方面的异同。
二、MaxCompute介绍
MaxCompute 主要服务于批量结构化数据的存储和计算,可以提供海量数据仓库的解决方案以及针对大数据的分析建模服务。下图为MaxCompute系统架构。MaxCompute支持SQL查询计算,自定义函数UDF实现复杂逻辑,MapReduce程序实现更具体的业务计算,支持Graph,面向迭代的图计算处理框架,提供Java API连接操作SQLTask,基于DAG的处理、交互式内存计算、机器学习等计算类型及MPI迭代类的算法,简化了企业大数据平台的应用架构。MaxCompute和Hive一样可以使用SQL、UDF以及MapReduce开发。基于MaxCompute的Serverless无服务器的设计思路,用户只需关心作业和数据,而无需关心底层分布式架构及运维。
三、MaxCompute和Hive对比
1. 文件系统对比
MaxCompute和Hive文件系统对比如下图。
飞天(Apsara)是由阿里云自主研发、服务全球的超大规模通用计算操作系统。飞天系统是分布式文件存储和计算系统。对于MaxCompute,可将飞天视为类似于Hadoop的框架,如Hive基于Hadoop,那么可以理解为MaxCompute基于飞天系统。
2. 客户端对比
Hive客户端:用户进入Hive客户端执行show Database命令可以看到所有的数据库以及查询数据库中对应的表。
MaxCompute客户端:
首先下载并安装MaxCompute客户端到本地,可以看到MaxCompute客户端页面如下图所示,这里主要介绍一下MaxCompute的项目空间。
项目空间(Project)是 MaxCompute 的基本组织单元,它类似于传统数据库的Database 或 Schema 的概念,是进行多用户隔离和访问控制的主要边界 。一个用户可以同时拥有多个项目空间的权限。通过安全授权,可以在一个项目空间中访问另一个项目空间中的对象,例如表(Table)、资源(Resource)、函数(Function)、 和实例Instance。MaxCompute除了命令行,客户端还提供Python和Java的SDK进行访问。MaxCompute SDK的入口,可通过此类来获取项目空间下的所有对象集合,包括Projects、Tables、Resources、Functions、Instances。
构造 MaxCompute对象可通过传入Aliyu Account实例来构造MaxCompute对象。程序示例如下图所示。创建一个Aliyu Account实例,首先输入“access_id"、“access_key"信息。 odpsUrl是根据用户自己的region填写的endpoint,然后填写project名称。MaxCompute Tunnel数据通道是基于Tunnel SDK编写的。用户可以通过Tunnel向MaxCompute中上传或者下载数据。
SQLTask:SQLTask是用于运行、处理SQL任务的接口。可以通过运行接口直接运行SQL。
注意:每次只能提交运行一个SQL语句,若为脚本模式可以一次提交多个SQL 。运行接口返回Instance实例,通过Instance获取SQL的运行状态及运行结果。程序示例如下图所示。创建类后输入accessId,accessKey信息。然后创建一个Odps实例对象,同时输入endpoint。关于SQLTask的具体介绍可参考官方文档。
3. Hive SQL与MaxCompute SQL对比
(1)建表语句对比:MaxCompute SQL与Hive SQL建表语句对比如下图所示。Hive SQL建表语句需要定义其分隔符、文件格式等。而MaxCompute建表不需要指定分隔符,指定文件存储路径,指定文件的存储格式。由于MaxCompute是基于阿里云飞天文件系统,用户无需关心文件存储格式,压缩格式,存储路径等,这些操作由阿里云来完成。用户不必疲于文件存储成本、压缩性价比、读写速度等优化,可以将精力集中在业务开发上。
(2)数据上传和下载:Hive数据上传和下载需要通过load命令以及文件路径(load date inpath)。MaxCompute中可通过命令工具Tunnel进行数据上传和下载。
Upload: MaxCompute上传数据,支持文件或目录(指一级目录)的上传,每一次上传只支持数据上传到一张表或表的一个分区。若上传到分区表则必须指定上传的分区,多级分区需要指定到末级分区。示例如下:tunnel upload log.txt为数据文件,test_project为项目空间,.test_table为表名,最后为分区信息。
Download: 从MaxCompute的表中下载数据,只支持下载到单个文件,每一次下载只支持下载一张表或一个分区到一个文件。分区表需要指定下载的分区,多级分区则需要指定到末级分区。
(3)分区分桶: Hive和MaxCompute都支持分区分桶,其中分区用法一致。
分桶操作实际上是将一个大文件根据某个字段hash分为多个小文件,适当的分桶可提升查询效率。分桶使用方法如下表所示。
在Hive中使用分桶命令需要执行命令hive.enforce.bucketiong=true;使用关键字clustered by指定分区依据的列名,以及指定分桶数。在MaxCompute中是底层进行分桶操作。在MaxCompute中可以在建表时指定clustered by中的Hash Key,MaxCompute将对指定列进行Hash运算,根据Hash值分散到各个Bucket中。为避免数据倾斜和热点,取得较好的并行执行效果,clustered by字段列宜选择取值范围大、重复键值少的列。为达到join优化目的,应考虑选取常用的Join/Aggregation Key,即类似传统数据库中的主键。
(4)外部表(External Table):Hive可以通过外部表的功能进行操作,例如Hbase、ES的数据。
MaxCompute2.0支持外部表功能。MaxCompute通过外部表来映射阿里云的OTS和OSS两个数据存储产品来处理非结构化的数据,例如音频、视频数据等。在外部表操作过程中需要注意外部表的建表语句以及权限问题。MaxCompute非结构化数据框架通过External Table与各种数据的关联,关联OSS上开源格式数据的External Table的建表的DDL语句格式如下所示。包括列信息、分区信息、文件格式、arn信息等。
DROP TABLE [IF EXISTS] <external_table>;
CREATE EXTERNAL TABLE [IF NOT EXISTS] <external_table>
(<column schemas>)
[PARTITIONED BY (partition column schemas)]
[ROW FORMAT SERDE '<serde class>'
[WITH SERDEPROPERTIES ('odps.properties.rolearn'='${roleran}' [,'name2'='value2',...])]
]
STORED AS <file format>
LOCATION 'oss://${endpoint}/${bucket}/${userfilePath}/';
该语法格式与Hive创建表的语法格式接近,但需注意以下问题:
1)column schemas:外部表的column schemas必须与具体OSS上存储的数据的schema相符合,否则会报错。
2)ROW FORMAT SERDE:非必选选项,只有在使用一些特殊的格式(例如TEXTFILE)时才需要使用。
3)WITH SERDEPROPERTIES:当关联OSS权限使用STS模式授权时,需要该参数指定odps.properties.rolearn属性,属性值为RAM中具体使用的Role的Arn信息。用户可以在配置STORED AS 的同时通过说明file format文件格式。
4)如果不使用STS模式授权,则需指定odps.properties.rolearn属性,或直接在Location传入明文AccessKeyId和AccessKeySecret信息(因信息有保密性不建议使用)。并且子账号AccessKeyId和AccessKeySecret信息需要自行保存,因为AccessKeyId和AccessKeySecret信息只提供一次,不支持后续查询,一旦丢失需要重新绑定。
OSS外部表授权方式:
一键授权:当MaxCompute和OSS的Owner是同一个账号时,可登录阿里云账号后单击一键授权,将跳转到下图所示界面,单击同意授权。在访问控制更改子账号添加管理对象存储服务(OSS)权限(AliyunOSSFullAccess)。
自定义授权:
- 新增一个RAM角色。如下图所示,在RAM访问控制台点击“新建RAM角色"。
- 修改角色策略内容设置。下图所示案例为给创建的RAM角色oss-admin添加的信任策略内容
当MaxCompute和OSS的Owner是同一账号时,在Service中只需写"odps.aliyuncs.com",不是同一账号时,需要在Service中填写"MaxCompute的Owner云账号id@odps.aliyuncs.com"。
--当MaxCompute和OSS的Owner是同一个账号,设置如下。
{
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": [
"odps.aliyuncs.com"
]
}
}
],
"Version": "1"
}
--当MaxCompute和OSS的Owner不是同一个账号,设置如下。
{
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": [
"MaxCompute的Owner云账号id@odps.aliyuncs.com"
]
}
}
],
"Version": "1"
}
- 授予角色访问OSS必要的权限AliyunODPSRolePolicy。如下图所示,可以看见权限中有ListBuckets、GetObject、ListObjects等具体信息,用户可以根据需要自定义权限。
- 将权限AliyunODPSRolePolicy授权给该角色。如下图所示,在角色后面点击添加权限,则被授权主体就是之前被授权的子账号主体。在左侧选择权限策略,点击确定即可。
(5)自定义函数: Hive与MaxCompute均支持自定义函数UDF、UDTF、UDAF。MaxCompute 2.0版本升级后,Java UDF支持的数据类型从原来的BIGINT、STRING、DOUBLE、BOOLEAN扩展了更多基本的数据类型,同时还扩展支持了ARRAY、MAP、STRUCT以及Writable等复杂类型。使用复杂数据类型的方法,STRUCT对应com.aliyun.odps.data.Struct。com.aliyun.odps.data.Struct从反射看不出Field Name和Field Type,所以需要用@Resolve注解进行辅助。即如果需要在UDF中使用STRUCT等数据类型,要求在UDF Class上也标注@Resolve注解。但是当STRUCT类型中的field有很多字段时,需要手动添加@Resolve注解。针对此问题,可以使用Hive 中的GenericUDF去实现。MaxCompute 2.0支持Hive风格的UDF,部分Hive UDF、UDTF可以直接在MaxCompute上使用。
(6)MapReduce开发:MapReduce是一个基于集群的计算平台,是一个简化分布式编程的计算框架,是一个将分布式计算抽象为Map和Reduce两个阶段的编程模型。MaxCompute提供三个版本的MapReduce编程接口:MaxCompute MapReduce、MapReduce(MR2)、Hadoop兼容版本MapReduce。MaxCompute MapReduce是MaxCompute的原生接口,执行速度更快、开发更便捷、不暴露文件系统。MR2是对MaxCompute MapReduce的扩展,支持更复杂的作业调度逻辑,MapReduce的实现方式与MaxCompute原生接口一致。 Hadoop兼容版本MapReduce特点是高度兼容Hadoop MapReduce ,与MaxCompute MapReduce MR2不兼容。
(7)SQL调优:MaxCompute和Hive基本SQL优化相似,例如常见的Key分布不均匀、数据倾斜、join长尾、窗口函数优化等。
4. Web UI对比
Hive任务依赖于Hadoop的HDFS和YARN提供的WebUI进行访问。MaxCompute使用Logview查看Job 信息。通过Logview可看到一个Job 的任务运行状态、任务的运行结束、任务细节及每个步骤的进度等任务执行状况。Job 提交到MaxCompute后将生成Logview的链接。可直接在浏览器打开Logview链接查看Job 信息。Logview首页分成上下两部分,Instance信息和Task信息。
Instance信息:用户提交的SQL任务对应的MaxCompute Instance信息,包含URL链接、项目、InstanceID、提交人、开始时间、结束时间和状态(Status)等。Instance信息部分可以单击Status查看当前队列的Status详细信息,包含四种状态,Waiting表示当前作业正在MaxCompute中处理,并没有提交到分布式调度系统(Fuxi)中运行。Waiting List : n表示作业已提交至分布式调度系统(Fuxi)排队等待运行,当前在队列中处于第n位。Running则说明作业在分布式调度系统(Fuxi)中运行。以及成功状态。
Task 信息:该Instance对应的Task信息,包括任务名称、类型、状态、运行结果(Result)、详细信息(Detail)、开始时间、结束时间、总运行时间(Latency)、进度。其中,Latency指运行总共消耗的时间,与其它页面的Latency含义类似。Result是在Job运行结束后,可以看到运行结果。Detail是一个Job在运行中和结束后,均可以单击Detail来查看任务运行的具体情况。
案例:下面介绍一个Logview信息案例。
点击上图SQL,可以看到具体执行任务的LogView语句信息页面如下:
目录中Status是上述所介绍的四种状态信息。通过SubStatus History可以看到任务运行过程中的详细信息,包括任务等待、准备、执行、结束等详细执行过程信息。
下方一行为Task信息:
点击Result可以查看运行结果;
点击Detail可以看到任务运行过程中的详细信息。
上图左侧Fuxi Job DAG会根据任务指定详细执行计划,生成一个DAG(有向无环)图。右侧上方Fuxi Jobs为具体状态信息。右侧下方为Instance信息,通过Instance信息可以看到整个任务的执行状况,包括失败数、运行数、长尾信息等,可便于对SQL进行相应优化。 Summary是Job运行结束后才可以查看的信息,主要包括Job消耗的CPU、内存、Job输入的表名、记录数和字节数。通过Summary也可以分析Job是否有长尾,并进行相应优化。因此Logview是MaxCompute开发过程中排查、发现问题的重要工具。
5. 界面化操作对比
Hive可以借助hue工具来操作查询数据,但其交互性不是很强。MaxCompute中阿里云的产品基本上都是界面化操作,可拖拽,开发门槛非常低。因此非常适合初学大数据或者没有相关开发人力的公司。MaxCompute的界面化操作可以结合Dataworks做数据同步、权限控制、数据管理和其他数据源交互、定时调度等。
6. 权限对比
Hive中权限操作支持ACL授权。MaxCompute支持ACL授权以及Policy权限授权。
Policy权限授权: 在RAM访问控制页面权限策略管理中,点击新建自定义权限,选择脚本模式,就可以编写Policy权限。如下图所示为具体权限内容。用户在开发过程中,可以使用ACL权限或Policy权限授权。创建Policy权限策略后,创建一个RAM角色,为角色制定策略,就会拥有一个相应权限以进行开发。
四、MaxCompute注意事项
1. Java沙箱限制
MaxCompute MapReduce及UDF程序在分布式环境中运行时,受到Java沙箱的限制(MapReduce作业的主程序,例如MR Main则不受此限制),具体限制如下所示。
1)不允许直接访问本地文件,只能通过MaxCompute MapReduce/Graph提供的接口间接访问。读取resources选项指定的资源,包括文件、Jar包和资源表等。通过System.out和System.err输出日志信息,可以通过MaxCompute客户端的Log命令查看日志信息。
2)不允许直接访问分布式文件系统,只能通过MaxCompute MapReduce/Graph访问到表的记录。3)不允许JNI调用限制。
4)不允许创建Java线程,不允许启动子进程执行Linux命令。
5)Java反射限制:suppressAccessChecks权限被禁止,无法setAccessible某个private的属性或方法,以达到读取private属性或调用private方法的目的。
2. SQL使用限制
如下图所示:具体参考官方文档介绍。
3. MaxCompute数据操作
MaxCompute不支持直接对表数据进行删除(Delete)和更新(Update)语法操作。
更新(Update)数据:只能将源分区或表数据导入到新分区或表(新分区或表可以与源分区或表相同),在导入过程中执行相应的更新逻辑。对于非分区列,只支持重命名和新建列,不支持对列的删除。MaxCompute不支持Update语句,建议把更新后的结果筛选出来,然后用Insert Overwrite的方法写回原表。
删除(Delete)数据:可以通过删除(Drop)表达到数据删除目的。非分区表可以通过TRUNCATE TABLE table_nam;语句清空表数据。分区表可以通过ALTER TABLE table_name DROP IF EXISTS PARTITION(分区名=‘具体分区值’)删除分区达到删除整个分区数据的目的。通过INSERT和WHERE条件把需要的数据导入到另一张新分区或表中或就地更新,INSERT语句支持源表和目的表是同一张表。
4. MaxCompute单字段限制8MB
处理思路:目前由于存储机制限制,MaxCompute表中单个字段(多为String字段)的最大长度不能超过8MB。对于超过8MB的超大字段,建议拆分成多个字段。具体的拆分逻辑可以根据业务特性设计,保证每个字段不超过8MB即可。
常用方法:由于复杂结构的超大字段在数据开发和分析中会严重影响计算性能,因此建议用户根据数仓建设规范来设计数据架构,避免超大字段。具有复杂结构的原始数据,作为ODS层,最好以压缩的方式归档。定时(例如每天)对ODS层的增量数据做数据清洗,复杂字段拆分为多个简单字段,然后存储在CDM层的表中,便于数据的统计分析。
5. 设置兼容Flag
默认模式是MaxCompute模式,如果要切换至Hive模式,需要开启odps.sql.hive.compatible为True。odps.sql.hive.compatible表示是否打开Hive兼容模式,其值默认为False。可通过以下两种方法开启Hive兼容模式。开启后才可以支持Hive指定的各种用法,例如inputRecordReader、outputRecordReader、Serde等。Hive兼容后用户创建外部表或开发MaxCompute SQL过程中可以从Hive平滑迁移到MaxCompute中。
--Project级别切换为Hive模式:setproject odps.sql.hive.compatible=True;
--Session级别切换为Hive模式:set odps.sql.hive.compatible=True。odps.sql.hive.compatible表示是否打开Hive兼容模式,其值默认为False(禁止)。每执行一个Session都需要写这句话。
最后做一个MaxCompute与Hive异同总结
欢迎加入“MaxCompute开发者社区2群”,点击链接MaxCompute开发者社区2群申请加入或扫描二维码