想象中的问题
我的穷人的概念解决方案 使用SparkSQL& Databricks spark-csv
$ ./spark-shell --packages com.databricks:spark-csv_2.10:1.4.0
val dfBigLog = sqlContext.read
.format("com.databricks.spark.csv")
.option("header", "true")
.load("/media/username/myUSBdrive/bogusBigLog1TB.log")
dfBigLog.select("Country")
.groupBy("Country")
.agg(count($"Country") as "CountryCount")
.orderBy($"CountryCount".desc).show
问题1:Spark如何并行处理?
我认为上述解决方案的大部分执行时间(99%?)是将USB驱动器中的1TB文件读入Spark群集。从USB驱动器读取文件是不可并行化的。但是在阅读完整个文件之后,Spark会做些什么来并行处理?
用于创建DataFrame的节点数量是多少? (也许只有一个?)
用于groupBy
&的节点数count
?我们假设有100多个国家(但Spark还不知道)。 Spark如何分区以在20个节点上分发100多个国家/地区值?
问题2:如何使Spark应用程序尽可能快? 我想改进的方面是并行读取1TB文件。
使用Snappy压缩将CSV文件转换为Parquet文件格式+。我们假设这可以提前完成。
复制HDFS上的Parquet文件。让我们假设Spark集群在同一个Hadoop集群中,并且数据节点与20个节点Spark集群无关。
将Spark应用程序更改为从HDFS读取。我想Spark现在会使用几个节点来读取文件,因为Parquet是可拆分的。
让我们假设Snappy压缩的Parquet文件小10倍,大小= 100GB,HDFS块大小= 128 MB。总计782个HDFS块。
但是,Spark如何设法使用所有20个节点来创建DataFrame和处理(groupBy
和count
)? Spark每次都使用所有节点吗?
答案 0 :(得分:4)
问题1:Spark如何并行处理(读取a 来自USB驱动器的文件)?
无法使用此方案。
Spark依赖于hadoop兼容的文件系统来读取文件。安装USB驱动器时,只能从本地主机访问它。试图执行
.load("/media/username/myUSBdrive/bogusBigLog1TB.log")
将在群集配置中失败,因为群集中的执行程序将无法访问该本地路径。
可以在本地模式(master=local[*]
)中使用Spark读取文件,在这种情况下,您只有1个主机,因此其他问题将不适用。
问题2:如何使Spark应用程序尽可能快?
分而治之。
问题中概述的策略是好的。使用Parquet将允许Spark对数据和.select("Country")
列进行投影,从而进一步减少了摄取所需的数据量,从而加快了速度。
Spark中并行性的基石是分区。同样,当我们从文件中读取时,Spark依赖于Hadoop文件系统。从HDFS读取时,分区将由HDFS上文件的分割决定。这些分裂将在执行者之间平均分配。这就是Spark最初将这项工作分配给所有可用的工作执行者的工作。
我对Catalist的优化并不十分熟悉,但我认为我可以假设.groupBy("Country").agg(count($"Country")
会变得类似于:rdd.map(country => (country,1)).reduceByKey(_+_)
映射操作不会影响分区,因此可以在站点上应用。
reduceByKey将首先在本地应用于每个分区,部分结果将在驱动程序上进行组合。因此,大多数计数都发生在集群中,并且将其添加为集中。
答案 1 :(得分:3)
从USB驱动器读取文件不可并行化。
USB驱动器或任何其他数据源适用相同的规则。可以从驱动程序访问任何一个源,并且可以并行访问所有工作者计算机和数据(直到源限制),或者根本没有访问数据。
用于创建DataFrame的节点数量是多少? (也许只有一个?)
假设可以从所有计算机访问文件,它取决于配置。对于初学者,你应该看看分割大小。
GroupBy&算?
再一次取决于配置。