2017-06-27 12 views
0

sqlContextのHiveテーブルで使用したいUDFを作成しようとしています。シリアライズ可能でない他のライブラリのオブジェクトを含めることは、いかなる方法で可能ですか?ここでは動作しないものの最小限の例です:シリアル化可能でないオブジェクトを含むSparkSQL UDFを作成する

def myUDF(s: String) = { 
import sun.misc.BASE64Encoder 
val coder= new BASE64Encoder 
val encoded= decoder.encode(s) 
encoded 
} 

私はテーブル「テスト」

上でそれを実行しようとした場合、私はUDF関数としてスパークシェルで

val encoding = sqlContext.udf.register("encoder", myUDF) 

を関数を登録します

sqlContext.sql("SELECT encoder(colname) from test").show() 

私はエラー

org.apache.spark.SparkException: Task not serializable 
object not serializable (class: sun.misc.BASE64Encoder, value: [email protected]) 
を取得10

これには回避策がありますか?私は、オブジェクトとクラスにmyUDFを埋め込もうとしましたが、それもうまくいきませんでした。

答えて

1

あなたは

def encoder = udf((s: String) => { 
    import sun.misc.BASE64Encoder 
    val coder= new BASE64Encoder 
    val encoded= coder.encode(s.getBytes("UTF-8")) 
    encoded 
}) 

としてudf関数を定義しようとすると、@santonがBASE64Encoderエンコーダをするために開始されていることを指摘したように

を更新しました

dataframe.withColumn("encoded", encoder(col("id"))).show 

としてudf関数を呼び出すことができます各行データフレームのがあり、パフォーマンスの問題が発生する可能性があります。その解決策は、という静的オブジェクトBASE64Encoderに作成し、それをudfという関数内で呼び出すことです。

+0

あなたのソリューションはうまくいきますが、後で私の問題が悪いと認識していて、それがうまく動作するようになったことに気付きました。 – Harpe

+0

@Harpe、はいあなたのやり方も正しいです:) upvoteのおかげで:)あなたが望むならそれを受け入れることができます;) –

+0

このコードはまた、すべての単一の行に対して新しい 'BASE64Encoder'オブジェクトをインスタンス化します。それはあなたのアプリケーションで大丈夫かもしれませんが、潜在的なパフォーマンスの影響があります。私も同様の問題で苦労しています。 – santon

関連する問題