写点什么

【联通】数据编排技术在联通的应用

作者:Alluxio
  • 2022 年 9 月 13 日
    北京
  • 本文字数:7863 字

    阅读完需:约 26 分钟

【联通】数据编排技术在联通的应用

欢迎来到【微直播间】,2min 纵览大咖观点,本期分享的题目是数据编排技术在联通的应用。

本次分享内容将围绕四个方面讲述 Alluxio 数据编排技术在联通的应用,主要围绕缓存加速、存算分离、混合负载以及轻量级分析四个不同的使用场景进行分享:

摘要

01. 在缓存加速方面的应用

为了加速 Spark 计算,引入了 Alluxio 来加速数据的读写性能,提高数据写入的稳定性,以及接管 Spark Cache 后提升 Spark 作业的稳定性。这是我们一开始采用的架构,数据编排在我们的整个架构中的定位是缓存加速层。

  • 加速迭代计算:加速下游 SQL 读取数据速度,提升数据写⼊稳定性;

  • Spark Job 间共享数据,替换 Spark cache;

  • 内存多副本显著提⾼热数据访问速度;

  • 调整数据分布策略实现负载均衡;

  • Alluxio 带来性能与稳定性提升;


02. 在存算分离方面的应用

  • 利⽤其他业务资源满⾜计算扩容需求;

  • 实现存储独⽴扩容,数据冷热分离;


03. 在混合负载领域的应用

  • 利⽤Alluxio Client Cache 实现缓存隔离;

  • 利⽤Alluxio Fuse 打通 ETL 与 AI 训练/推理;


04. 轻量级分析相关探索

Presto + Alluxio 实现轻量级数据分析

1) 在⽤户集群搭建 Alluxio + Presto 两套系统满⾜数据分析需求,运维复杂度相对较低,纯 SQL 交互⽤户体验好;

2) Alluxio mount 平台 HDFS⽤于私有数据共享,Alluxio SDS mount 平台 Hive⽤于公有数据访问及性能加速;

3) 基于 Presto Iceberg connector 的 hadoop catalog mode,采⽤只写缓存的⽅式在本地完成 ETL,最终数据持久化⾄平台 HDFS;

4) Alluxio 使⽤3 副本策略保证缓存数据的可⽤性,可挂载独⽴存储集群持久化存储需⻓期保存的分析数据。

以上仅为大咖演讲概览,完整内容【点击观看】


附件:大咖分享文字版完整内容可见下文

01. 在缓存加速方面的应用

首先介绍 Alluxio 作为分布式缓存加速大数据计算的使用场景。我们事业部存在多个数据处理与数据分析业务,这些业务分布在不同的平台。使用 GreenPlum 数据库的数据处理业务基于批处理存储过程完成数据加工,对计算时间有严格的要求,有明确的 deadline。这些业务遇到的主要问题是 GreenPlum 集群规模达到几十台时遇到扩容瓶颈,进一步扩展给业务运维工程师带来很大挑战;还有一部分业务基于 hive 运行 T+1 批处理作业,遇到的主要问题是内存、CPU 等资源消耗比较大,并行度不高,跑的速度比较慢;还有一些传统统计业务是跑在 Oracle 上,Oracle 单机跑的效果不是特别好,并且 Oracle 比较贵,一台小型机可能就要两千多万,业务方期望能有其他数据分析平台替代 Oracle。

当时,我们的课题是基于 Spark、Hadoop 这个开源体系,去做一个统一的计算平台,把上述三个引擎承接的业务全部接过来。我们直接用 Spark + HDFS 遇到了一些问题:


首先,它的性能是没有办法满足 GreenPlum 承载的生产业务,因为 GreenPlum 是 MPP 数据库,同等体量下它会比 Spark 要快很多;


其次,GreenPlum 承载的业务中存在伴生的交互式查询的场景,同样性能也是没有办法去满足的。


接着,对于一些批处理的业务来说,Spark + HDFS 比较欠缺稳定性,批处理的业务每一次任务周期会有几千、几万个 SQL 去做迭代计算,任务如果经常失败的话,没有办法很好地在那之前保证去完成。

所以,为了加速 Spark 计算,我们引入了 Alluxio 来加速数据的读写性能,提高数据写入的稳定性,以及接管 Spark Cache 后提升 Spark 作业的稳定性。这是我们一开始采用的架构,数据编排在我们的整个架构中的定位是缓存加速层。

具体看一下使用案例,如果拿加速迭代计算来说,我们会把 Sink 直接写到 Alluxio 上,然后下一个 SQL 的 Source 去读这个 Sink,把 Source 和 Sink 之间的串联交给 Alluxio 的缓存去做,这样可以比较显著提升整个 pipeline 的稳定性。因为不需要再和磁盘交互,可以极大降低磁盘压力。而通过内存,pipeline 的稳定性得到了比较好的改善,通过直接读取内存会提高整个 pipeline 的运行速度。

第二个使用案例,是我们通过 Alluxio 去共享整个 Job 之间的数据,而避免使用 Spark Cache。通过 Spark Cache 方式会对整个 Executor JVM 造成比较大的压力。性能测试结果表明在数据量达到一定规模的情况下,Spark Cache 的性能是要比 Alluxio 差一些。而且 Alluxio 随着 Spark 中间数据的增大,它对性能的影响是可以预测的,是线性而不是指数性上涨的。所以说,我们选择用 Alluxio 做中间数据的共享层。

为了增强数据读取的性能,可以显示的为每个路径去配置副本浮动范围。而且 Alluxio 还支持了数据预加载的功能--distributedLoad.这个在 2021 年的时候,社区也是花了很多的精力在上面,目前是做的十分完善的工具了。我们可以在执行一些固定任务之前,提前先把数据加载到内存。这样可以提高整个 pipeline 的运行速度。此外,Alluxio 还支持一些内存操作工具,比如 pin 和 free,这样的话能方便我们更好地去管理内存。就是按照我们既定的一个 pipeline 可以使整个内存布局得到最好的优化。

接下来是跟 Alluxio 数据编排 Policy 有关的例子。比如我们一个 Spark 任务去读一个数据,它可能会在每个 worker 上都拉起一些副本,比如重复使用的一些数据。这种情况可能会迅速把缓存占满。对于这种情况,Alluxio 可以提供一个叫确定性哈希的策略。这个策略可以使我们在固定的某几个 worker 上去读。这样可以把整个集群的副本数加起来,能更有效地去使用空间。

除此之外,针对大量场景,它还支持一些跟负载均衡相关的策略。比如最高可控策略,它会选择整个集群内空间剩余量最大的一个 worker 去读。这样可以使所有 worker 的使用比较均衡。但是,它也有一些问题,当大量 Alluxio Client 在 Spark Executor 这边如果大量去挤兑一个 Alluxio Worker 的话,那么可能会导致这个 worker 的使用量瞬间打满,出现性能降级的情况。

针对这种情况,我们可以去选择一个轮循策略,在若干有剩余量的 work 之间去轮循使用,这样可以比较好地去实现集群的负载均衡。

从总的使用效果来看,Alluxio 还带来了比较大的性能与稳定性的提升。这里是一个比较典型的 Spark Task 统计,Alluxio 对整个 GC 的时间优化,还有整个任务总耗时的优化的收益是比较显著的。它最大的优点是可以显著降低每批次 Job 的重算概率,从而使整个过程更加稳定,更加可预测。

最终效果是我们从之前 GreenPlum 迁移过来的核心业务的规模已经有接近 70 倍的增长,并且承接的用户数相比之前提高了 100%,业务总体提速了 26 个小时。交互式查询业务目前日常数据已经达到 60TB,如使用 Spark 单表 2.5tb 数据,查询耗时也是分钟级别。原先 Oracle 业务迁移到 Spark 后可以做用户级的计算,这对于他们来讲是具有很大的价值。

02. 在存算分离方面的应用

接下来是我们针对集群继续发展的特点,做了在存算分离方面的一些建设。存算分离的背景大概是什么样的?

这主要是跟整个集群的发展有一定的关系。首先在我们这边的平台建设是跟着业务走。随着业务快速增长,会出现资源碎片化的情况。如图所示,第一年新建一个机房,我们占用了一部分机架,其他业务或部门也会占用一些机架。到第二年的时候,第一年的机房就满了,第二年新建的机房大家可以各自去申请一些。这就导致整个机器不具有连续性,可能会跨机房,甚至可能会跨楼,有时候甚至还会跨数据中心。与之伴随的就是业务快速增长,基本上处于逐年倍增的情况,而且资源申请周期非常长,至少需要一年的时间才能交付,最后导致的情况就是集群呈现碎片化。

更为糟糕的是在业务增长过程中,其实它的资源需求是不平衡的,主要是存储与计算之间的不平衡。


首先,一个客观事实是历史数据的存储需求是逐年递增的。之前业务只需要保留 1 至 2 个月的数据。但是现在因为一些历史的趋势分析或是各方面测算,一些主要业务的数据需要保存 12 至 24 个月。业务数据每个周期之间的环比涨幅大概是 10%,涨幅大时甚至有 5~10 倍的情况,主要是跟业务逻辑变化相关。


存储规模的涨幅大概是计算规模涨幅的 5 到 6 倍,这也是存储计算发展不平衡的情况。

我们使用了存算分离的技术来解决这些问题。


首先解决计算资源的问题。我们向其他的业务租借了一个现有的集群,利用该集群空闲的夜间完成数据加工作业。我们在上面部署了一套 Spark,以及 Alluxio 和我们集群的 HDFS 构成一套存算分离的数据分析系统。为什么不在该集群部署 Hadoop?原因是租借的业务集群已经搭建了一套 Hadoop,我们不被允许二次搭建 Hadoop,也不允许去使用他们的 Hadoop。所以,我们就用该业务集群的 Alluxio 去挂载我们平台的 HDFS。挂载 HDFS 之后就跟我们自己平台保持一样的命名空间,这样看起来都是一样的,基本上做到用户无感知。

更详细的如此图所示,就是对于 2 个 Alluxio 来说,看到的 Path 都是一样的,都是映射到 HDFS 的一个 Path,所以用户认为这两个 Path 都是一样的。我们在读写不同 Path 的时候,会让不同的 Alluxio 分别执行读写操作。比如远程 Alluxio 对 Path1 是只读的,它会去写 Path2,本地 Alluxio 会写 Path1,但只会去读 Path2,这样就避免了两个 Alluxio 相互之间冲突。

在具体落实方案上,我们还使用了一些自己的设计,来避免存算分离会遇到的一些问题。


首先,我们在远程业务集群这块,是基于 RocksDB+Raft HA 的方式来解决没有本地 HDFS 时 Alluxio HA 元数据操作性能的问题。因为我们的 HDFS 在我们的集群,中间有一定的网络消耗。如果我们直接还是采用原来的 zookeeper ha,首先我们需要在他们的集群搭一套 zookeeper ha,以及把元数据放在我们自己集群的 HDFS 上,跨网络元数据交互可能会带来很多的不确定性。比如带宽打满了,或者是因为其他网络波动的因素,会导致 Alluxio 本身的性能抖动,甚至可能出现因为数据写入或者读取超时导致整个 Alluxio 挂掉的情况。所以,我们选择了 Alluxio 2.x 之后不断去建设去完善的 RocksDB+Raft HA 的方式来解决这个问题。


其次,我们在业务集群这边因为要满足所有中间数据的存储,提升整个计算性能,所以我们使用 HDD 作为存储介质。Spark 作业的中间过程数据直接存储在缓存磁盘里,不会与 UFS 有任何交互,所以对于用户来说,这种模式的性能是不受影响的。


第三,最终结果还可以持久化至集群。因为最终结果的数量也不是特别大,所以它的耗时还是可以接受的。最后对于用户来说,他可能需要跨集群部署任务,我们是在租借的业务集群之内搭建了一个 Dolphin Scheduler Worker,通过 Dolphin 的调度策略,帮助用户把他的特定任务起在这个 Worker 上面。通过 Worker 的选择来控制它提交到不同的集群。对于用户来说只是配置上做了变更,作业提交入口以及管理入口都是相同的,解决了跨集群作业管理的问题。

实现计算混合部署之后,我们又接到了大量的数据存储需求。但是我们的集群短时间内没有办法扩容了,所以我们申请了一批大容量存储,然后把大容量存储 mount 到 Alluxio,将历史数据自动化降级到大容量存储上,查询的时候就经由 Alluxio 透明访问。我们会把前 2 个月至前 12 个月的历史数据降级到大容量存储上,本地集群只保留最近几个月会频繁参与计算的数据。对于用户来说,访问的路径跟之前还是一样的,我们通过 mount 方式屏蔽了历史数据分层管理的差异性。对于我们的好处是单位服务器的存储容量显著提高了,大容量存储可以独立扩容,对于我们来说缓解了很大的存储压力。

以下是我们做完存算分离以后的实际效果。

首先,某核心用户租借算力占平台分配算力的 82%,这个是比较大的提升。承接新业务使用租借算力占比达到 50%,Alluxio 管理 ETL 过程数据达到 148TB,算是非常庞大的数字了。因为 Alluxio 其实作为缓存来讲并不会去管理特别大量的数据。管理 100 至 200TB 这个数据量,我们跟社区一起做了很多工作,包括 worker 启动超时等优化,以满足中间数据存储的需求。单独扩容的大容量存储给我们带来的好处是单台服务器的存储容量提升 5 倍,计算集群采用的计算型服务器存储容量比较小,大容量存储单台机器就能存储 90TB 数据,服务器台数相同的情况下,容量提升比较明显,所以历史数据存储显著降低,扩容成本是降低了 83%。

03. 在混合负载领域的应用

当集群向后继续发展的时候,我们引入了更多的计算引擎来适配更多的业务场景以得到更好的效果。其中比较典型的场景是我们在一个平台上同时提供 Spark 和 Presto,Spark 主要用于 ETL,Presto 提供即席查询服务。它们共用 Alluxio 时会遇到一些问题:首先,Alluxio System Cache 不支持 Quota,没有办法隔离 Spark 跟 Presto 之间的用量,由于 Spark ETL 作业写入的数据较大,数据直接写入 Alluxio 作为 pipeline 下一个节点的读取加速。这种情况下内存冲刷比较频繁,会一次性占用较多的内存。这样 Presto 刚完成数据加载,想查数据的时候发现缓存中没有了,Presto 查询的缓存利用率不是特别高。

第二个情况是一些用户使用 TensorFlow 做自然语言处理或者时间序列分析的 AI 计算。在 AI 计算之前,用户首先基于 Spark 做分布式 ETL,然后想把 ETL 结果直接拿给 TensorFlow 使用,在这种情况下,用户很难把分布式的数据和本地数据联系到一起。第三方框架比如 TensorFlow on Spark 一般都会封装一些标准模型。用户使用的模型不是主流模型,但实际效果较好,这种情况没有办法套用现用的第三方框架,直接将 Spark DataFrame 转换成 TensorFlow 的数据模型直接使用。这样 TensorFlow 还是一种读取本地文件的模式,就是不是很好的能把 Spark 与 TensorFlow 联动起来。

针对使用案例刚才讲到的一些问题,我们做了一些改进。首先,Presto 这边我们放弃了使用 Alluxio System Cache,而是使用 Alluxio Local Cache 缓存数据,这样跟 Spark 使用的 Alluxio System Cache 进行隔离。我们会为每个 Presto Worker 去开辟一个独立的缓存。这个缓存是放在 Ramdisk 上面,官方推荐放到 SSD 里边也是可以的。缓存不占用 Presto Worker 的 JVM 空间,不会对 GC 造成额外负担。除此之外,因为我们有一些磁盘场景,所以跟社区一起完善了基于 RockDB 的缓存实现。以上是我们在缓存隔离上做的一些设计。

在 AI 这边,我们利用 Alluxio Fuse 打通了 ETL 与 AI 训练和推理。Alluxio Fuse 首先做了本地文件跟分布式系统挂载,这样就可以把分布式文件映射到本地文件。然后用户可以直接使用读写本地文件的方式操作一个分布式系统中的文件,与笔记本上开发的读写本地代码的逻辑完全相同。这样就成功地打通了 Spark ETL 跟 TensorFlow 的计算。Alluxio 目前是提供两种 Fuse 挂载模式,首先提供为每个 Worker 创建一个 Fuse 的挂载目录。这种方式可以更好地提高数据访问性能,我们目前使用的是这种模式。还有一种是单独起一个 Fuse 进程,这样就不需要在本地区部署 Alluxio 集群,这种方式有助于灵活部署。大家可以按照自己需要去选择不同的部署模式。

目前使用的效果,Presto 因为引入了 Cache,查询性能提升了 50%左右,相比 OS Cache 更加稳定。如果我们都用 OS Cache 性能是最快的,但因为集群支撑的是数据密集型的负载,所以 OS Cache 不是特别稳定,容易被刷下去。相比没有 Cache 加速时,它的查询性能有不错的提升。大数据 AI 集成方面,用户可以用 TensorFlow 去训练推理的代码不需要做任何改动,就可以跟 Spark ETL 做集成,目前首批业务是完成了 60 万用户的接入,整个过程基于 Dolphin Scheduler 实现大数据+AI 全流程自动化调度,用户的运维复杂度非常低。这里帮 Alluxio 的邱璐做个广告,她目前是 Alluxio Fuse 的负责人。Alluxio Fuse 已经在微软、Boss 直聘、哔哩哔哩、陌陌等公司的生产训练中完成了部署。

04. 轻量级分析相关探索

现状一,目前联通在大力推动数字化转型,之前很多跟数据分析没有关系的业务,如一些传统业务,也想做数据分析。利用之前沉淀的数据,想做预测或者是原因定位。目标用户更多是业务工程师,更喜欢关系型数据库以及 SQL。


现状二,不同的业务之间同时需要访问平台运营的公有数据,以及访问、管理业务私有数据。这些私有数据的业务口径由业务方制定,并按照自己的开放策略向其他业务方提供。因此共享私有数据需要数据提供方授权,公有数据只需要平台授权就可以。


现状三,服务器资源增量目前低于业务的需求量,因为数据分析需求上涨很厉害,而且不可预测,很多需求不在总体规划里。与此同时,业务自有服务器在空闲时间段负载比较低,一般主要是白天比较忙。这样的话,他们的现有资源其实是能够去支撑新增的一些数据分析业务的。


所以,考虑到平台在扩容的时候是没有办法跟上业务的发展脚步的。为了能尽快满足业务数字化建设需求,我们计划为这些业务做私有化部署,基于 Spark 做私有化部署的时候,我们遇到一些问题。

首先,如果按照我们自己标准的模式为每个用户去独立部署一个 Spark on Yarn 的话,管理复杂度就太高了。我们可能会管很多个集群的 Spark on Yarn,这样的管理成本是无法支撑的。另外,部分用户服务器已经部署了 HBase on Hadoop,这些集群不允许我们部署 Hadoop 也不允许我们在上面部署 Hbase,而且不能使用已有的 Hadoop。这样就给 Spark 体系增加了很多难度。并且,业务用户希望使用这种纯 SQL 分析数据,如果是这样,我们会需要添加类似于 Kyuubi 的工具,我们需要为了满足一个需求添加很多组件,这样的话多个集群的管理复杂度会非常高。还有一种方式就是我们不采用 on Yarn 的方式,采用 Spark Standalone 模式,其实部署起来相对还好,只使用 Spark + Alluxio 还不错。


但这种方式的问题是,如果我们采用 Spark per job 作业模式,它的并发度是有限的。如果我们给一个通用值,它并发度是一个查询起一个 job,并发度是比较低的,可能同时只能并发几个。而且 Spark 配置复杂度偏高,对于 SQL 用户来说不是很友好,还需要配置内存大小,executor 数目,或者 Dynamic allocate 限制参数。如果不采用 Spark per job 采用单 Session 的模式,又没有办法在多任务间做优先级隔离,无法对一个业务的多个 SQL 进行编排。

我们的思路是希望使用 Presto+Alluxio 做一个轻量级的数据分析,基于 Presto Iceberg native connector,直接去操作存储在 Alluxio 上面的 Hadoop catelog 表,只需要加 Presto + Alluxio 两个组件,我们就可以完成整个 ETL 的过程。我们用了两套 mount 系统:第一套是比较传统的 Alluxio 直接去 mount 平台的 HDFS;第二套是 Alluxio structure data service(结构化数据服务)mount hive 表,对于用户集群来说,他看到的 hive 表跟平台这边的 hive 表是一样的。Mount 的好处是可以将数据透明地映射到 Alluxio 命名空间之内,通过 Hive Table load 提前把数据加载至 Alluxio 缓存中,增加数据读取性能。所有的中间过程只需要 Presto 以 must cashe 的方式写入 Alluxio 本地,加工完之后,就可以把这个数据最后的结果数据写回平台的 hive。整个架构比较简单的,只需要两个组件,每台机只要起两个进程,没有额外的负担。


而且用户可以通过 JDBC 或者是 Command line 两种形式访问 Presto,并且用户可以通过选择性的 persist Iceberg Hadoop table 来授权给其他集群用户访问中间数据。通过 Alluxio 的统一命名空间设计,用户看到的 hive table、Iceberg table 是完全一致的,实现了多个集群之间的透明管理。

在这个轻量级数据分析栈内,我们只需要在用户集群搭建两个组件就可以满足需求。因为用户基于 Presto 以纯 SQL 的方式完成数据分析,体验比较好。目前我们用户喜欢用 JDBC 的方式去连接,所以暂时不需要提供更多可视化工具。如果需要,只要在我们现有的可视化工具里配置链接就行。Alluxio mount 平台 HDFS 用于私有化数据共享,SDS mount 平台 Hive 用于共有数据访问及性能加,基于 Presto Iceberg connector 的 hadoop catalog mode 这种模式,可以采用只写缓存的方式在本地完成 ETL。Alluxio 全部使用的挂载磁盘的方式来保证缓存空间足够容纳数据分析中间数据,最终数据持久化至平台 HDFS。Alluxio 在写入的时候会使用三副本的策略,保证缓存数据的可用性。

分享嘉宾

张策 联通软件研究院 大数据工程师


嘉宾介绍:毕业于北京交通大学,2018 年加入联通软件研究院,主要负责大数据平台的建设与维护,同时在 Alluxio 社区担任 PMC Member。

想要获取更多有趣有料的【活动信息】【技术文章】【大咖观点】,请关注[Alluxio智库]


发布于: 13 分钟前阅读数: 2
用户头像

Alluxio

关注

还未添加个人签名 2022.01.04 加入

Alluxio是全球首个面向基于云原生数据分析和人工智能的开源的资料编排技术!能够在跨集群、跨区域、跨国家的任何云中将数据更紧密地编排接近数据分析和AI/ML应用程序,从而向上层应用提供内存速度的数据访问。

评论

发布
暂无评论
【联通】数据编排技术在联通的应用_中国联通_Alluxio_InfoQ写作社区