Shuffle 是 Spark 作业中用于连接上下游数据交互的过程。提供 Shuffle 能力的服务称为 Shuffle Service。
最初, Spark 内部实现了基于哈希的 Shuffle Service,后来引入了基于排序的 Shuffle Service。尽管 Spark 内部不断对 Shuffle 机制进行迭代和改进,但由于存储和计算之间的耦合限制,Spark 内部实现的 Shuffle 机制在某些场景下可用性受到限制。
为了解决这个问题,业界提出了将 Shuffle Service 从 Spark 中独立出来的 Shuffle 设计,通常称为 Remote Shuffle Service(RSS)。 RSS 允许 Shuffle Service 在 Spark 之外运行,解耦了存储和计算,提供更好的可用性和性能。
火山 EMR Serverless Celeborn 是火山 EMR 推出的全托管服务级别 Remote Shuffle Service,采用高可用及存算分离架构。它能够支持 Spark 引擎进行远程 Shuffle 数据的读取和写入,并可在云环境中部署和应用。
功能 | 功能优化/描述 | 主要场景 |
---|---|---|
替换 Spark 原生 ESS | Shuffle 性能和稳定性提升 | 通用场景 |
Spark 可开启动态资源分配 | 由于托管 Shuffle 数据,Executor 可以被快速释放 | 通用场景 |
支持列式Shuffle | 助力 Native Shuffle 性能提升 | Spark on Native场景 |
在分布式计算引擎中,计算节点之间的数据交换是常见的,但也是昂贵的。传统的 Shuffle 框架中,磁盘和网络的效率低下(M 个 Mapper 和 N 个 Reducer 之间的 M * N),导致使用成本较高。
传统的 Shuffle 框架除了效率低下,还需要在计算节点上有很大的本地存储来存储 Shuffle 数据,因此也阻碍了存算分离架构的应用。
EMR Serverless Celeborn 通过以更有效的方式重新组织 Shuffle 数据,并将数据存储在一个单独的服务中来减少数据的存储和传输,使得整体Shuffle 成本更低,架构如下:
此服务通过数据重组提高了磁盘和网络效率,它将 Mapper 端的 Shuffle 数据保存在 Worker 节点上,Mapper 端不需要本地磁盘来存储这些数据。当 Recuder 需要该分区的数据时,它只需要一个网络连接并顺序读取文件即可。这很大程度上减少了 Mapper 端对本地磁盘的需求,并且将 Shuffle 上下游 Mapper 和 Reducer 解耦开来,上游Mapper 执行结束时可及时释放计算资源。
EMR Serverless Celeborn 还提供了 Tiered Storage(分层存储)能力,根据作业规模的不同选择不同介质(内存/SSD/HDD)存储 Shuffle 数据,进一步提升了中小规模作业执行性能。
由于 EMR Serverless Celeborn 实现了在 Reducer 端聚合数据的能力,解决了 Shuffle 阶段碎片读的问题,这大大降低了对磁盘 IOPS 的依赖,减少了 Spark Executor 运行时 OOM(内存溢出)的风险,保障了大 Shuffle 作业的稳定性,通过 CRC 校验方案,能够最大程度的保障 Shuffle 数据的稳定性,避免了因为数据丢失导致的执行正确性问题。