Spark如何并行处理1TB文件?

时间:2016-04-09 20:38:34

标签: apache-spark dataframe parallel-processing apache-spark-sql

想象中的问题

  • 一个巨大的CSV日志文件,让我们说1 TB大小,文件位于USB驱动器上
  • 该日志包含世界各地用户的活动日志,我们假设该行包含50列,其中有国家。
  • 我们希望每个国家/地区的行数按降序排列。
  • 假设Spark集群有足够的RAM节点来处理内存中的整个1TB(20个节点,4个核心CPU,每个节点有64GB RAM)

我的穷人的概念解决方案 使用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和处理(groupBycount)? Spark每次都使用所有节点吗?

2 个答案:

答案 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&算?

再一次取决于配置。