Apache spark dataset groupByKey映射组仅使用分配的50个执行器中的2个执行器

Apache spark dataset groupByKey映射组仅使用分配的50个执行器中的2个执行器,apache-spark,dataset,Apache Spark,Dataset,我有一个任务,它从Hive加载一些数据,然后进行一些处理,最后将数据写入Cassandra。在某种程度上,它工作得很好,但突然之间,其中一个Spark操作出现了瓶颈,即即使在整个管道中分区计数设置为2000,也只使用了2个内核。我正在运行Spark版本:Spark-core_2.11-2.0.0 我的Spark配置如下: spark.executor.instances = "50" spark.executor.cores = "4" spark.executor.memory =

我有一个任务,它从Hive加载一些数据,然后进行一些处理,最后将数据写入Cassandra。在某种程度上,它工作得很好,但突然之间,其中一个Spark操作出现了瓶颈,即即使在整个管道中分区计数设置为2000,也只使用了2个内核。我正在运行Spark版本:Spark-core_2.11-2.0.0 我的Spark配置如下:

  spark.executor.instances = "50"
  spark.executor.cores = "4"
  spark.executor.memory = "6g"
  spark.driver.memory = "8g"
  spark.memory.offHeap.enabled = "true"
  spark.memory.offHeap.size = "4g"
  spark.yarn.executor.memoryOverhead = "6096"
  hive.exec.dynamic.partition.mode = "nonstrict"
  spark.sql.shuffle.partitions = "3000"
  spark.unsafe.sorter.spill.reader.buffer.size  = "1m"
  spark.file.transferTo = "false"
  spark.shuffle.file.buffer = "1m"
  spark.shuffle.unsafe.file.ouput.buffer = "5m"
当我对正在运行的执行器执行线程转储时,我看到:

com.*.MapToSalaryRow.buildSalaryRow(SalaryTransformer.java:110)
com.*.MapToSalaryRow.call(SalaryTransformer.java:126)
com.*.MapToSalaryRow.call(SalaryTransformer.java:88)
org.apache.spark.sql.KeyValueGroupedDataset$$anonfun$mapGroups$1.apply(KeyValueGroupedDataset.scala:220)
出现问题的代码的简化版本是:


 sourceDs.createOrReplaceTempView("salary_ds")
 sourceDs.repartition(2000);
 System.out.println("sourceDsdataset partition count = "+sourceDs.rdd().getNumPartitions());
 Dataset<Row> salaryDs = sourceDs.groupByKey(keyByUserIdFunction, Encoders.LONG()).mapGroups(
                new MapToSalaryRow( props), RowEncoder.apply(getSalarySchema())).
                filter((FilterFunction<Row>) (row -> row != null));
  salaryDs.persist(StorageLevel.MEMORY_ONLY_SER());
  salaryDs.repartition(2000);
  System.out.println("salaryDs dataset partition count = "+salaryDs.rdd().getNumPartitions());


sourceDs.createOrReplaceTempView(“薪水”)
资料来源DS.重新分配(2000年);
System.out.println(“sourceDsdataset分区计数=“+sourceDs.rdd().getNumPartitions());
Dataset salaryDs=sourceDs.groupByKey(keyByUserIdFunction,Encoders.LONG()).mapGroups(
新的MapToSalaryRow(props),RowEncoder.apply(getSalarySchema())。
过滤器((FilterFunction)(行->行!=null));
salaryDs.persist(StorageLevel.MEMORY_ONLY_SER());
《工资再分配》(2000年);
System.out.println(“salaryDs数据集分区计数=“+salaryDs.rdd().getNumPartitions());
上述两条打印语句都显示分区计数为2000

功能映射组的相关代码为:


class MapToSalaryInsightRow implements MapGroupsFunction<Long, Row, Row> {
    private final Properties props;

        @Override
    public Row call(Long userId, Iterator<Row> iterator) throws Exception {
        return buildSalaryRow(userId, iterator, props);
    }
}


类MapToSalayInsightRow实现MapGroupsFunction{
私人最终财产道具;
@凌驾
公共行调用(长用户ID、迭代器迭代器)引发异常{
返回buildSalaryRow(userId、迭代器、props);
}
}
如果有人能指出问题所在,我们将不胜感激。
感谢

问题在于有一列类型为array,因此其中一行的数组非常大。尽管分区大小大致相同,但其中两个分区的大小是原来的40倍。在这些情况下,获取这些行的任务将花费更长的时间

问题是有一列类型为array,因此对于其中一行,该数组非常庞大。尽管分区大小大致相同,但其中两个分区的大小是原来的40倍。在这些情况下,获取这些行的任务将花费更长的时间