1.背景
Spark平台以分布式内存计算的模式达到更高的计算性能,然而,分布式内存计算的模式也是一柄双刃剑,在提高性能的同时不得不面对分布式数据存储所产生的问题,具体问题主要有以下几个:
1) 当两个Spark作业需要共享数据时,必须通过写磁盘操作。比如:作业1要先把生成的数据写入HDFS,然后作业2再从HDFS把数据读出来。在此,磁盘的读写可能造成性能瓶颈。
2) 由于Spark会利用自身的JVM对数据进行缓存,当Spark程序崩溃时,JVM进程退出,所缓存数据也随之丢失,因此在工作重启时又需要从HDFS把数据再次读出。
3) 当两个Spark作业需操作相同的数据时,每个作业的JVM都需要缓存一份数据,不但造成资源浪费,也极易引发频繁的垃圾收集,造成性能的降低。
仔细分析这些问题后,可以确认问题的根源来自于数据存储,由于计算平台尝试自行进行存储管理,以至于Spark不能专注于计算本身,造成整体执行效率的降低。所以,需要一个专门的分布式的内存文件系统,来减轻Spark内存压力的同时赋予了Spark内存快速大量数据读写的能力,把存储与数据读写的功能从Spark中分离,使得Spark更专注在计算的本身,以求通过更细的分工达到更高的执行效率。
2.调研
业界特别受欢迎的分布式内存文件系统—Tackyon,在经过一系列环境部署和配置调整,使用spark-sql进行测试,速度没有提升。
而tachyon也是Spark 默认的 off-heap 内存方案,因此,Spark 的安装包已经 build-in 了 Tachyon 的 Client。配置spark进行测试,速度有显著提升,但是功能上有限制。
于此同时,又调研了另外一个内存分布式文件系统 —Ignite文件系统(IGFS),IGFS提供了和Hadoop HDFS类似的功能,但是只在内存中。事实上,除了他自己的API,IGFS还实现了Hadoop的文件系统API,可以透明地加入Hadoop或者Spark的运行环境。
IGFS将每个文件的数据拆分成独立的数据块然后将他们保存进一个分布式内存缓存中。然而,与Hadoop HDFS不同,IGFS不需要一个name节点,它通过一个哈希函数自动确定文件数据的位置。
IGFS可以独立部署,也可以部署在HDFS之上,这时他成为了一个存储于HDFS中的文件的透明缓存层。
3.测试结果
1)ignite测试
使用专车测试用例,在不同数据量和spark配置环境下执行的时间进行对比,外加count(*)语句,执行结果如下图所示:
根据测试结果,ignite在存储与计算在同一个集群的情况下,计算速度并没有显著提升。考虑到实际应用中,跨集群进行计算的业务方数据量都太大,不适用于内存存储。
2)spark内建的tachyon client测试
4.将表结构改为非map结构
观察应用程序,占用大量时间的语句是查询map结构表中的某一列,尝试将那一列提取出来,新建一个非map结构的表,再进行同样的查询,速度显著提升: