采用alluxio提升MR job和Spark job性能的注意点

时间:2023-03-08 19:57:43

1. 介绍

相信很多使用alluxio的同学,都是冲着其memory speed的加速效果而来。我也一样,认为只要用上了alluxio,整合了spark和hadoop就可以轻松把以前的JOB提升数倍的性能。然而,事实并不是这么顺利的。

今天主要就来总结下alluxio在提升MR job和Spark job性能上存在的问题和挑战。

2. 实验说明

2.1 实验环境

后面在说明问题的时候会贴一些实验结果。为了排除网络IO的影响,我这边的实验将hadoop、spark还有alluxio都部署在一台机器上。这台机器内存120G,40核。

2.2 实验方法

主要是做对比实验,一个使用alluxio,一个不使用alluxio,查看效果。

2.3 实验负载

为了让对比实验的结果差异尽量明显,在设计实验负载的时候,我们选取了能最大化发挥alluxio内存存储优势的实验负载。

我们运行一个只进行读取文本文件的job,来作为实验负载。这样的job主要性能瓶颈都是在IO上,可以保证内存存储带来最大效果。

3. MapReduce on alluxio

3.1 读取10G文件(1G split)

采用alluxio提升MR job和Spark job性能的注意点

采用alluxio提升MR job和Spark job性能的注意点

3.2 读取20G文件(1G split)

采用alluxio提升MR job和Spark job性能的注意点

3.3 读取60G文件(1G split)

采用alluxio提升MR job和Spark job性能的注意点

3.4 读取60G文件(512MB split)

采用alluxio提升MR job和Spark job性能的注意点

4. Spark on Alluxio

这个可以拿Spark shell来测试,实验结果也是:alluxio没法带来成倍的性能提升。实际用alluxio和不用alluxio效果差不多。

5. 关于使用alluxio来提升性能的注意点

5.1 alluxio是否以memory speed来进行读写?

alluxio是否以内存的速度来进行读写?答案肯定是:YES。 当然前提是没有其他干扰(比如和hadoop这样的分布式计算引擎集成在一起,影响性能的因素是非常多的)。这里主要是单纯利用文件操作API读写和以MR JOB或者SPARK JOB形式读写的差别。这里给下结论:

  1. 纯文件系统下的测试和以JOB形式进行测试的区别
    a. 纯文件系统的API去读取文本文件,可以有预期的性能提升(8倍左右)。这时候是比较纯粹的测试,没干扰。
    b. job形式进行测试。生产使用的MR JOB修改后进行测试,都是基本差不多的(无论文本文件还是seq file)。因此需要分析其原因。

  2. JOB形式测试依赖 配置、JOB任务负载(不同的JOB,产生性能瓶颈的地方不同。要确保是IO密集型的JOB)

PS: 还有个坑,就是alluxio利用文件系统API来操作的时候,如果是sequence file格式的话,也是不会以memory speed来进行读写的。我怀疑开销可能是在解压缩上。因为我实验的sequence file data是有压缩的。欢迎大家反馈。

5.2 如何使用alluxio提升MR job性能?

要使用alluxio来提升性能也是可以,确保如下要求:

  1. 任务是IO密集型的JOB
  2. 参数配置符合要求
  3. split size要大(也就是说map个数要少),最起码split size 大于1G的纯IO密集型才可能体会到有性能提升

以上结论可以看我第三节的实验结果。但是实际操作中你会发现有很多问题,比如控制split size特别大,在调整配置的时候会引发各种问题。而且即使split size变大了,提升了单个map任务的读取速度了,但是却会在集群角度降低map的并发性能。

而且即使在完美情况下,恐怕也无法有成倍的性能提升(第三节的实验是纯粹的IO类JOB,也尽量采用了比较大的split size,也仍然只有50%左右性能提升)。至于为什么我没有采用更大的split size,是因为这样配置会引发其他的一些问题,导致集群不能正常工作。

5.3 如何使用alluxio提升Spark job性能?

实验跑了下line count job,统计数G文件的行数。不过测试出来也是性能差不多。耗时应该都在任务分片上了。所以使用spark on alluxio来提升性能也有如下要求:

  1. spark job是IO密集型的
  2. 最好是有很多spark job,并且不同job之间有RDD共享(alluxio提供的内存数据管理可以很好的管理热数据,从而增加内存命中率来改进性能)
  3. spark sql这种大表关联查询的场景貌似比较适合。因为查询的时候经常有一些中间结果集的共享。因此这种spark的大表的关联查询job估计使用alluxio能有效果~

6. 综上

想用alluxio来提升单个job的性能,基本上是比较难的,不建议。如果你们的使用场景,job比较多,内存资源比较有限的情况下,通过alluxio合理管理热数据,能有效改进性能。还有spark或者hive之类的大表关联查询,估计也有效果。其他场景应该比较难看到什么性能提升。

关于alluxio的应用场景,alluxio的作者其实也给出了总结:专访范斌,谈开源三年后的Alluxio

范斌: Alluxio作为一个内存级的虚拟分布式存储系统有几个常见的使用场景:

  1. 计算层需要反复访问远程(比如在云端,或跨机房)的数据;
  2. 计算层需要同时访问多个独立的持久化数据源(比如同时访问S3和HDFS中的数据);
  3. 多个独立的大数据应用(比如不同的Spark Job)需要高速有效的共享数据;
  4. 当计算层有着较为严重的内存资源、以及JVM GC压力,或者较高的任务失败率时,Alluxio作为输入输出数据的Off heap存储可以极大缓解这一压力,并使计算消耗的时间和资源更可控可预测。

实际例子:
Alluxio的目的就是想要让计算层和存储层可以再次轻装上阵,让它们独立的优化和发展自己,而不用担心破坏两者之间的依赖。具体说来,Alluxio提供一层文件系统的抽象给计算层。这层抽象之上的计算只需要和Alluxio交互来访问数据;而这层抽象之下可以同时对接多个不同的持久化存储(比如一个S3加上一个HDFS部署),而这层抽象本身又是由部署在靠近计算的内存级Alluxio存储系统来实现。一个典型的场景比如在百度,Spark不在需要关心数据是否是在本机房还是远程的数据中心,它只需要通过Alluxio中读写数据,而Alluxio可以聪明的帮助应用在需要时把数据同步到远端。

百度应用alluxio提升性能的主要原因:经过更深层次的发掘,我们发现了问题所在。由于数据分散分布在多个数据中心,有很大的可能是:数据的查询需要到达远程数据中心以提取数据——这应该是在用户运行查询时遇到延迟的最大原因。

这个可以参考文章:为了应对数据大爆炸 百度投向了这个开源新项目

我想alluxio之所以作为acceleration layer来说不够称职,其原因可能就是并没有去为MapReduce和Spark去实现自己的alluxio native acceleration layer. 说到希望给计算JOB做这种即插即用的内存加速,可以考虑使用ignite。 我也写了相关文章比较了ignite和alluxio,可以关注下。

再做个友情提醒: 使用alluxio需要仔细看看上述场景是否符合你们的使用场景。想和MR和Spark集成,利用内存来加速job处理的,不妨考虑下Apache ignite,我最近会玩玩试试效果