Spark本地模式与HDFS性能比较

5
我有一个Spark集群和一个同样的机器上的Hdfs。 我已经将单个文本文件(大小约为3GB)复制到每个机器的本地文件系统和hdfs分布式文件系统中。
我有一个简单的word count pyspark程序。
如果我从本地文件系统提交读取文件的程序,它需要大约33秒时间。 如果我从hdfs提交读取文件的程序,它需要大约46秒时间。
为什么? 我预期结果恰恰相反。
在sgvd的请求之后添加:
16个从节点1个主节点
Spark独立模式,没有特殊设置(副本因子3)
版本1.5.2
import sys
sys.path.insert(0, '/usr/local/spark/python/')
sys.path.insert(0, '/usr/local/spark/python/lib/py4j-0.8.2.1-src.zip')
import os
os.environ['SPARK_HOME']='/usr/local/spark'
os.environ['JAVA_HOME']='/usr/local/java'
from pyspark import SparkContext
#conf = pyspark.SparkConf().set<conf settings>


if sys.argv[1] == 'local':
    print 'Esecuzine in modalita local file'
    sc = SparkContext('spark://192.168.2.11:7077','Test Local file')
    rdd = sc.textFile('/root/test2')
else:
    print 'Esecuzine in modalita hdfs'
    sc = SparkContext('spark://192.168.2.11:7077','Test HDFS file')
    rdd = sc.textFile('hdfs://192.168.2.11:9000/data/test2')


rdd1 = rdd.flatMap(lambda x: x.split(' ')).map(lambda x:(x,1)).reduceByKey(lambda x,y:x+y)
topFive = rdd1.takeOrdered(5,key=lambda x: -x[1])
print topFive

这取决于很多因素。你的集群有多大?你使用什么集群管理器?有任何自定义设置吗?Spark版本是多少?你能展示一下你的代码吗? - sgvd
我会在问题空间中回答。 - arj
3个回答

1
“执行程序、驱动程序和RDD(就溢出和存储级别而言)具体有哪些参数?”
从Spark documentation得知。
性能影响
“洗牌”是昂贵的操作,因为它涉及磁盘I/O、数据串行化和网络I/O。为了组织“洗牌”数据,Spark生成一组任务——将任务组织成Map来处理数据,再生成一组Reduce任务来聚合数据。这个术语来自MapReduce,并不直接相关于Spark的映射和归约操作。
某些“洗牌”操作可能会消耗大量堆内存,因为它们使用在内存中的数据结构来组织记录,在传输之前或之后。具体而言,“reduceByKey”和“aggregateByKey”在映射端创建这些数据结构,“ByKey”操作在减少一侧生成这些数据结构。当数据不适合内存时,Spark会将这些表溢出到磁盘上,导致额外的磁盘I/O和增加的垃圾收集开销。
我对Spark Job与Map & Reduce任务的内存/CPU核心限制感兴趣。
从Hadoop基准测试的关键参数:
yarn.nodemanager.resource.cpu-vcores
mapreduce.map.cpu.vcores
mapreduce.reduce.cpu.vcores
mapreduce.map.memory.mb
mapreduce.reduce.memory.mb
mapreduce.reduce.shuffle.memory.limit.percent

关键参数,用于将SPARK参数与Hadoop进行等效性基准测试。

spark.driver.memory
spark.driver.cores
spark.executor.memory
spark.executor.cores
spark.memory.fraction

这些只是一些关键参数。详细的设置请查看SPARKMap Reduce
如果没有正确的参数集,我们无法比较两种不同技术的作业性能。

1
这有点违反直觉,但由于复制因子为3且您有16个节点,每个节点平均存储HDFS中20%的数据。因此,平均约需要6个工作节点才能在没有任何网络传输的情况下读取整个文件。
如果记录运行时间与工作节点数量,您应该会注意到,在大约6个节点之后,从本地FS和从HDFS读取之间没有区别。
上述计算可以使用变量进行,例如x = worker nodes的数量y = replication factor,但是您可以轻松看出,由于从本地FS读取要求文件存在于所有节点上,因此您最终会得到x = y,并且在使用floor(x / y)个节点之后不会有任何区别。这正是您所观察到的,一开始似乎有些违反直觉。您会在生产中使用100%的复制因子吗?

更改副本因子但不更改工作节点数量不会改变时间。 使用6个工作节点,副本因子为3和6个数据节点的时间增加到1分30秒。 - arj
你是怎么配置的?你重启了你的集群吗?你在描述中说你有16个从节点。 - Radu Ionescu
修改重复因子尝试:我已将文件的重复因子从2更改为16。程序提交给16个从节点。 节点数量尝试:我已重新配置整个集群(Spark和Hadoop),仅使用6个节点。 - arj

0

这是因为数据的分布方式,单个文档并不是一个好的选择,有几种更好的替代方案,比如parquet,如果你使用它,你会注意到性能会明显提高,这是因为文件的分区方式,使得你的Apache Spark集群可以并行读取这些部分,从而提高性能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接