java使用spark本地模式为什么性能低下

java使用spark 本地模式,性能很差甚至不如纯java代码是什么原因

    SparkConf conf = new SparkConf()
            .setAppName("MyApp")
            .set("spark.executor.memory", "8g")
            .set("spark.driver.memory", "8g")
            .setMaster("local[*]");

    JavaSparkContext sc = new JavaSparkContext(conf);

    List<Integer> data=new ArrayList<>();
    for (int i = 0; i < 20000000; i++) {
        data.add(i);
    }
    System.out.println("开始");
    long startTime = System.currentTimeMillis();
    /*
    for (int i = 0; i < 20000000; i++) {
       int x=i*i;
    }
    */
    JavaRDD<Integer> rdd = sc.parallelize(data).map(x -> x * x);
    System.out.println(rdd.count());
    System.out.println("结束");
    long endTime = System.currentTimeMillis(); // 获取方法结束时间
    long executionTimeMillis = endTime - startTime; // 计算方法执行时间(毫秒)
    double executionTimeSeconds = executionTimeMillis / 1000.0; // 转换为秒
    System.out.println(executionTimeSeconds);

问题描述:最开始以为是spark的内存给的太少,通过set修改了内存大小,但是毫无影响,又做了对比测试,可以看到我代码中被注释掉的部分实现了同样的功能,都是求2次方。纯java输出的用时是0.02,而spark却用了20秒,而且通过任务管理器也发现spark代码部分在运行时CPU和内存占用都不高

版本说明:使用的是spark3.4.0的

<dependencies>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.12</artifactId>
        <version>3.4.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-sql_2.12</artifactId>
        <version>3.4.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-mllib_2.12</artifactId>
        <version>3.4.0</version>
    </dependency>
</dependencies>

那是因为你是小数据量的计算,spark使用的是内存和分布式计算,java的计算是基于单机的,在处理大数据量的计算spark的优势才能凸显
spark哦那个了很多高级的数据结构,这些结构在处理大规模数据上做了优化,并且采用的了高效的数据缓存和数据分区技术,在大规模数据上能进行高效的内存计算和并行计算,总而言之就是spark是处理大规模数据的

【以下回答由 GPT 生成】

对于该问题,可能存在以下几个原因导致Java使用Spark本地模式性能较低:

  1. 数据处理量过大:根据代码中的循环添加数据的代码,你使用了2000万个数据进行计算,这可能超出了本地模式下Spark的处理能力范围。对于本地模式来说,推荐的数据量范围通常是百万级别。

  2. 数据分区过多:在本地模式下,Spark默认会将数据分成与CPU核心数量相等的分区,每个分区都会作为一个任务并行执行。如果分区过多会导致任务之间频繁切换上下文,导致性能下降。你可以通过设置spark.default.parallelism参数来控制分区数量。可以根据你的CPU核心数量和数据规模合理调整该参数,通常设置为CPU核心数的两倍。

  3. Executor和Driver内存设置不合理:你通过代码设置了Executor和Driver的内存为8GB,可能是这个问题的根本原因之一。根据你的代码和数据规模,8GB的内存可能过大,导致资源分配不均,引发性能问题。你可以尝试减小Executor和Driver内存的设置,例如将其设置为2GB,然后观察性能是否有所改善。

针对上述问题,你可以尝试以下优化方案来提高性能:

  1. 减少数据处理量:可以试着减少数据量,例如通过修改循环添加数据的代码,将2000万个数据减少为几百万个。

  2. 调整分区数量:根据你的CPU核心数量和数据规模,合理设置spark.default.parallelism参数,通常设置为CPU核心数的两倍。

  3. 调整Executor和Driver内存设置:根据你的数据规模和机器配置,合理分配Executor和Driver的内存大小,避免内存过大导致资源浪费或者过小导致性能下降。

最后,根据你给出的代码和数据规模来看,如果上述优化方案没有明显效果,可能需要考虑将任务分布到集群上运行,以获得更好的性能。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^