Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala “是怎么回事?”;交换hashpartitioning";星星之火_Scala_Apache Spark_Apache Spark Sql_Partition_Partitioner - Fatal编程技术网

Scala “是怎么回事?”;交换hashpartitioning";星星之火

Scala “是怎么回事?”;交换hashpartitioning";星星之火,scala,apache-spark,apache-spark-sql,partition,partitioner,Scala,Apache Spark,Apache Spark Sql,Partition,Partitioner,我有一个数据集,我想将其写入拼花地板文件中,以便在Spark上请求这些文件,包括谓词下推 目前,我使用按列和分区数重新分区来将数据移动到特定分区。该列标识相应的分区(从0到(固定的)n)。结果是scala/spark生成了一个意外的结果,并创建了更少的分区(其中一些是空的)。也许是散列冲突 为了解决这个问题,我试图找出原因并找到解决办法。我找到了一种解决方法,将数据帧转换为rdd,并将partitionBy与HashPartitioner一起使用。让我吃惊的是:我得到了预期的结果。但将数据帧转换

我有一个数据集,我想将其写入拼花地板文件中,以便在Spark上请求这些文件,包括谓词下推

目前,我使用按列和分区数重新分区来将数据移动到特定分区。该列标识相应的分区(从0到(固定的)n)。结果是scala/spark生成了一个意外的结果,并创建了更少的分区(其中一些是空的)。也许是散列冲突

为了解决这个问题,我试图找出原因并找到解决办法。我找到了一种解决方法,将数据帧转换为rdd,并将partitionBy与HashPartitioner一起使用。让我吃惊的是:我得到了预期的结果。但将数据帧转换为RDD对我来说不是一个解决方案,因为它需要太多的资源

我已经在上测试了这个环境

  • cloudera CDH 5.9.3上的SPARK 2.0

  • emr-5.17.0上的SPARK 2.3.1

这是我的输出测试。请使用Spark shell运行它们

    scala> import org.apache.spark.HashPartitioner
    import org.apache.spark.HashPartitioner

    scala> val mydataindex = Array(0,1, 2, 3,4)
    mydataindex: Array[Int] = Array(0, 1, 2, 3, 4)

    scala> val mydata = sc.parallelize(for {
         |  x <- mydataindex
         |  y <- Array(123,456,789)
         | } yield (x, y), 100)
    mydata: org.apache.spark.rdd.RDD[(Int, Int)] = ParallelCollectionRDD[0] at parallelize at <console>:27

    scala> val rddMyData = mydata.partitionBy(new HashPartitioner(5))
    rddMyData: org.apache.spark.rdd.RDD[(Int, Int)] = ShuffledRDD[1] at partitionBy at <console>:26

    scala> val rddMyDataPartitions =   rddMyData.mapPartitionsWithIndex{
         |                 (index, iterator) => {
         |                    val myList = iterator.toList
         |                    myList.map(x => x + " -> " + index).iterator
         |                 }
         |              }
    rddMyDataPartitions: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[2] at mapPartitionsWithIndex at <console>:26

    scala>
         | // this is expected:

    scala> rddMyDataPartitions.take(100)
    res1: Array[String] = Array((0,123) -> 0, (0,456) -> 0, (0,789) -> 0, (1,123) -> 1, (1,456) -> 1, (1,789) -> 1, (2,123) -> 2, (2,456) -> 2, (2,789) -> 2, (3,456) -> 3, (3,789) -> 3, (3,123) -> 3, (4,789) -> 4, (4,123) -> 4, (4,456) -> 4)

    scala> val dfMyData = mydata.toDF()
    dfMyData: org.apache.spark.sql.DataFrame = [_1: int, _2: int]

    scala> val dfMyDataRepartitioned = dfMyData.repartition(5,col("_1"))
    dfMyDataRepartitioned: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = [_1: int, _2: int]

    scala> dfMyDataRepartitioned.explain(false)
    == Physical Plan ==
    Exchange hashpartitioning(_1#3, 5)
    +- *(1) SerializeFromObject [assertnotnull(input[0, scala.Tuple2, true])._1 AS _1#3, assertnotnull(input[0, scala.Tuple2, true])._2 AS _2#4]
       +- Scan ExternalRDDScan[obj#2]

    scala> val dfMyDataRepartitionedPartition  = dfMyDataRepartitioned.withColumn("partition_id", spark_partition_id()).groupBy("partition_id").count()
    dfMyDataRepartitionedPartition: org.apache.spark.sql.DataFrame = [partition_id: int, count: bigint]

    scala> // this is unexpected, because 1 partition has more indexes

    scala> dfMyDataRepartitionedPartition.show()
    +------------+-----+
    |partition_id|count|
    +------------+-----+
    |           1|    6|
    |           3|    3|
    |           4|    3|
    |           2|    3|
    +------------+-----+
scala>import org.apache.spark.HashPartitioner
导入org.apache.spark.HashPartitioner
scala>val mydataindex=Array(0,1,2,3,4)
mydataindex:Array[Int]=数组(0,1,2,3,4)
scala>val mydata=sc.parallelize(用于{
|x val rddMyDataPartitions=rddMyData.mapPartitionsWithIndex{
|(索引,迭代器)=>{
|val myList=iterator.toList
|myList.map(x=>x+“->”+索引)。迭代器
|                 }
|              }
rddMyDataPartitions:org.apache.spark.rdd.rdd[String]=MapPartitionsRDD[2]位于MapPartitionsSwithindex的位置:26
斯卡拉>
|//这是预期的:
scala>rddMyDataPartitions.take(100)
res1:Array[String]=Array((0123)->0,(0456)->0,(0789)->0,(1123)->1,(1456)->1,(1789)->1,(2123)->2,(2456)->2,(2789)->2,(3456)->3,(3789)->3,(3123)->3,(4789)->4,(4123)->4,(4456)->4)
scala>val-dfMyData=mydata.toDF()
dfMyData:org.apache.spark.sql.DataFrame=[\u 1:int,\u 2:int]
scala>val DfMyDataRepartited=dfMyData.repartition(5,col(“_1”))
dfmydatarepartated:org.apache.spark.sql.Dataset[org.apache.spark.sql.Row]=[\u1:int,\u2:int]
scala>DfMyDataRepartited.explain(false)
==实际计划==
交换哈希分区(_1#3,5)
+-*(1)SerializeFromObject[assertnotnull(输入[0,scala.Tuple2,true])。_1为_1#3,assertnotnull(输入[0,scala.Tuple2,true])。_2为#4]
+-扫描外部RDDSCAN[obj#2]
scala>val-dfMyDataRepartitionedPartition=dfmydatarepartited.withColumn(“partition\u id”,spark\u partition\u id()).groupBy(“partition\u id”).count()
dfMyDataRepartitionedPartition:org.apache.spark.sql.DataFrame=[partition\u id:int,count:bigint]
scala>//这是意外的,因为1分区有更多索引
scala>dfMyDataRepartitionedPartition.show()
+------------+-----+
|分区| id |计数|
+------------+-----+
|           1|    6|
|           3|    3|
|           4|    3|
|           2|    3|
+------------+-----+
我首先想到HashPartitioner被用于重新划分数据帧的方法中,但情况似乎并非如此,因为它在RDD上工作

有谁能告诉我这个“Exchange hashpartitioning”(参见上面的解释输出)是如何工作的吗


2019-01-16 12:20:这不是的副本,因为我对整数列上按列(+数字分区)重新分区的哈希算法感兴趣。正如您在源代码中看到的那样,通用HashPartitioner正在按预期工作。

这里没有任何意外。如Spark中所述,使用哈希(键)分区的模数和非均匀分布,特别是在小数据集上,也并非没有例外

Dataset
RDD
之间的差异也是意料之中的,因为两者都使用不同的哈希函数(同上)

最后

结果是scala/spark生成了一个意外的结果,并创建了更少的分区

不是正确的观察值。创建的分区数正是请求的数目

scala> dfMyDataRepartitioned.rdd.getNumPartitions
res8: Int = 5

但是空的在聚合中不可见,因为没有相应的值。

这里没有什么意外。正如Spark中所解释的,Spark使用分区的哈希(键)模数和非均匀分布,特别是在小数据集上,也不例外

Dataset
RDD
之间的差异也是意料之中的,因为两者都使用不同的哈希函数(同上)

最后

结果是scala/spark生成了一个意外的结果,并创建了更少的分区

不是正确的观察值。创建的分区数正是请求的数目

scala> dfMyDataRepartitioned.rdd.getNumPartitions
res8: Int = 5

但是空的值在聚合中不可见,因为没有相应的值。

可能重复感谢您的回复,但事实并非如此:正如我之前所写的:我尝试使用HashPartitioner,我能够理解那里的哈希是如何计算的。这里我问C在重新分区中使用的哈希算法Column+分区数,它有一个不同的结果可能重复感谢您的回复,但事实并非如此:正如我已经写的:我尝试使用HashPartitioner,并且我能够理解那里的哈希是如何计算的。这里我询问在按Column+分区数重新分区中使用的哈希算法,它有不同的rent Resultt感谢您的回答。但我对哈希函数本身感兴趣。我正在使用一个整数字段来重新分区。来自Itneger的哈希代码就是整数本身。您能告诉我在哪里可以找到哈希函数的实现吗?您是对的。它正在使用