数据湖可以很好地帮助企业应对当前数据场景越来越多、数据结构越来越复杂、数据处理需求越来越多样化的问题。阿里云从2018年起就开始布局数据湖,推出了云原生数据湖分析Data Lake Analytics(DLA),从数据湖管理(帮助客户高效管理构建数据湖),Serverless Spark(提供高性价比的大规模计算),Serverless SQL(提供高性价比的在线交互式分析)三个方面帮助客户挖掘数据价值。本文分享相关技术挑战及解决方案。
一 数据湖的机遇与挑战
数据湖可以很好地帮助企业应对当前数据场景越来越多、数据结构越来越复杂、数据处理的需求越来越多样化的问题。Gartner 2020年发布的报告显示目前已经有39%的用户在使用数据湖,34%的用户考虑在1年内使用数据湖。
从2018年起,阿里云就开始布局数据湖,推出了云原生数据湖分析Data Lake Analytics(简称:DLA)产品,结合对象存储OSS一起,从弹性扩展、按需付费、服务化等方面打造有竞争力的产品。通过采用存储计算分离模式,存储和计算完全按需付费,用户只需要为实际产生价值的计算买单;DLA深度定制云原生弹性能力,实现作业级弹性,一分钟可弹300个节点。云原生数据湖分析DLA从成本、弹性、交付能力方面相对传统数据分析方案,获得了较大的提升。
在云上也已经有数千家企业使用数据湖服务满足数据应用,如友盟+ 的U-DOP数据开放平台根据友盟+多年沉淀的大数据领域经验,形成了以APP、WEB、小程序、广告营销、社会化分享和推送为基础的多端主题数据的采集和处理能力,为客户形成规范化的多端数据资产。尤其是利用了数据湖的弹性能力,应对了双十一峰值期间DAU暴涨的业务变化,例如,通过实施分析搜索关键词的变化,改变首页广告推荐信息,对活跃用户和下单用户分不同渠道的分析梳理,及时调整优惠策略,以吸引更多的客户新购及复购等。
数据库与大数据一体化趋势在加强,传统的数据库使用者与DBA,也可以使用及维护大数据系统,一体化解决大数据的问题。具体在DLA体现在数据库的数据无缝与大数据结合,比如DLA提供的一键入湖建仓的功能;DLA Serverless SQL兼容MySQL协议及部分语法。
DLA Serverless产品形态,开发者只需要使用平台接口即可,如使用DLA SQL的JDBC接口提交SQL,使用DLA Spark的OpenAPI提交Spark作业。开发者只需要关注业务逻辑本身,不需要关心平台的复杂逻辑。原来使用开源组件遇到的很多痛点都可以迎刃而解:
入门门槛高
Hadoop生态往往需要多个组件同时使用,比如Yarn、HDFS、Spark、Hive、Kerberos、Zookeeper等等。开发者需要了解所有组件,因为开发过程中这些组件往往都会接触到。
开发维护困难
开发者在开发过程中会遇到各个组件带来的使用问题,开发者需要了解所有这些组件以应对这些问题。这些加重了开发者的使用负担。
稳定性难以保障
开源组件本身都必须经过细致的调参并加上合适的硬件资源配置,才能良好运行,并且需要修复不少BUG,出现问题没有兜底。
缺乏适应云的性能优化
云上的OSS、PolarDB等组件都是云原生的组件,开源组件对这部分的改造适应不足,没有充分挖掘出更高的性能。
DLA从数据湖管理(帮助客户高效管理构建数据湖),Serverless Spark(提供高性价比的大规模计算),Serverless SQL(提供高性价比的在线交互式分析)三个方面帮助客户挖掘数据价值。整体架构如下所示。接下来,本文将从这三个方面,分别讲述相关技术挑战以及解决方案。
二 如何管理与构建数据湖?
数据湖中数据难以管理主要体现在两个方面:
已经在数据湖存储OSS上面的数据如何高效的构建元数据。
非OSS数据如何高效的入湖建仓。
数据湖管理相关的主要功能包括元数据管理、元数据发现、数据库入湖建仓、实时数据入湖。接下来重点介绍“海量文件元数据自动构建技术”和“入湖建仓数据管理技术”两个关键技术。
1 海量文件元数据自动构建技术
当以OSS作为数据湖存储,存储的数据文件具有以下几个特性:
- 格式丰富:包括CSV、Text、JSON、Parquet、Orc、Avro、hudi、Delta Lake等格式,其中CSV、Text又包含多种自定义的分隔符等。
- 文件数在百万级别:OSS的扩展性及性价比较好,用户存储在OSS的文件会是百万级别。
- 文件动态上传:存储在OSS上面数据文件具有动态持续上传的特性,新的文件如何快速增量修改元数据。
为了高效的为OSS上面的海量数据构建元数据,阿里云DLA提出并实现了“海量文件元数据自动构建技术”。具体技术如下图所示,核心解决了:万表万分区识别、增量感知更新元数据两个问题。
万表万分区识别
用户OSS上面的文件数量会到百万级别,这些文件不仅格式不同,比如JSON、CSV、Text等,而且同一种格式由于业务属性不同具体的Schema字段也不一样。该技术通过文件Schema识别器搭配文件分类器支持自动生成万表万分区。其中文件Schema识别器比如针对JSON单文件识别到0.15s、CSV单文件识别0.2s,搭配可插拔的智能采样策略及分布式策略,百万文件的Schema识别可以到分钟级别。文件分类器通过树的结构进行聚合、剪枝、压缩,百万级别文件的分类识别需要290ms左右。
增量感知更新
户会往OSS上面持续不断的上传文件,元数据自动构建既要把属于已经创建表的文件Schema变化更新到已有的表,同时对独立新增的文件创建新的表。这里一方面“文件Schema识别器”通过获取OSS上面文件的增加、删除变化对变化的文件进行识别,同时“文件分类器”对新增的文件Schema和已经创建的表进行对别生成变化策略,目前支持增加分区、增加字段、字段不更改、不感知文件删除4种策略,后续可以持续添加新的策略。
2 入湖建仓数据组织技术
把DataBase及消息日志服务的数据统一存储到数据湖存储OSS进行管理,能够满足计算加速、构建数仓归档、冷热分离等业务需求。DLA的入湖建仓数据组织技术包括三种数据组织管理模式:镜像模式、分区模式、增量模式,三种模式能够搭配友好支持这些业务场景。
镜像模式
每次全量同步源库一个Database下面所有表的数据到数据湖存储OSS之上,同步期间可以做到源库负载增加控制在10%以内。这里主要使用了全局统一数据分片调度算法。保持数据湖的数据和源库一致。
分区模式
面对归档场景支持按天全量及增量同步源库数据到数据湖,并以时间分区的方式进行组织,方便归档管理。这种模式能够做到小时级别的时间延迟。
增量模式
这种模式通过行列混存技术、commitlog及index管理技术,可以做到T+10min的数据入湖。其中通过delta的增量文件及异步compaction技术解决了小文件问题;通过delta增量文件及索引技术可以支持Database场景更新、删除日志的增量实时写入;通过commitlog的方式记录分区文件的映射,解决百万分区在传统Catalog管理模式性能慢的问题。
三 云原生数据湖平台需打通云基础设施
DLA整体是一个多租户的架构,分Region部署,每个Region的用户共享一套控制逻辑。虚拟集群VC是逻辑的隔离单元。平台支持 Serverless Spark、Serverless SQL等引擎,打造云原生服务。
如上图所示,平台主要面临的挑战有:资源高效供给、安全防护、访问数据源的带宽保障。
1 资源高效供给
云原生平台基于阿里云的底座ECS&ACK&ECI,与阿里云IAAS资源大池打通,本Region跨可用区资源调度,保障资源的供给。支持1分钟弹300个节点,单客户在大Region 5w计算节点资源的保障。
2 安全防护
用户可以写任意的代码平台内运行,可能是故意恶性的攻击行为,如果没有任何保护,则平台面临安全危险。在安全方面,我们通过如下技术保障安全性:
- 一次密钥:每个Job任务都会去TokenServer申请临时的Token,Job失效Token会过期,如果存在攻击行为,则平台会直接让Token过期,则访问Meta等服务会被拒绝。
- 预防DDOS&注入攻击:所有的访问平台服务的请求,都会对接到安全防护中心,安全防护中心检测有任何攻击或者注入行为,直接关闭网络端口。
- 计算容器隔离:计算节点间采用阿里云自研的安全容器,容器本身可以实现VM相同的安全隔离级别。
- 安全白名单:用户互相之间的网络是完全隔离的。
- ENI虚拟网卡:打通VPC需要配置自己账号下的安全组和虚拟交换机(VSwitch),配置之后结算节点容器会分配用户VPC对应VSwitch网段的的IP,并挂载用户的安全组。
3 高吞吐网络带宽
访问OSS服务是通过高吞吐的带宽服务。
使用ENI技术访问自持VPC,跟在自持VPC内ECS上部署计算引擎访问自持VPC内数据一样,带宽同样是VPC内网带宽。
四 Serverless Spark服务的技术挑战
Apache Spark是目前社区最为流行的开源引擎,不但具备流、SQL、机器学习以及图等计算能力,也可以连接丰富的数据源。但是,面对数据湖场景,传统集群版Spark方案,除了面临前面提到的数据管理困难、运维成本、计算资源弹性能力不足、企业级能力弱等问题外,还面临访问OSS的性能不佳、复杂作业难以调试等问题。
借助于第二章节提到的数据湖管理机制,可以很好地解决数据管理难题。借助于第三章节提到的多租户安全平台,DLA Spark实现了全新的云原生Serverless产品形态,很好地解决了弹性问题、运维成本问题以及企业级需求问题。本章节对Spark访问OSS的性能优化以多租户UI服务做进一步展开。
1 Spark访问OSS优化
社区版本的问题
开源版Spark访问OSS数据默认采用Hadoop FileFormat接口直接对接OSSFileSystem实现。该方法在实践中发现存在性能差,一致性难以保证等问题。
(1)Spark访问OSS性能差
核心原因在于OSS KV模型跟HDFS文件树模型的差异。FileFormat算法最初设计是基于HDFS文件系统,然而对象存储如OSS,为了解决扩展性,本质上采用的是KV模型。KV模型相对于HDFS文件系统差异较大,比如RenameDirectory接口,在HDFS中只是指针操作,但在KV中,需要将所有子文件和目录的KV执行Rename,性能开销很大,并且保证不了原子性。Hadoop FileOutputFormat在写入数据的时候先写到临时目录,最后写入最终目录,临时目录到最终目录的过程中需要做文件树合并,合并过程中有大量Rename操作。
(2)一致性难保证
FileFormat v1算法中,合并文件树操作全部在AppMaster单点执行,效率非常低,尤其是动态分区场景。为了解决AppMaster单点,社区提供了算法2,其核心思路是将合并过程并行到Task中执行,在性能上会有一定的提高,但是,如果Job执行失败,部分成功的Task会将数据写入最终数据目录,导致脏数据问题。
Spark OSS访问优化
(1)基于MultipartUpload的FileOutputFormat实现
针对Spark访问OSS的特点,我们全新实现了Hadoop FileOutputFormat接口,如上图所示。算法的改进重点在优化合并操作,合并的核心是解决文件何时可见的问题。OSS提供MultipartUpload接口,也就是断点续传功能,文件可以分片上传,上传没有结束,分片文件是不可见的。借助该特性,我们可以让Task直接将数据写入到最终目录,只有作业成功才让文件最终可见,该方法不用先写入临时目录,也就大大减少了元数据的操作。对于执行失败的Task写入的临时分片,我们在作业结束时,执行Abort操作,就可以将其删除,这也就降低了空间占用。
针对Spark典型ETL Benchmark Terasort,在1TB输入数据量的情况下,DLA FileOutputFormat执行时间缩短62%,性能提升163%。而针对动态分区场景,社区算法1运行失败,算法2可以执行成功,DLA FileOutputFormat算法相比算法2性能还要进一步提升124%。
(2)OSS元数据Cache
Spark读取OSS的过程中,在ResolveRelation阶段,Spark会遍历OSS的目录,解析表结构和分区结构,以及解析Schema,该过程中同样会有大量元数据操作,并且同一个OSS 对象的元数据会被访问多次。针对该问题,我们实现了对OSS元数据的缓存,第一次访问到的OSS对象元数据就会被缓存到本地,后续如果访问该对象直接读取本地缓存。这种方式可以最大限度降低对OSS元数据的访问。Cache机制可以让ResolveRelation有1倍左右的性能提升,针对典型的Spark查询场景,该机制整体可以提升60%的性能。
2 多租户UI服务
UI服务对于开发者来说至关重要,开发人员依赖UI服务进行作业调试,以及生产作业的问题排查。好的UI服务可以很好地加速研发效率。
HistoryServer的痛点
Spark社区提供HistoryServer提供对Spark历史作业的UI和日志服务,在实际应用中遇到诸多痛点,典型如下:
(1)Eventlog空间开销大
HistoryServer依赖Spark引擎将运行中的Event信息全部记录到FileSystem中,然后后台回放并绘出UI页面。对于复杂作业和长作业Eventlog量较大,可以达到百GB甚至TB级别。
(2)复杂作业和长作业不支持
复杂作业或者长作业的Eventlog很大,HistoryServer会解析失败,甚至OOM。再加上空间开销大的原因,用户一般都只能关闭Eventlog。
(3)Replay效率差,延迟高
HistoryServer采用后台Replay Eventlog的方式还原Spark UI,相当于把Spark引擎的事件全部重放一遍,开销大,会有延迟。特别是作业较多或者较复杂的情况下,延迟可达分钟甚至十分钟级别。
DLA多租户SparkUI
SparkUI服务是DLA平台自研的多租户UI服务,针对社区方案做了深度优化:
(1)去Eventlog
DLA Spark去掉了Eventlog依赖,在作业结束的时候,Spark Driver只是dump UI的Meta到OSS,保存作业结束前的页面元信息。这部分信息只是相对于Eventlog来说,会大大减少,即使非常复杂的作业也只有MB级别。UiServer读取OSS上的UI Meta,将其反序列化出来即可展示SparkUI页面。
(2)UIServer水平扩展
UIServer主要负责解析历史UI Meta和提供Stderr和Stdout日志服务,是轻量化,无状态的,可以实现水平扩展,进而支持万级别客户同时在线服务。UIServer URL采用加密token作为参数,token代表的用户身份,作业id,UIServer据此实现多租户服务化。
(3)本地日志自动滚动
对于长作业而言,Stderr或者Stdout信息会随着时间增加累积,最终甚至可能打爆磁盘。DLA Spark安全容器内置后台进程,实现日志滚动,保存最有价值的最近一段时间的日志。
五 Serverless SQL服务的技术挑战
DLA Serverless SQL是基于目前托管于Linux基金会之下的PrestoDB打造的云原生数据湖引擎,Alibaba同时也是Presto基金会成员之一,一直在贡献优化Presto。PrestoDB引擎本身具有优秀的特性:
- 全内存计算带来的极致速度。
- 支持完整SQL语义带来的强大表达力。
- 易用的插件机制使得我们可以对任何数据源进行关联查询。
- 强大的社区使得我们使用之后没有后顾之忧。
不过社区PrestoDB是单租户的一个引擎,它假定你是在一个公司内部使用,因此算力隔离、高可用等等方面没有过多投入,这使得要直接使用它来作为云原生服务的引擎存在几个问题:
- 一个用户如果提交大量大查询将可能占用集群所有资源,导致其它用户无法使用。
- 单Coordinator使得整个服务的可用性无法得到保证。
我们做了一系列的优化、改造使得它可以云原生的形态服务所有的用户,今天着重介绍多租户隔离技术以及多Coordinator两个主要的特性。
首先我们看一下DLA Serverless SQL的整体架构:
我们在核心的PrestoDB集群周边建设了诸如接入层、统一元数据等等服务来使得用户可以用得稳定、用得便利,下面我们将在多租户隔离技术和多Coordinator技术的介绍中详细剖析。
1 多租户隔离技术
PrestoDB原生是有资源组的支持,它可以支持在不同资源组间做一定程度的CPU、内存的限制,但是它有一些问题使得我们无法基于它来实现计算力的隔离:
- 全局调度层面:即使一个租户使用了过多的计算力资源也不会及时被惩罚,只有新查询会被Block。
- Worker调度层面:所有租户的Split是在同一个队列里面进行调度,一个租户如果有过多Split会影响其它租户。
我们的计算力多租户方案如下:
我们在集群中引入了一个ResourceManager的模块用于从所有的Coordinator收集所有租户的资源使用信息,ResourceManager把收集到的资源使用信息跟我们预设的计算力的阈值进行对比,计算出哪些租户应该被惩罚,然后把这个惩罚信息通知到所有的Worker。Worker在进行调度的时候会参照ResourceManager通知过来的惩罚信息决定哪些租户的查询得到调度,哪些租户的查询不进行调度。这样不同的租户之间算力就会得到隔离,我们测试了如果有一个租户过量使用资源,它会在最长1.3秒之内得到惩罚,从而释放资源给其它租户,而社区默认版本的“惩罚”要等到租户所有的查询执行完成才会到来。只有元数据和计算力得到隔离,我们才能放心用一个集群来服务我们所有的用户。
2 Multi-Coordinator技术
社区版本的Presto里面,Coordinator是一个单点,它会带来两个方面的问题:
- 可用性隐患: 一旦Coordinator宕机、整个集群将不可用达5到10分钟。
- 无法实现无缝升级,升级过程中影响所有用户的查询使用。
我们采取了如下的架构方案:
首先我们在Presto的Coordinator之上放置了一个新的FrontNode模块,让用户连接到这个模块,而不是直接连接到我们底层的Coordinator,这样我们底层到底有多少个Coordinator,现在哪个Coordinator在给用户提供服务都对用户完全透明,这样架构上就比较灵活,从而方便我们在底层对Coordinator进行扩展。
FrontNode在接收到用户的查询之后会把请求按照Round Robin的方式发送给底层的多个Coordinator,这样多个Coordinator就可以分担压力,但是整个集群还是有一些全局的事情要有单个Coordinator来做,比如Presto的Worker状态监控、OOM Killer等等,因此我们引入了一个Zookeeper来做Coordinator选主的事情,选主之后主Coordinator的职责会跟社区的Presto类似:做全局的Worker状态监控、OOM Killer以及执行分配给它的查询;从Coordinator的职责则比较轻量级: 只负责执行分配给它的查询。
如果其中一个Coordinator因为任何问题宕机,Zookeeper会在秒级发现这个问题并重新选主,用户受到影响的查询只要重试即可。而且我们正在做的一个尝试是做查询的自动重试,对于确定是系统原因造成的失败我们做自动重试,这样一个Coordinator对用户的影响将会很小。
而有了多Coordinator的架构,我们要实现无缝升级就非常简单了,我们在升级的时候只要主动把某个Coordinator/Worker从集群中摘除,进行升级,升级完成再加入集群,客户可以毫不感知,因为在升级过程中始终有一个正常工作的集群在给用户提供服务, 比如我们在升级从Coordinator的时候,整个集群情况如下:
通过诸如多租户隔离技术、多Coordinator架构等等优化,我们基于PrestoDB打造了可以服务所有的用户的阿里云云原生数据湖Serverless SQL引擎。
六 云原生数据湖端到端最佳实践
如上图方案所示,DLA提供了端到端的方案,面对OSS数据开放性带来的管理及入湖困难,DLA数据湖管理,帮助您一站式构建安全数据湖。
- 提供统一开放的Meta服务对OSS数据进行管理,支持库表权限。
- 利用元数据爬取功能,可以一键创建OSS上的元数据信息,轻松自动识别CSV/JSON/Parquet等格式,建立好库表信息,方便后续计算引擎使用。
- 一键将RDS/PolarDB/MongoDB等数据库的数据同步到OSS存储当中,搭建冷热数据分层的业务架构,对多源海量数据进行数据洞察分析。
- 支持流式构建Hudi格式,满足T+10分钟的延迟要求,极大提升分析的端到端的延迟。
- Serverless化SQL分析,帮助您即开即用数据湖。用户无需购买任何资源,即可运行标准的SQL语法查询数据。
- 支持对数据湖存储OSS Cache加速,提升10倍的性能。
- 支持RDS、PolarDB、ADB、MongoDB数据十种数据源的分析。
- 对比传统的Presto、Impala方案提升10x的性价比提升。
- Serverless化Spark计算,帮助您自主玩转数据湖。用户无需购买任何资源,即可使用云原生的Spark服务,支持OSS 数PB的数据清洗、机器学习、用户可编程,玩转数据湖。
- 每分钟可弹出500个节点参与计算。
- 对比传统的自建Spark方案提升3x的性价比提升。
由于DLA涉及较多的技术点,本文讲述了部分技术细节,更多欢迎关注云原生数据湖分析DLA:https://www.aliyun.com/product/datalakeanalytics
【本文为51CTO专栏作者“阿里巴巴官方技术”原创稿件,转载请联系原作者】