簡體   English   中英

通過將函數應用於數據幀,將頂點添加到 Tinkerpop 圖(gremlin)

[英]Add Vertices to a Tinkerpop graph (gremlin) by applying a function to a Dataframe

正如問題所表明的那樣,我一直在嘗試編寫一些可以讀取數據幀並將頂點添加到具有從數據幀中提取的屬性的 gremlin 圖的代碼。 為此,我編寫了以下代碼:

val graph = TinkerGraph.open()

val g = graph.traversal

def myFunction(field1:String,field2:String) ={

    graph.addVertex(field1,field2)
 }


val df = List(
  (1,"A","X",1),
  (2,"B","X",2),
  (3,"B","X",3),
  (4,"D","X",4),
  (5,"E","X",5),
  (6,"A","Y",1),
  (7,"C","Y",2)
).toDF("id","value","group","ts")


df.map(row => myFunction("id1", row.getAs[String]("value")))

問題是我不斷收到同樣的錯誤:

org.apache.spark.SparkException: Task not serializable
    at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:304)
    at org.apache.spark.util.ClosureCleaner$.org$apache$spark$util$ClosureCleaner$$clean(ClosureCleaner.scala:294)
    at org.apache.spark.util.ClosureCleaner$.clean(ClosureCleaner.scala:122)
    at org.apache.spark.SparkContext.clean(SparkContext.scala:2085)
    at org.apache.spark.rdd.RDD$$anonfun$map$1.apply(RDD.scala:324)
    at org.apache.spark.rdd.RDD$$anonfun$map$1.apply(RDD.scala:323)
    at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:150)
    at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:111)
    at org.apache.spark.rdd.RDD.withScope(RDD.scala:316)
    at org.apache.spark.rdd.RDD.map(RDD.scala:323)
    at org.apache.spark.sql.DataFrame.map(DataFrame.scala:1425)
    at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:57

我在這里閱讀了一些問題/答案,我得出的結論是,問題是我的函數得到了不可序列化的“東西”( graphg ),因此它失敗了。

我該怎么做才能避免這個錯誤? 我嘗試創建一個對象,在內部定義我的函數(如下所示)並使用test1.myFunction在外部調用該函數,但它仍然無法正常工作。

object test1  {

    val graph = TinkerGraph.open()

    val g = graph.traversal

def myFunction(field1:String,field2:String) ={

    graph.addVertex(field1,field2)
}

}

基於評論中的討論。 是 Datastax Graph TinkerPop 實現的一個工作示例。 以下是TinkerPop 驅動程序文檔的代碼庫草圖。 每個 spark 分區都在其中一個遠程執行程序上處理。 因此,您應該在 foreachPartition 調用內部連接到遠程 TP 服務器並向其發送數據。

df.foreachPartition(rows => {
     Cluster cluster = Cluster.open(); 
     Client client = cluster.connect();
      for (row <- rows) {
          val params = Map ("field1" -> "id1",
           "field2", row.getAs[String]("value"))
          client.submit("graph.addVertex(field1,field2)", params.asJava).all()
      }
      cluster.close()
})

TL;DR 這樣的代碼在 Apache Spark 中沒有位置。

序列化問題是次要問題。 即使您解決了序列化問題,並使用foreach操作代替轉換( map ),Spark 也沒有共享狀態。

忽略local模式,每個執行器使用自己的 JVM(甚至物理主機)。 沒有共享內存,與驅動程序的唯一通信是runJob結果或accumulators 兩者都可以在這里使用,但在這個問題中,從一開始就在本地計算所有內容一樣好(如果不是更糟的話)。

給你的基本讀物: 理解閉包

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM