Java 如何使用Spark 2.3.1中的map和reduce函数执行分组和计数

Java 如何使用Spark 2.3.1中的map和reduce函数执行分组和计数,java,apache-spark,mapreduce,dataset,Java,Apache Spark,Mapreduce,Dataset,我是spark的新手,我正在尝试使用以下spark功能进行分组和计数: Dataset<Row> result = dataset .groupBy("column1", "column2") .count(); 但这也给出了异常,如org.apache.spark.sparkeexception:Task not serializableformapToPair函数 是否有人可以建议使用数据集的reduce和map功能进行分组和计数的更好方法 感谢

我是spark的新手,我正在尝试使用以下spark功能进行分组和计数:

 Dataset<Row> result =  dataset
       .groupBy("column1", "column2")
       .count();
但这也给出了异常,如
org.apache.spark.sparkeexception:Task not serializable
for
mapToPair
函数

是否有人可以建议使用数据集的
reduce
map
功能进行分组和计数的更好方法


感谢您的帮助

您添加的链接中的groupBy指的是RDD。在RDD语义中,groupBy基本上会根据密钥洗牌所有数据,也就是说,它会将与密钥相关的所有值带到一个位置

这就是为什么建议使用reduceByKey,因为reduceByKey首先对每个分区执行reduce操作,并且只对减少的值进行洗牌,这意味着更少的通信量(并通过将所有内容都带到一个分区来防止内存不足问题)

在数据集中,groupBy的行为不同。它不会将数据集作为返回对象提供,而是提供KeyValueGroupedDataset对象。当您使用这个对象(或者更通用的agg)时,它基本上定义了一个与reduceByKey非常相似的reducer

这意味着不需要单独的reduceByKey方法(dataset groupby实际上是reduceByKey的一种形式)


坚持原来的groupBy(…)。count(…)

基于一个包含两列的数据集,一列是美国的郡名,另一列是州名

期望输出:

reduce()
Autauga County, Alabama, Baldwin County, Alabama, Barbour County, Alabama, Bibb County, Alabama, Blount County, Alabama, Bullock County, Alabama, Butler County, Alabama, Calhoun County, Alabama, Chambers County, Alabama, Cherokee County, Alabama, Chilton County,
…
用法:

System.out.println("reduce()");
String listOfCountyStateDs = countyStateDs
    .reduce(
        new CountyStateConcatenatorUsingReduce());
System.out.println(listOfCountyStateDs);
实施:

 private final class CountyStateConcatenatorUsingReduce
      implements ReduceFunction<String> {
    private static final long serialVersionUID = 12859L;

    @Override
    public String call(String v1, String v2) throws Exception {
      return v1 + ", " + v2;
    }
  }
private final class countystateconcatenator或使用reduce
实现ReduceFunction{
私有静态最终长serialVersionUID=12859L;
@凌驾
公共字符串调用(字符串v1、字符串v2)引发异常{
返回v1+“,”+v2;
}
}

但是,您必须编写自己的逻辑,这可能会很费时,而且您还是更喜欢使用groupBy…

如果我能给您一些提示,请使用SCALA。Java不是它现在的位置,除了may be KAFKA。“但我在这里读到,使用group by不是一个好主意,因为它没有组合器”-但是有没有其他比group by更有效的方法来分组行?取决于您的需要。对于几乎所有的聚合,这将是最有效的方法。我想说,使用数据帧语义而不是数据集语义通常可以提高性能。在本例中,您在幕后使用数据帧语义,因为您是按列分组的,而不是按某些映射函数分组的。
 private final class CountyStateConcatenatorUsingReduce
      implements ReduceFunction<String> {
    private static final long serialVersionUID = 12859L;

    @Override
    public String call(String v1, String v2) throws Exception {
      return v1 + ", " + v2;
    }
  }