小文件

时间:2016-12-14 09:55:02

标签: java hadoop apache-spark hadoop-partitioning

我是Spark的新手,我正在使用一个主要用于解除对象目的的群集。我有一个100MB的文件,每行都由一些算法处理,这是一个非常繁重和漫长的处理。

我想使用10节点集群并并行化处理。我知道块大小超过100MB,我试图重新分区textFile。如果我理解的话,这个repartition方法会增加分区的数量:

JavaRDD<String> input = sc.textFile(args[0]);
input.repartition(10);

问题在于,当我部署到群集时,只有一个节点正在有效处理。如何管理并行处理文件?

更新1:这是我的spark-submit命令:

/usr/bin/spark-submit --master yarn --class mypackage.myclass --jars 
myjar.jar 
gs://mybucket/input.txt outfile

更新2:分区后,基本上有2个操作:

JavaPairRDD<String, String> int_input = mappingToPair(input);
JavaPairRDD<String, String> output = mappingValues(int_input, option);
output.saveAsTextFile("hdfs://...");

其中mappingToPair(...)

public JavaPairRDD<String, String> mappingToPair(JavaRDD<String> input){
        return input.mapToPair(new PairFunction<String, String, String>() {
            public Tuple2<String, String> call(String line) {
                String[] arrayList = line.split("\t", 2);
                return new Tuple2(arrayList[0], arrayList[1]);
            }
        });
    }

mappingValues(...)是以下类型的方法:

public JavaPairRDD<String,String> mappingValues(JavaPairRDD<String,String> rdd, final String option){
        return rdd.mapValues(
                new Function<String, String>() {
                    // here the algo processing takes place...
                }
        )
}

1 个答案:

答案 0 :(得分:2)

这里可能存在多个问题:

  1. 该文件只有一个块大。使用多个执行程序读取此函数根本没用,因为HDFS节点可以全速运行一个节点,或者速度减半(加上开销)的两个节点等等。执行程序计数变得有用(对于读取步骤)有多个块分散在不同的HDFS节点上。
  2. 您也可能以不可拆分的压缩格式存储文件,因此输入步骤只能用一个执行程序读取它,即使它是块大小的100倍。
  3. 您不会将repartition(10)来电链接到您的流程中,因此根本无效。如果您将此行替换为input.repartition(10);input = input.repartition(10);将使用它,并且应该将RDD拆分为多个,然后再继续下一步。
  4. 请注意,重新分区可以使您的流程更长,因为必须将数据拆分并传输到其他计算机,这可能很容易受到慢速网络的瓶颈。

    使用客户端部署模式时尤其如此。这意味着第一个执行程序(驱动程序)是您提交的本地Spark实例。因此,它首先将所有数据从集群下载到驱动程序,然后在分区后将其上传回其他YARN节点。

    我可以继续讨论这个问题,但我想说的主要问题是:如果你的算法很简单,那么进程甚至可以在一个执行器上运行得更快,而不是分区,传输,然后运行所有执行者并行算法。