vlambda博客
学习文章列表

Spark在云原生时代的发展

前言

在ABC (AI, BigData, Cloud)时代,传统的大数据解决方案和厂商 (Cloudera, Hortonworks) 略显颓势,而云厂商 (AWS, Azure, GCP) 和云原生解决方案 (Databricks Cloud, Snowflake, ElasticSearch等) 则愈加迸发出活力。在这个云原生的时代拥抱云变成了不二之选,那么对于Spark[1]来说它是如何在云原生时代积极拥抱云的呢?

背景

10多年前,Google的3篇论文拉开了大数据时代的大幕,这3篇论文不仅从理论上详尽地阐述了分布式大数据的经典算法,更从工程上解决了普通商业硬件的分布式架构之道,同时也定义了未来多年内的普通商业硬件,尤其是大数据服务器的设计架构。

当时一台典型的大数据服务器通常包括一路或两路CPU,核数从十几核到几十核不等 (Hyper Threading);几十G的内存;多块SATA或SAS HDD硬盘。

Spark在云原生时代的发展

受限于当时硬件的能力,软件上的设计需要考虑到硬件的行为从而能更好地利用到硬件的性能:

移动代码而非移动数据:MapReduce框架在实现时非常强调的一点是移动代码而非移动数据,因为代码的大小相比于数据是小很多的,在网络带宽较小的时代移动数据会带来巨大的开销,相反将代码放到数据所在节点去执行能带来显著的提升。数据和计算共存:正是由于移动代码而非移动数据的设计思路而形成了数据和计算共存的架构。一个典型的Hadoop集群通常会把数据集群HDFS和计算集群MapReduce (YARN) 部署在一起提高数据本地性 (Data Locality)。带宽优先设计:大数据应用由于处理的数据量巨大通常需要较长的处理时间,在这样的前提下在MapReduce设计之初就有了这样一条假设:大数据任务通常对于响应的要求较低。因此在MapReduce设计中无论是任务分发还是数据传输优先考虑的是带宽而非延迟。充分利用多盘优势,避免随机读写:HDD由于机械结构的限制其顺序读写的吞吐量一般在100~200MB左右,而随机读写的性能则会更差。相较于CPU的处理能力有量级的差距。为了匹配速度差,通常会使用多块HDD磁盘来并行化和分散IO,提高整体IO吞吐量。同时在IO设计的时候也会尽量把随机IO转换成顺序IO以提高吞吐量 (Sort based shuffle write/read就是一个典型的例子)。

当然还有其他许多的优化考量点不在这罗列了。重要的是在这10多年间,从软件架构到硬件性能,从服务器设计到数据中心架构都有了巨大的变化,这其中包括:

容器化。随着docker的诞生,容器化技术在后台服务领域迅速推广开来,容器化不仅能带来devops的便捷性,同时也能更好地隔离资源。而Kubernetes的诞生,则将容器化应用和容器化调度推到了一个新的高度。存储计算分离。随着网络带宽的提升和异构集群技术的发展,存储计算分离被再度提出了,尤其是在公有云上存储计算分离已成为常态,如何更好地适应存储计算分离变得尤为重要。更快的存储设备。更快的存储设备近些年来不断推出,如SSD,PMEM等,这些新的存储设备不仅有更高的速率,而且大大优化了随机读写的性能。显著提升的网络带宽。近10年中网络带宽得到了显著的提升,从最早的1Gbps,到现在主流的10Gbps,25Gbps乃至40Gbps,100Gbps。同时RDMA,DPDK的应用也越来越广泛。

这样的变化对于现有的大数据软件架构带来了极大的挑战,原先的设计在新的硬件和架构中变得不再有意义:

1.存储计算分离使得我们所恪守的数据本地性不再有意义,所有的数据不再是本地的了,更快的网络抹平了本地性带来的优势。2.更高的网络带宽和更低的延迟使得我们不必再以带宽优先来设计网络传输,更低的延迟变得更有意义。3.更快的存储设备,更好的随机读写性能使得我们所做的对于顺序读写的优化 (归并排序) 变成了额外的负担。

因此面向新的硬件和架构,面向云原生的时代,大数据软件的设计必须进行相应的调整和优化以发挥更好的性能。Spark作为当前最为主流的分布式计算框架,它又是如何在云原生时代做出相应的改变的呢?

Spark演化的方向

容器化

容器化由于其优异的devops能力、资源隔离、统一调度等特性,在微服务和后台架构中有广泛的应用,但是在大数据、Hadoop领域容器化却没有广泛的采用,这其中制约大数据容器化的问题主要有哪些呢?

1.容器化调度和大数据应用所恪守的数据本地性相背离,会带来一定的性能问题。2.大数据应用对于系统性能、尤其是IO性能要求较高,而容器化有一定的性能开销。3.更为重要的是大数据系统架构之时容器化技术、容器化调度尚未兴起,在融入容器化技术中需要与原有架构做较大的调整。

当然容器化技术的调度也是日新月异的,上面所列的问题在新的版本中可能已不复存在。既然有这样那样的问题,那为什么大数据还需要容器化呢?

首先在企业devops流程中,docker技术已是事实上的标准,同时前后端技术也已经全面docker化了,统一企业devops流程,将大数据应用docker化是一个自然的过程。其次容器化调度框架Kubernetes已成为企业数据中心统一的DCOS,所有的前后台部署都使用k8s统一进行调度。但大数据存储和计算游离在容器化调度之外,额外部署管理增加了管理负担和资源开销。容器化技术所提供的资源隔离对于大数据应用来说有很大的意义。大数据应用通常对于资源的需求是激进的,如果没有很好的资源管理和隔离机制,会造成应用的互相影响,降低应用的稳定性,因此有效的资源隔离是非常必要的。

在这样的背景下,容器化并支持容器化调度是现有大数据组件的趋势之一。Spark在其设计之初将与资源管理框架的交互抽象化,并支持多种资源管理框架,如YARN,Mesos等。而从2.3版本开始官方适配了k8s,能够以容器化的方式启动Spark应用程序并调度executor。Spark on Kubernetes的主要架构如下所示:

Spark在云原生时代的发展

在后续的版本中,Spark on Kubernetes也逐步补齐了与其他资源管理框架支持上的差异,并预期在Spark 3.0中将其GA。相信随着Spark on Kubernetes的成熟,大数据容器化技术的进化,使用容器化会是不二之选。

存储计算分离

在前面的背景中也提到了由于网络带宽的增加和异构集群的流行,存储计算分离再度流行,尤其是在云上环境,块存储 (Blob Storage)、云盘已经成为主流,主流的虚拟机配置中只有少量的本地硬盘作为系统盘和本地缓存,同时配置云盘作为数据盘。在这样的情况下,数据中心的架构变为了如下的形态:

存储计算分离对于现在的MR是框架的挑战主要有:

1.数据本地性的约束已不复存在,所有的输入数据都是通过远程读取的,因此针对数据本地性的任务调度策略已没有多大意义。2.所有的本地存储 (比如shuffle,spill) 都会涉及到网络传输,因此基于本地硬盘的shuffle方式已不是最佳选择,会带来额外的代价。

既然所有的数据都是通过远程进行读写,那何不利用这样的特性来设计一个更为合理的shuffle框架呢?为此Spark在3.0以后正式引入remote shuffle的方式,以适应存储计算分离的架构。SPARK-25299[2]将Spark的shuffle读写与shuffle逻辑解耦并框架化,剥离出与本地系统交互的部分,后续可以基于SPARK-25299的框架来实现remote shuffle,例如Splash[3]

对象存储的支持

在云上环境中,数据持久化已不再交由虚拟机的本地硬盘,更多的则是使用块存储或是对象存储,而对于海量数据的存取,对象存储是一个廉价而高效的解决方案。对象存储,其高扩展性以及海量文件存储的能力,非常适合大数据存储,但是另一方由于其原子性语义的缺失、较弱的一致性、list, rename较高的代价,也会为大数据处理带来一定的问题。

那如何来解决对象存储带来的问题,更好地支持对象存储呢?

1.在Hadoop层面上实现更好的FileSystem API,如S3A[4],来解决上面提到的问题。2.在数据组织形态上设计更好的结构,来规避上述提到的问题,比如Spark所支持的Apache Iceberg[5]Delta Lake[6]Apache Hudi[7]

弹性化调度

云上环境的计算资源是易失的,像是AWS,Azure都会提供更为廉价的易失性实例,为了能更好地使用这些易失性实例,需要分布式计算框架将fault tolerance作为常态考虑。这样就需要尽可能地将状态的保存从本地存储迁移到远端可靠集群上去。SPARK-25299[8] remote shuffle的可以有效地避免本地状态 (shuffle) 的保存,是的计算节点变为无状态的,更好地支持易失性的场景。

同时在云上环境中,为了更好地利用计算资源,控制计算成本,分布式框架也需要及时主动地释放资源,做到弹性扩缩容。Spark从1.2版本起就支持executor级别的弹性扩缩容来更好的利用executor资源。但是在云上环境,光是释放executor资源是不够的,更进一步的是需要释放计算实例,为此需要将Spark的弹性扩缩容策略进一步改进,以更好地支持云上实例的动态扩缩容。

总结

本文从大数据的基本架构以及软硬件演进的历史介绍了大数据框架在云原生时代下的挑战。同时也从4方面详细介绍了Spark在应对云原生时代的进化。大数据框架在不断地迭代演进中以适应新的基础架构,在ABC时代拥抱云、融入云,打造更好的云原生大数据框架必定会是未来的发展方向。

References

[1] Spark: https://spark.apache.org/
[2] SPARK-25299: https://issues.apache.org/jira/browse/SPARK-25299
[3] Splash: https://github.com/MemVerge/splash
[4] S3A: https://hadoop.apache.org/docs/current/hadoop-aws/tools/hadoop-aws/index.html
[5] Apache Iceberg: https://iceberg.incubator.apache.org/
[6] Delta Lake: https://delta.io/
[7] Apache Hudi: https://hudi.incubator.apache.org/
[8] SPARK-25299: https://issues.apache.org/jira/browse/SPARK-25299


腾讯大数据诚招计算、存储、消息中间件、调度、中台等各方向的大数据研发工程师,请私信或联系[email protected]