Spark의 GraphFrames를 기반으로하는 스칼라 클래스를 작성하려고합니다. GraphFrame 클래스는 여기에서 정의 됩니다 . GraphFrames 클래스는 직렬화 가능을 확장합니다. GraphFrames를 확장하고 추가 그래프 속성을 계산하는 클래스를 작성하고 싶습니다. 이 예제를 단순화하기 위해 함수를 포함하지 않는 클래스를 만들었습니다. 그것이하는 일은 단지 GraphFrames를 확장하는 것입니다.
import org.apache.spark.sql.DataFrame
import org.graphframes._
class NewGraphFrame(@transient private val _vertices: DataFrame,
@transient private val _edges: DataFrame) extends GraphFrame {
}
val vertices = Seq(
(1, "John"),
(2, "Jane"),
(3, "Karen")
).toDF("id", "name")
val edges = Seq(
(1, 3),
(2, 3),
(2, 1)
).toDF("src", "dst")
val g = new NewGraphFrame(vertices, edges)
REPL에서이 코드를 실행하면 다음 오류가 발생합니다.
java.lang.Exception: You cannot use GraphFrame objects within a Spark closure
at org.graphframes.GraphFrame.vertices(GraphFrame.scala:125)
at org.graphframes.GraphFrame.toString(GraphFrame.scala:55)
at scala.runtime.ScalaRunTime$.scala$runtime$ScalaRunTime$$inner$1(ScalaRunTime.scala:332)
at scala.runtime.ScalaRunTime$.stringOf(ScalaRunTime.scala:337)
at scala.runtime.ScalaRunTime$.replStringOf(ScalaRunTime.scala:345)
at .$print$lzycompute(<console>:10)
at .$print(<console>:6)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:786)
at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:1047)
at scala.tools.nsc.interpreter.IMain$WrappedRequest$$anonfun$loadAndRunReq$1.apply(IMain.scala:638)
at scala.tools.nsc.interpreter.IMain$WrappedRequest$$anonfun$loadAndRunReq$1.apply(IMain.scala:637)
at scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
at scala.reflect.internal.util.AbstractFileClassLoader.asContext(AbstractFileClassLoader.scala:19)
at scala.tools.nsc.interpreter.IMain$WrappedRequest.loadAndRunReq(IMain.scala:637)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:569)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:565)
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:807)
at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:681)
at scala.tools.nsc.interpreter.ILoop.processLine(ILoop.scala:395)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:415)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:923)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:909)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:909)
at scala.reflect.internal.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:97)
at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:909)
at org.apache.spark.repl.Main$.doMain(Main.scala:76)
at org.apache.spark.repl.Main$.main(Main.scala:56)
at org.apache.spark.repl.Main.main(Main.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.JavaMainApplication.start(SparkApplication.scala:52)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:894)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:198)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:228)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:137)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
나는 이것이 내가 두 번 직렬화한다는 것을 의미한다는 것을 알고 있습니다. 그러나 나는 분명히 그것에 관심이 없습니다. 클래스에서 그래프 기능을 사용할 수 있도록이 클래스를 확장하고 싶습니다. 이 오류를 발생시키는 spark repl없이이 클래스를 확장하려면 어떻게해야합니까?
흥미롭게도 직렬화가 발생하지 않았으므로 이것은 실제로 직렬화 문제가 아닙니다.
정의는 다음과 같이 GraphFrame
요약됩니다.
class GraphFrame private(private val _vertices: DataFrame, private val _edges) extends Logging with Serializable
첫 번째 private
는 기본 생성자가 내부 GraphFrame
또는 동반 객체 에서만 액세스 할 수 있음을 의미 합니다. _vertices
and _edges
는 비공개 이므로 하위 클래스에서 액세스 할 수 없으며 재정의 할 수 없습니다 (사용자 _vertices
및 _edges
필드는 GraphFrame
접두사로 사용할 수없는 : 의 해당 이름 필드와 다릅니다 override
.
GraphFrame
단일 공개 인수가없는 생성자를 정의합니다.
def this() = this(null, null)
GraphFrame
따라서 의 모든 하위 클래스 는 null
for GraphFrame._vertices
또는 을 가지며 GraphFrame._edges
, 이는 GraphFrame
. 접근 자 vertices
와 edges
확인 null
하고 던집니다. 이러한 접근자는 toString
메서드 에서 호출되기 때문에 .NET Framework를 만들 때 REPL이 폭발하는 이유 NewGraphFrame
입니다. GraphFrame
그것들이 null
있다면 그것은 직렬화가 시도되었음을 의미 한다고 가정하는 것 같습니다 .
REPL에서 다음과 같이 설명 할 수 있습니다.
new NewGraphFrame(vertices, edges).vertices
결과는 null
.
검색하는 메서드로 메서드 를 재정의하면 vertices
( 및에 대해 동일한 작업을 수행 ) 최소한 새 클래스 를 사용할 수 있습니다 ._
NewNewGraphFrame._vertices
edges
toString
override def vertices: DataFrame = _vertices
override def edges: DataFrame = _edges
의 방법 정도로 GraphFrame
당신이 사용에 관심이 vertices
/ edges
대신 _vertices
/ _edges
당신은 기존의 방법을 활용할 수 있습니다 GraphFrame
.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다