Apache spark Neo4j/Apache Spark任务不可序列化
我的目标是将apachespark中作为RDD加载的一些文档加载到Neo4j图中。问题似乎在于创建这样的节点,因为Eclipse报告任务不可序列化Apache spark Neo4j/Apache Spark任务不可序列化,apache-spark,neo4j,Apache Spark,Neo4j,我的目标是将apachespark中作为RDD加载的一些文档加载到Neo4j图中。问题似乎在于创建这样的节点,因为Eclipse报告任务不可序列化 线程“main”org.apache.spark.sparkeexception中的异常:任务不可序列化 我的代码如下: public class Spark { public static void createRdd() { SparkSession spark = SparkSession.build
线程“main”org.apache.spark.sparkeexception中的异常:任务不可序列化
我的代码如下:
public class Spark {
public static void createRdd() {
SparkSession spark = SparkSession.builder()
.master("local")
.appName("MongoSparkConnector")
.config("spark.mongodb.input.uri", "mongodb://127.0.0.1/TheFoodPlanner.join")
.getOrCreate();
JavaSparkContext jsc = new JavaSparkContext(spark.sparkContext());
JavaMongoRDD<Document> rddRecipes = MongoSpark.load(jsc);
Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "estrella100"));
try (Session session = driver.session()) {
rddRecipes.foreach(f -> {
String id = f.getString("id");
session.run("CREATE (n: Recipe {id:'" + id + "'})");
});
session.close();
}
driver.close();
jsc.close();
}
}
公共类Spark{
公共静态void createRdd(){
SparkSession spark=SparkSession.builder()
.master(“本地”)
.appName(“MongoSparkConnector”)
.config(“spark.mongodb.input.uri”mongodb://127.0.0.1/TheFoodPlanner.join")
.getOrCreate();
JavaSparkContext jsc=新的JavaSparkContext(spark.sparkContext());
javamongordrdrdrecipes=MongoSpark.load(jsc);
驱动程序驱动程序=图形数据库。驱动程序(“bolt://localhost:7687,AuthTokens.basic(“neo4j”、“estrella100”);
try(会话=driver.Session()){
rddRecipes.foreach(f->{
字符串id=f.getString(“id”);
run(“创建(n:Recipe{id:''“+id+'})”);
});
session.close();
}
driver.close();
jsc.close();
}
}
错误出现在session.run(“CREATE(n:Recipe{id:'“+id+”})”行中代码>
并行加载节点的正确方法是什么?问题在于,您将来自Mongo的基于Spark的数据连接器与Neo4j的“传统”Java连接器混为一谈。在这种情况下,通常的问题是,这些驱动程序没有针对Spark进行优化,而没有额外的代码来处理在多个执行器上运行代码的问题-这里的一个常见问题是驱动程序仅在驱动程序节点上打开连接,而不是在执行器上打开连接
对于您的情况,您有两种可能性:
使用现有的-您需要将Mongo中的数据转换为Neo4j连接器可以使用的格式-它可以比“手动”解决方案更优化,并且更易于使用
继续使用foreachforeach
,但您需要更改方法-驱动程序的初始化应该在每个执行器上进行-最简单的方法是这样做(伪代码,未测试)-这将使每个分区由持有该分区的执行者处理-在这种情况下,每个执行者都有自己与Neo4j的连接:
rddRecipes.foreachPartition { partitionOfRecords =>
Driver driver = GraphDatabase.driver("bolt://localhost:7687",
AuthTokens.basic("neo4j", "estrella100"));
try (Session session = driver.session()) {
partitionOfRecords.foreach(f -> {
String id = f.getString("id");
session.run("CREATE (n: Recipe {id:'" + id + "'})");
});
session.close();
}
}