阿里云云原生数据湖分析DLA是阿里云在数据湖领域推出的拳头产品,帮忙用户进行数据湖的构建、对数据湖的进行分析、在统一的元数据基础之上支持双引擎: Presto和Spark,一站式满足用户各种数据分析的需求。DLA基于云原生的理念进行构建、用户不需要感知任何物理机、ECS、手动部署等等,直接使用服务,而且是完全Serverless形态,支持灵活的弹性策略,提供多种计费模型,满足各种不同场景的用户使用需求。
在刚刚闭幕的PrestoCon 2020上,阿里云的云原生数据湖分析(DLA)作为Linux Foundation的一员在大会上了分享了DLA在提供托管Presto服务过程中碰到的一些挑战以及我们的解法,这里跟大家分享探讨一下。
Why Presto
首先给大家介绍一下为什么我们会选择Presto作为我们数据湖分析的引擎。
首先Presto采用的是全内存计算模型,性能非常的好,特别适合进行adhoc查询、数据探索、BI报表、轻量ETL等等各种业务场景;其次不像其它一些引擎只支持部分SQL语义,Presto支持完整的SQL语义,你不用担心有什么需求是Presto表达不出来的;再者Presto有个很方便的插件机制,你可以在不改动内核的情况下添加自己的插件,这样理论上你可以用Presto去连接任何数据源,满足你的各种业务场景;最后Presto有个非常棒的社区,现在Presto已经归属到Linux Foundation下面,Alibaba也是这个基金会的成员之一,国际国内大公司比如Facebook,Twitter,Amazon Athena,阿里巴巴,京东,头条等等都在使用Presto进行大数据的分析。基于上述优势,阿里云数据湖分析采用了Presto作为底层的分析引擎。
DLA SQL(兼容Presto)的技术架构
DLA SQL的技术架构分三块:FrontNode,Presto Clusters以及Unified Meta Service。
FrontNode是整个架构的接入层,它实现了MySQL协议,这样用户可以用任何兼容MySQL协议的客户端/BI工具/调度工具连接上来继续数据分析、报表制作。FrontNode会把用户提交的MySQL风格的SQL转换成Presto风格的SQL,并且发送给底层正确的Presto集群。
FrontNode之下,是我们的Presto集群,在每个Region,我们会有两类集群,一个是扫描量集群,对用户收费是按照用户SQL实际从底层数据源扫描的数据量进行收费的,这个集群是公用的,用户之间会通过我们的多租户隔离技术进行元数据和算力的隔离,关于隔离技术的细节后文会详细介绍。另外一类集群是CU集群,CU集群是根据指定的CPU Core的个数单独拉起的集群,它适合于使用频繁的客户,因为它不是按照扫描量计费,而是按照CPU Core个数计费的。这两种集群的收费差异可以看下图:
关于这两种收费模式更详细的差异对比可以查看我们的文档: 扫描量版与CU版本的差异
在整个架构的左边是我们的统一元数据中心,这个模块是DLA跟社区差异很大的一个地方,在社区的实现里面,所有的Connector连接底层实际的数据源去获取元数据,当用户需要添加新的数据源的时候需要添加新的Catalog文件,并且重启集群才能实现,通过把元数据收到统一服务里面,用户添加新的数据源对于DLA来说只是一个DDL操作,不需要重启集群,并且由于元数据统一在一个地方,使得我们可以很方便地实现权限管控,我们提供了MySQL风格的GRANT/REVOKE机制,这是开源Presto所没有的便利。
托管Presto云服务的三大挑战
托管Presto作为一个云服务有很多挑战,今天我们主要介绍以下三个:
- Coordinator单点问题
- 计算资源的多租户隔离
- Connector优化
Coordinator单点问题
Coordinator单点会有很多问题,一旦Coordinator挂掉整个集群就会不可用很长时间,要等待Coordinator重启,并且注册所有的Worker,这个时间在几分钟级别;另外如果只有一个Coordinator,我们是没有办法做无缝升级的,这些对于一个企业级服务都是不可接受的。我们采用如下架构解决了这个问题:
我们引入了Zookeeper在多个Coordinator之间选主,其中一个Coordinator会变成Leader,其它则是Follower。Leader Coordinator跟社区的Coordinator职责类似,它负责启动DiscoveryService,负责一些全局信息的收集以及决策工作,同时也会之下分配给它的Query。Follower则比较简单了,只负责执行分配给它的Query。
如果使用开源的Presto的话,有多个Coordinator之后会产生一个问题:用户应该连接哪个Coordinator呢?在DLA的架构里面这不是一个问题,因为DLA的用户不会直接连到Coordinator,只会连接FrontNode,FrontNode负责查询的分发,因此用户完全不感知我们有几个Coordinator。
实现了多个Coordinator之后,要实现无缝升级就比较简单了,如果大家有兴趣我们后续文章可以专门介绍一下。
计算资源的多租户隔离
Presto原生设计是在一个公司内部使用的,对于计算资源多租户隔离考虑的不多,虽然有Resource Group的机制来限定一个Group的计算资源和内存,但是Group对于计算资源的使用是可以超过指定的上限的,Presto做的“限制”是如果有新的查询,那么新的查询不会被调度,但是老的查询还是会继续占用大量资源,这样就会影响一个集群上的其它租户的使用。
DLA对计算资源隔离这块进行了优化,把多租户的概念引入了进去:
首先与社区Presto所有Split在一个全局队列不同,在DLA的版本里面,每个租户有自己的队列,这样做到第一层的隔离。然后我们在全局引入了一个Resource Manager的角色,它会从所有的Coordinator聚合所有租户对于资源的使用情况,然后根据我们设定的阈值去计算每个租户在下个调度周期是否应该被惩罚,然后把这个惩罚信息发送给所有的Worker。在Worker上,任务调度器在进行实际调度一个租户的Split之前,会先检查这个租户是否被惩罚了,如果被惩罚了,那么它的所有的Split都不会被调度,这样就把计算资源保留给其它的租户使用。
我们用下面的测试配置进行了测试:
- 4台Worker,每台配置是4C8G;使用TPCH20G的数据;选用第TPCH第20条SQL进行实验,因为它JOIN了好几个表,需要使用大量CPU。
- 实验场景: 4个租户,A、B、C各提交一条SQL,D提交5条SQL。
测试效果如下:
可以看到在社区版本里面,租户D因为提交了更多了SQL,所以它有更多的Split在运行,挤压了其它租户;在DLA版本里面,所有租户运行中的Split个数是差不多的。
下面看看8条查询的运行耗时:
可以看到在开源版本里面,所有8条查询耗时几乎一样;而在DLA的版本里面租户A、B、C的查询耗时较短,因为租户D使用过多资源被惩罚了,所以它的5条查询耗时较长。
连接器优化
OSS是阿里云上的对象存储服务,DLA采用OSS作为数据湖的存储层。我们支持对OSS数据进行INSERT INTO/OVERWRITE以及查询,同时我们对OSS的请求进行了优化,可以把对于OSS API的调用次数降低到开源版本的1/10到1/3。
TableStore是阿里云上广泛使用的KV存储服务,在DLA的帮助下让用户可以使用SQL语句来分析KV存储中的数据,而且如果用户有建立索引的话,DLA会自动采用合适的索引以达到更好的性能。
AnalyticDB是阿里云提供的云原生数据仓库服务,DLA支持用户读写AnalyticDB的数据,可以帮助用户在把数据灌入AnalyticDB之前做一些预先清洗的工作。
对于MaxCompute我们支持读写,并且支持读取MaxCompute的OSS外表的数据。
此外我们支持开源Presto支持的所有的Connector,同时我们也做了一些的优化,比如对于JDBC类数据源,我们支持自动探测底层表结构,然后根据索引列进行Split切分,这样可以提高JDBC类数据源的查询效率。
总结
Presto作为一款优秀的OLAP计算引擎非常适合用来做各种数据分析的工作,不管你是自建的还是采用云上的服务。阿里云数据湖分析在开源社区版本之上提供了多种计费模式以及弹性伸缩的能力,从而可以实现比用户自建更高的性价比;我们支持阿里云上主流的数据源,并且进行深度优化,让用户可以把更多的时间专注下数据分析上;我们提供了更多的稳定性(多Coordinator)与易用性(MySQL协议支持)让各个不同人群可以轻松上手。总之DLA SQL(兼容Presto)的目标是比自建有更高的性价比、按需弹性的算力、开箱即用的体验、方便的数据摄入、MySQL生态带来的简单易用、内置各种优化的Presto分析服务。
为了方便中国的Presto用户交流,我们创建了专门的钉钉群,欢迎加入沟通: