繁体   English   中英

Apache Spark连接操作的弱扩展性差

[英]Poor weak scaling of Apache Spark join operation

我在Apache Spark上运行“join”操作,看到没有弱的可伸缩性。 如果有人能够解释这一点,将不胜感激。

我创建两个数据帧(“a”,“b”)和(“a”,“c”)并通过第一列连接数据帧。 我为“一对一”连接生成数据帧值。 另外,我使用相同的分区来避免随机播放。

数据帧中的行数 - 1024 * 1024 * 16 * cores_total(cores_total - 启动程序的核心总数)。 列“a”由随机Int值组成,“b”列的所有值等于1,“c”列的所有值等于2。

从理论上讲,随着数据大小和核心数量增加64倍,执行时间应该保持不变,但执行时间会略有增长。 我获得了以下执行时间:

在此输入图像描述

Apache Spark版本 - 2.1.0。 我们使用8个集群节点,配备1 Gbit以太网,每个节点有2个Intel Xeon E5-2630,64 GB RAM。

/* join perf */
import scala.io.Source
import scala.math._
import org.apache.spark._
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf
import scala.util.control.Breaks._
import scala.collection.mutable._
import org.apache.spark.rdd._
import org.apache.spark.sql._
import scala.util.Random
import org.apache.spark.util.SizeEstimator
import org.apache.spark.HashPartitioner

object joinPerf {

    def get_array(n: Int): Array[Int] = {
        var res = Array[Int]()
        for (x <- 1 to n) {
            res :+= Random.nextInt
        }

        return res
    }

    def main(args: Array[String]) {
        val start_time = System.nanoTime
        val conf = new SparkConf().setAppName("joinPerf")
        val sc = new SparkContext(conf)
        val cores_total = sc.getConf.get("spark.cores.max").toInt
        val partitions_total = sc.getConf.get("spark.default.parallelism").toInt
        val sqlContext = new org.apache.spark.sql.SQLContext(sc)
        import sqlContext._
        import sqlContext.implicits._
        println("start")
        val elems_total = 1024 * 1024 * 16 * cores_total
        val start_cnt = 1024 * 1024
        Random.setSeed(785354)

        var vals = Vector[Int]()
        for (x <- 1 to start_cnt) {
            vals :+= Random.nextInt
        }

        var test_rdd = sc.parallelize(vals)
        println(test_rdd.count)
        test_rdd = test_rdd.flatMap(x => get_array(elems_total / start_cnt)).distinct

        println("test_rdd count = " + test_rdd.count)
        println("partitions count = " + test_rdd.getNumPartitions)

        var test_rdd1 = test_rdd.map(x => (x, 1)).toDF("a", "b").repartition(partitions_total, $"a").cache
        var test_rdd2 = test_rdd.map(x => (x, 2)).toDF("a", "c").repartition(partitions_total, $"a").cache

        println("test_rdd1 count = " + test_rdd1.count)
        println("test_rdd2 count = " + test_rdd2.count)

        var start_test_time = System.nanoTime
        var test_res = test_rdd1.join(test_rdd2, test_rdd1("a") === test_rdd2("a"))
        println(test_res.count)
        print("join time = ")
        println((System.nanoTime - start_test_time) / 1e9d + " sec. ")

        print("all time = ")
        println((System.nanoTime - start_time) / 1e9d + " sec. ")
        sc.stop()
    }
}

配置参数:

spark.serializer                 org.apache.spark.serializer.KryoSerializer
spark.kryoserializer.buffer.max  1024
spark.kryo.unsafe                true
spark.kryo.referenceTracking     false
spark.driver.memory              22g
spark.executor.memory            22g
spark.driver.maxResultSize       22g
spark.rpc.message.maxSize        2047
spark.memory.fraction            0.8
spark.memory.storageFraction     0.5
spark.executor.extraJavaOptions  "-XX:+UseParallelGC"

每个核心的分区 - 4。

启动程序示例:

./bin/spark-submit --class "joinPerf" --conf spark.executor.cores=8 --conf spark.cores.max=64 --conf spark.default.parallelism=256 ./joinPerf.jar

从理论上讲,随着数据大小和核心数量增加64倍,执行时间应保持不变,但执行时间略有增长

它不应该。 虽然可以预期线性可扩展性,假设没有IO瓶颈,但在对均匀分布的数据执行严格的本地操作时,当转换需要数据交换( RDD shuffles, Dataset Exchange )时,情况就不再如此。 在广泛的转换中, joins属于最昂贵的类别(下一个类别的groupByKey操作),因为它们具有非还原性质,并且使用大型本地支持集合。

Shuffles不仅具有高于线性的复杂度(对于基于排序的方法至少为O(N log N )),而且还可以引起数据的非均匀分布,并且需要大量的磁盘和网络IO。

在代码的情况下,这会更加严重,这RDDs数据RDDs两次 - 一次重新分区RDDs ,一次join Datasets (用于RDDs HashPartitionerDataset分区不兼容)。

最后增加簇大小,有其自身的性能影响,与增加的通信和同步开销以及减少的数据局部性有关。

总的来说,您很少会看到真正的线性可扩展性,即使您这样做,也可以预期斜率<1。

另外,在使用Datasets时,我不会依赖cache count习惯。 它可能不可靠

另请参见Spark:扩展核心数时的性能数不一致

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM