Java 在apache spark中使用distinct时出现StackOverflowerError
我使用Spark2.0.1 我试图在JavaRDD中找到不同的值,如下所示Java 在apache spark中使用distinct时出现StackOverflowerError,java,apache-spark,rdd,apache-spark-2.0,Java,Apache Spark,Rdd,Apache Spark 2.0,我使用Spark2.0.1 我试图在JavaRDD中找到不同的值,如下所示 JavaRDD<String> distinct_installedApp_Ids = filteredInstalledApp_Ids.distinct(); 相同的堆栈跟踪会一次又一次地重复。 输入filteredInstalledApp_id有数百万条记录的大量输入。问题是记录的数量,还是有一种在JavaRDD中查找不同值的有效方法。任何帮助都将不胜感激。提前谢谢。干杯 编辑1: 添加过滤方法 Jav
JavaRDD<String> distinct_installedApp_Ids = filteredInstalledApp_Ids.distinct();
相同的堆栈跟踪会一次又一次地重复。
输入filteredInstalledApp_id有数百万条记录的大量输入。问题是记录的数量,还是有一种在JavaRDD中查找不同值的有效方法。任何帮助都将不胜感激。提前谢谢。干杯
编辑1:
添加过滤方法
JavaRDD<String> filteredInstalledApp_Ids = installedApp_Ids
.filter(new Function<String, Boolean>() {
@Override
public Boolean call(String v1) throws Exception {
return v1 != null;
}
}).cache();
JavaRDD filteredInstalledApp\u id=installedApp\u id
.filter(新函数(){
@凌驾
公共布尔调用(字符串v1)引发异常{
返回v1!=null;
}
}).cache();
编辑2:
添加了用于生成installedApp\u ID的方法
public JavaRDD<String> getIdsWithInstalledApps(String inputPath, JavaSparkContext sc,
JavaRDD<String> installedApp_Ids) {
JavaRDD<String> appIdsRDD = sc.textFile(inputPath);
try {
JavaRDD<String> appIdsRDD1 = appIdsRDD.map(new Function<String, String>() {
@Override
public String call(String t) throws Exception {
String delimiter = "\t";
String[] id_Type = t.split(delimiter);
StringBuilder temp = new StringBuilder(id_Type[1]);
if ((temp.indexOf("\"")) != -1) {
String escaped = temp.toString().replace("\\", "");
escaped = escaped.replace("\"{", "{");
escaped = escaped.replace("}\"", "}");
temp = new StringBuilder(escaped);
}
// To remove empty character in the beginning of a
// string
JSONObject wholeventObj = new JSONObject(temp.toString());
JSONObject eventJsonObj = wholeventObj.getJSONObject("eventData");
int appType = eventJsonObj.getInt("appType");
if (appType == 1) {
try {
return (String.valueOf(appType));
} catch (JSONException e) {
return null;
}
}
return null;
}
}).cache();
if (installedApp_Ids != null)
return sc.union(installedApp_Ids, appIdsRDD1);
else
return appIdsRDD1;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
公共JavaRDD getIdsWithInstalledApps(字符串输入路径、JavaSparkContext sc、,
JavaRDD安装的应用程序(ID){
JavaRDD appIdsRDD=sc.textFile(inputPath);
试一试{
JavaRDD appIdsRDD1=appIdsRDD.map(新函数(){
@凌驾
公共字符串调用(字符串t)引发异常{
字符串分隔符=“\t”;
字符串[]id_Type=t.split(分隔符);
StringBuilder temp=新的StringBuilder(id_类型[1]);
如果((临时索引(“\”)!=-1){
转义字符串=temp.toString().replace(“\\”,“”);
转义=转义。替换(“\”{,“{”);
转义=转义。替换(“}\”,“}”);
temp=新的StringBuilder(转义);
}
//删除字符开头的空字符的步骤
//串
JSONObject wholeventObj=新的JSONObject(temp.toString());
JSONObject EventJSONObject=wholeventObj.getJSONObject(“eventData”);
int-appType=eventJsonObj.getInt(“appType”);
if(appType==1){
试试{
返回(String.valueOf(appType));
}捕获(JSONException e){
返回null;
}
}
返回null;
}
}).cache();
if(installedApp_id!=null)
return sc.union(installedApp_id,appIdsRDD1);
其他的
返回appIdsRDD1;
}捕获(例外e){
e、 printStackTrace();
}
返回null;
}
我假设主数据集位于inputPath
中。它似乎是一个逗号分隔的文件,带有JSON编码的值
我认为,通过结合Spark SQL的数据帧和来自_json的函数,您可以使代码变得更简单。我正在使用Scala,将代码转换为Java作为一个家庭练习:)
加载inputPath
文本文件的行和行解析本身可以如下所示:
import org.apache.spark.sql.SparkSession
val spark: SparkSession = ...
val dataset = spark.read.csv(inputPath)
您可以使用show
操作符显示内容
dataset.show(truncate = false)
您应该看到JSON编码的行
JSON行似乎包含eventData
和appType
字段
val jsons = dataset.withColumn("asJson", from_json(...))
请参见对象以获取参考
使用JSON行,您可以选择感兴趣的字段:
val apptypes = jsons.select("eventData.appType")
然后用installedApp\u id
将其连接起来
我相信代码会变得更容易阅读(希望也更容易编写)。迁移将为您提供额外的优化,您可能无法使用RDDAPI之类的汇编程序自己编写这些优化
最好的是,过滤掉空值就像使用na
操作符一样简单,它会给出likedrop
。我相信您会喜欢它们的
它不一定能回答您最初的问题,但是这个java.lang.StackOverflowerError
可能仅仅通过代码迁移就可以解决问题,而且代码也更易于维护。如果是转换,您确定它是独特的吗?您如何创建过滤器安装的应用程序ID
?您执行了什么操作ecute?@JacekLaskowski我添加了用于创建filteredInstalledApp_ID的filter方法。基本上,我试图从原始RDDWhy RDDs中过滤空值?为什么是Java?Spark版本是什么?我对Java很满意。因此我使用Java.Spark版本2.0.1。为什么是RDDs?如果有其他规定,我很乐意使用。感谢您的及时回复。欢迎您展示inputPath
的内容示例。我猜不出appType
的样子以及它所在的JSON的样子。让我试试scala,看看问题是否得到解决。谢谢
val apptypes = jsons.select("eventData.appType")