Apache spark Neo4j/Apache Spark任务不可序列化

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

我的目标是将apachespark中作为RDD加载的一些文档加载到Neo4j图中。问题似乎在于创建这样的节点,因为Eclipse报告任务不可序列化

线程“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连接器可以使用的格式-它可以比“手动”解决方案更优化,并且更易于使用

  • 继续使用foreach
    foreach
    ,但您需要更改方法-驱动程序的初始化应该在每个执行器上进行-最简单的方法是这样做(伪代码,未测试)-这将使每个分区由持有该分区的执行者处理-在这种情况下,每个执行者都有自己与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();
        }
    }