Java 火花性能调节

Java 火花性能调节,java,scala,hadoop,apache-spark,hdfs,Java,Scala,Hadoop,Apache Spark,Hdfs,祝你节日快乐 我有一个由5台机器组成的集群(1台主机器和4台从机器),其中安装了hadoop、Thread和spark。我正在spark上测试我的应用程序的性能 详情如下 我有一个85 Mb的csv文件,包含1000万条记录,每个数据节点(4个数据节点)上的块大小为128 Mb,复制值为3 我上传了两次文件,块分布如下 数据节点1-1块 Datanode2-2块 数据节点3-2个块 Datanode4-1块 当我在Spark上提交申请(BayesNet算法)时,大约需要53分钟才能完成 我从ha

祝你节日快乐

我有一个由5台机器组成的集群(1台主机器和4台从机器),其中安装了hadoop、Thread和spark。我正在spark上测试我的应用程序的性能

详情如下

我有一个85 Mb的csv文件,包含1000万条记录,每个数据节点(4个数据节点)上的块大小为128 Mb,复制值为3

我上传了两次文件,块分布如下

  • 数据节点1-1块
  • Datanode2-2块
  • 数据节点3-2个块
  • Datanode4-1块
  • 当我在Spark上提交申请(BayesNet算法)时,大约需要53分钟才能完成

    我从hadoop和spark集群中移除了一台机器(现在我的集群是1个主集群和3个从集群),现在我的hdfs块分布如下

  • Datanode1-2块
  • Datanode2-2块
  • 数据节点3-2个块
  • 现在,我在每个datanode上有2个块,当我在Spark中提交申请时,大约需要38分钟

  • 数据节点1-3块
  • Datanode2-3块
  • 我再次移除了hadoop和spark集群中的一台机器(现在我的集群是1个主节点和2个从节点),现在datanodes将分别有3个块

    当我提交申请时,大约需要38分钟

    我们可以注意到,向集群添加一台机器实际上增加了执行时间

    所以我的问题是

  • 从理论上讲,向现有集群添加一台新机器应该可以提高性能,为什么在我的例子中不是这样呢
  • 我是否缺少任何配置
  • 这是因为Spark中的数据局部性吗
  • 或者这是由于hdfs数据倾斜造成的
  • 有没有关于如何提高性能或执行速度的建议
  • 或者这是预期的行为
  • 注意:我将Spark 1.6.2与hadoop 2.6.0一起使用,我使用的是Spark独立资源管理器,而不是Thread。 每台机器都是ubuntu,具有16 GB ram和4个内核

    我将驱动程序和工作程序内存配置为6GB,每个节点只有一个工作程序实例

    代码:- 首先,我使用JavaSparkContext加载文件

    private JavaSparkContext javaSparkContext;
    
    SparkConf sparkConf = new SparkConf().setMaster("spark://masterIp:7077");
    javaSparkContext=new JavaSparkContext(sparkConf);
    
    JavaRDD<String> rawInput = javaSparkContext.textFile("hdfs://namenodeIp/tmp/*.csv");
    JavaRDD<Instance> instances = rawInput.map(new TransformStringToRDD(attributes, false));
    

    在上面的代码中,
    SimulatedAnnealing.learnNetwork
    (出现在上面的
    learnBySimulatedAnnealing
    函数中)是算法的主要入口点,该算法在
    SimulatedAnnealing.scala
    中实现,其他必需的函数在
    bayesianetalgorithm.scala
    中实现,随着代码行越来越多,我提供了指向其他所需代码所在位置的链接。

    理论上,向现有集群添加新机器应该会提高性能-否。如果且仅当增加分发的成本可以通过提高IO吞吐量和提高并行性来分摊时,它可能会提高性能。您还没有显示您的代码,但通常使用85MB Spark根本没有意义。@zero323我已经上传了两次该文件,所以基本上我是在170MB的文件上运行Spark。那么,您建议的最小文件大小是多少?我将生成该文件并测试Spark性能。在所有条件相同的情况下,每个分区的数据量介于64-256MB之间是一个好主意,分区数大于执行器线程总数。否则,很有可能您将观察到的唯一一件事就是安排延迟和洗牌。@zero323好的,我将尝试一下,明天之前让您知道结果。我正在通过
    SparkLauncher
    启动spark作业,我的项目中有很多类,如果您愿意,我可以展示我的算法的训练函数的代码。好吧,它可以提供一些额外的见解,但如果您没有观察到严重的倾斜或某些数据局部性问题,那么我认为这里不会有更多的内容。
    @Override
        public DiscreteBayesNetwork learnBySimulatedAnnealing(double maxNumberOfParents, double prior, boolean isCausal, int classIndex,
                double initTemperature, int maxIterations, double temperatureStep) {
    
            JavaRDD<org.apache.spark.mllib.regression.LabeledPoint> rddLabeledPoints = getLabeledPointRddFromJavaRddInstances(instances,
                    classIndex);
            List<Map<String, List<String>>> format = new ArrayList<>(attributes.size());
            for (int i = 0; i < attributes.size(); i++) {
                Map<String, List<String>> attrNameAndValues = new HashMap<>();
                Attribute attr = attributes.get(i);
                List<Value> allNominalVals = attr.getAllNominalValues();
                List<String> attrValNames = new ArrayList<>();
                for (int j = 0; j < allNominalVals.size(); j++) {
                    attrValNames.add(allNominalVals.get(j).getName());
                }
                attrNameAndValues.put(attr.getName(), attrValNames);
                format.add(attrNameAndValues);
            }
            BayesianBeliefNetwork nw = SimulatedAnnealing.learnNetwork(rddLabeledPoints, maxNumberOfParents, prior, false, classIndex, format,
                    initTemperature, maxIterations, temperatureStep, ScoringType.ENTROPY());
            System.out.println(nw.treeDescription(format));
    
            JavaBayesianBeliefNetwork network = BayesianBeliefNetwork.getJavaBayesianBeliefNetwork(nw);
            DiscreteBayesNetwork discreteBayesNetwork = null;
            discreteBayesNetwork = ConversionUtilities.convertJavaBayesianBeliefNetworkToDiscreteBayesNetwork(network, attributes, format,
                    (int) maxNumberOfParents, prior, isCausal, classIndex);
            return discreteBayesNetwork;
        }
    
    /**Parses data from JavaRDD<Instance> to RDD<org.apache.spark.mllib.linalg.Vector>.
     * @param JavaRDD<Instance>
     * @return RDD<org.apache.spark.mllib.linalg.Vector>
     */
    public static JavaRDD<org.apache.spark.mllib.regression.LabeledPoint> getLabeledPointRddFromJavaRddInstances(
            JavaRDD<Instance> rddInstances, int classIndex){
    
        // Load and parse data
        JavaRDD<org.apache.spark.mllib.regression.LabeledPoint> parsedData = 
                rddInstances.map(new Function<Instance, org.apache.spark.mllib.regression.LabeledPoint>() {
                    public org.apache.spark.mllib.regression.LabeledPoint call(Instance inst) {
                        double[] values = new double[inst.getValues().size() -1];
                        double label = Double.NaN;
                        for (int numValue = 0; numValue < inst.getValues().size(); numValue++) {
                            double val = inst.getValue(numValue).getNumericValueAsDouble();
                            if(numValue != classIndex){
                                values[numValue] = val;
                            }
                            else{
                                label = val;
                            }
                        }
    
                        Vector featureVals = Vectors.dense(values);
                        LabeledPoint lb = new LabeledPoint(label, featureVals);
                        return lb;
                    }
                });
        parsedData.cache();
        return parsedData;
    }