Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.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
ApacheSpark:JavaRDD中特定字段的记录计数_Java_Apache Spark_Rdd - Fatal编程技术网

ApacheSpark:JavaRDD中特定字段的记录计数

ApacheSpark:JavaRDD中特定字段的记录计数,java,apache-spark,rdd,Java,Apache Spark,Rdd,我想在对象的字段中以Java RDD为基础计算不同类型的记录。 我有一个实体类,它将名称和状态作为该类的成员变量。实体类如下所示: import java.io.Serializable; import lombok.AllArgsConstructor; import lombok.Getter; @Getter @AllArgsConstructor public class Entity implements Serializable { private final Strin

我想在对象的字段中以Java RDD为基础计算不同类型的记录。

我有一个实体类,它将
名称
状态
作为该类的成员变量。实体类如下所示:

import java.io.Serializable;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class Entity implements Serializable {
    private final String name;
    private final String state;
}
我有一个实体对象的javaRDD。我想确定此RDD中每个状态存在多少对象

我目前使用的方法是使用LongAccumulator。其思想是迭代RDD中的每个记录,解析状态字段,并增加相应累加器的计数。到目前为止,我尝试的代码是:

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.util.LongAccumulator;

import java.util.ArrayList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CountRDD {
    public static void main(String[] args) {
        String applicationName = CountRDD.class.getName();
        SparkConf sparkConf = new SparkConf().setAppName(applicationName).setMaster("local");
        JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);
        javaSparkContext.setLogLevel("INFO");

        Entity entity1 = new Entity("a1", "s1");
        Entity entity2 = new Entity("a2", "s2");
        Entity entity3 = new Entity("a3", "s1");
        Entity entity4 = new Entity("a4", "s2");
        Entity entity5 = new Entity("a5", "s1");
        List<Entity> entityList = new ArrayList<Entity>();
        entityList.add(entity1);
        entityList.add(entity2);
        entityList.add(entity3);
        entityList.add(entity4);
        entityList.add(entity5);

        JavaRDD<Entity> entityJavaRDD = javaSparkContext.parallelize(entityList, 1);
        LongAccumulator s1Accumulator = javaSparkContext.sc().longAccumulator("s1");
        LongAccumulator s2Accumulator = javaSparkContext.sc().longAccumulator("s2");

        entityJavaRDD.foreach(entity -> {
            if (entity != null) {
                String state = entity.getState();
                if ("s1".equalsIgnoreCase(state)) {
                    s1Accumulator.add(1);
                } else if ("s2".equalsIgnoreCase(state)) {
                    s2Accumulator.add(1);
                }
            }
        });
        log.info("Final values for input entity RDD are following");
        log.info("s1Accumulator = {} ", s1Accumulator.value());
        log.info("s2Accumulator = {} ", s2Accumulator.value());
    }
}
import org.apache.spark.SparkConf;
导入org.apache.spark.api.java.JavaRDD;
导入org.apache.spark.api.java.JavaSparkContext;
导入org.apache.spark.util.org;
导入java.util.ArrayList;
导入java.util.List;
导入lombok.extern.slf4j.slf4j;
@Slf4j
公共类CountRDD{
公共静态void main(字符串[]args){
字符串applicationName=CountRDD.class.getName();
SparkConf SparkConf=new SparkConf().setAppName(applicationName).setMaster(“本地”);
JavaSparkContext JavaSparkContext=新的JavaSparkContext(sparkConf);
setLogLevel(“INFO”);
实体实体1=新实体(“a1”、“s1”);
实体实体2=新实体(“a2”、“s2”);
实体实体3=新实体(“a3”、“s1”);
实体实体4=新实体(“a4”、“s2”);
实体实体5=新实体(“a5”、“s1”);
List entityList=新建ArrayList();
entityList.add(entity1);
entityList.add(entity2);
entityList.add(entity3);
entityList.add(entity4);
entityList.add(entity5);
JavaRDD entityJavaRDD=javaSparkContext.parallelize(entityList,1);
LongAccumulator s1Accumulator=javaSparkContext.sc().LongAccumulator(“s1”);
LongAccumulator s2Accumulator=javaSparkContext.sc().LongAccumulator(“s2”);
entityJavaRDD.foreach(实体->{
如果(实体!=null){
字符串状态=entity.getState();
如果(“s1”。相等信号情况(状态)){
s1.添加(1);
}else if(“s2”。相等信号情况(状态)){
22.添加(1);
}
}
});
log.info(“输入实体RDD的最终值如下”);
log.info(“s1acculator={}”,s1acculator.value());
log.info(“s2Accumulator={}”,s2Accumulator.value());
}
}
上述代码工作并产生此输出
s1acculator=3
s2acculator=2

上述代码的
限制是:我们应该在执行前知道状态的所有允许值,并维护相应的累加器。这只会使代码对于更大的状态值来说太大

我可以想到的另一种方法是创建一对新的字符串(state)和整数(count)RDD。对输入RDD应用
mapToPair
转换,并从新创建的RDD中获取计数


关于如何处理这个问题的任何其他想法

如注释中所述,您可以在状态字段上调用
groupBy
,然后在其上调用
count
,这将为您提供每个状态的计数。你不需要累加器

作为补充说明,如果您避免使用lambda函数并使用数据帧(即
DataSet
),则作业的运行性能会显著提高。数据帧提供了比RDD更好的查询优化和代码生成功能,并且对于大多数处理用例具有向量化(意思是:非常快)功能

DataSet API javadoc在描述中有一个DataFrame groupBy示例:


首先最好将数据读取为数据帧,但您可以使用
SparkSession.createDateFrame

转换RDD和JavaRDD。如注释中所述,您可以在state字段上调用
groupBy
,然后在其上调用
count
,这将为您提供每个状态的计数。你不需要累加器

作为补充说明,如果您避免使用lambda函数并使用数据帧(即
DataSet
),则作业的运行性能会显著提高。数据帧提供了比RDD更好的查询优化和代码生成功能,并且对于大多数处理用例具有向量化(意思是:非常快)功能

DataSet API javadoc在描述中有一个DataFrame groupBy示例:


首先最好将数据读取为数据帧,但是可以使用
SparkSession.createDateFrame

转换RDD和JavaRDD。您应该使用groupBy方法。请参见此处的示例:您应该使用groupBy方法。请参见此处的示例: