私は、Scala jarファイルにDataFramesをパッケージ化し、Rでアクセスできるようにしたいと考えました。最終目標は、特定の頻繁に使用されるデータベーステーブルにアクセスする方法を作成することでしたPython、R、およびScalaでそれぞれ別のライブラリを書くことなくSparkR JVMを使用してScala jarファイルからメソッドを呼び出す
これを行うには、Scalaでjarファイルを作成し、SparkSQLライブラリを使用してデータベースにクエリを行い、必要なDataFramesを取得する関数を使用しました。 SparkはすでにRのJVM上で動作しているので、別のJVMを作成せずにこれらの関数をRで呼び出せるようにしたかったのですが、JVM Sparkの使用はSparkR APIで公開されていません。これをアクセス可能にしてJavaメソッドを呼び出し可能にするために、SparkRパッケージで "backend.R"、 "generics.R"、 "DataFrame.R"、 "NAMESPACE"を修正し、パッケージを再構築しました。
"backendこれらの機能をも含むようにgenerics.Rを 『:『私は修正
setMethod("callJMethod", signature(objId="jobj", methodName="character"), function(objId, methodName, ...) {
stopifnot(class(objId) == "jobj")
if (!isValidJobj(objId)) {
stop("Invalid jobj ", objId$id,
". If SparkR was restarted, Spark operations need to be re-executed.")
}
invokeJava(isStatic = FALSE, objId$id, methodName, ...)
})
setMethod("newJObject", signature(className="character"), function(className, ...) {
invokeJava(isStatic = TRUE, className, methodName = "<init>", ...)
})
形式手法』:
#' @rdname callJMethod
#' @export
setGeneric("callJMethod", function(objId, methodName, ...) { standardGeneric("callJMethod")})
#' @rdname newJobject
#' @export
setGeneric("newJObject", function(className, ...) {standardGeneric("newJObject")})
その後、私は、これらの機能のために輸出を追加しました.RはcallJMethod『と』createJObjectを」私が作りました』 NAMESPACEファイル:
export("cacheTable",
"clearCache",
"createDataFrame",
"createExternalTable",
"dropTempTable",
"jsonFile",
"loadDF",
"parquetFile",
"read.df",
"sql",
"table",
"tableNames",
"tables",
"uncacheTable",
"callJMethod",
"newJObject")
これにより、新しいJVMを起動せずに私が書いたScala関数を呼び出すことができました。
私が書いたスカラーメソッドは返されたときにRの "jobj"であるが、SparkR DataFrameは環境+ jobjであるDataFramesを返します。これらのjobj DataFramesをSparkR DataFramesに変換するために、私は上記の手順に従ってアクセス可能にした "DataFrame.R"でdataFrame()関数を使用しました。
私は、RからScalaで "構築した" DataFrameにアクセスし、SparkRのすべての機能をそのDataFrameで使用することができました。このようなクロスランゲージ・ライブラリを作る良い方法があるのか、Spark JVMが公開されるべきではない理由があるのかどうか疑問に思っていましたか?
しかし、RとScalaの間でデータを共有し、データを保存せずに再読み込みする良い方法はありますか?私が何か解決策2と3が不足していない限り、両方がそれを必要とするようです。 – shj
私はあなたが何を望んでいるか正確にはわかりません。 Sparkは、JVMあたり複数のコンテキストをサポートしていません([SPARK-2243](https://issues.apache.org/jira/browse/SPARK-2243)を参照)。また、コンテキスト間でRDDを共有することもできません。したがって、3つのタイプすべてでは、あるタイプのストレージからデータを読み取る必要があります。 [spark-jobserver](https://github.com/spark-jobserver/spark-jobserver)、["shared" RDDs(https://ignite.apache.org/features/igniterdd)]のようないくつかのオプションがあります。 html)をIgniteの上に置くか、この問題に対処しようとしているメモリ記憶層として[Tachyon](http://tachyon-project.org/)を使用していますが、単純なJVMの公開はどこにもありません。 – zero323
単純なSQLクエリの場合、おそらくbool-in [Thrift server](http://spark.apache.org/docs/latest/sql-programming-guide.html#running-the-thrift-jdbcodbc-server)を使用できます。 – zero323