web-dev-qa-db-ja.com

pysparkからキーストアファイルを読み取れません

以下のスニペットを使用して、Hiveからelasticsearch(v 6.2)にデータを接続し、問題なくロードしています

ADD JAR file:///<>/elasticsearch-hadoop-Hive-6.2.2.jar;
ADD FILE file:///<>/mycerts.jks;

CREATE EXTERNAL TABLE if not exists my_db.my_es_table
(
col1 int,
col2 string,
col3 string,
col4 timestamp,
key_id string
)
COMMENT 'data into ES'
STORED BY 'org.elasticsearch.hadoop.Hive.EsStorageHandler'
TBLPROPERTIES('es.resource' = 'index1/type1',
'es.index.auto.create'='true',
'es.nodes'='<vip_name>',
'es.port'='9200',
'es.net.http.auth.user'='<user>',
'es.net.http.auth.pass'='pwd',
'es.net.ssl.protocol'='SSL',
'es.net.ssl'='TRUE',
'es.net.ssl.truststore.location'='mycerts.jks',
'es.net.ssl.truststore.pass'='<pwd>',
'es.mapping.id'='key_id'
);

INSERT OVERWRITE TABLE my_db.my_es_table
SELECT
col1,
col2,
col3,
col4,
key_id
FROM my_db.stagging_data;

しかし、同じ部分をpy-sparkに移行しようとすると、例外がスローされます

   org.elasticsearch.hadoop.EsHadoopIllegalArgumentException: Expected to find keystore file at [file:///<path>/mycerts.jks] but was unable to. Make sure that it is available on the classpath, or if not, that you have specified a valid URI

以下は私がスパークのために試したコードスニペットです

df_delta=sqlContext.table('my_db.stagging_data')
status=df_delta.rdd.map(lambda row:(None,row.asDict())).saveAsNewAPIHadoopFile(path='-', outputFormatClass="org.elasticsearch.hadoop.mr.EsOutputFormat",keyClass="org.Apache.hadoop.io.NullWritable",valueClass="org.elasticsearch.hadoop.mr.LinkedMapWritable",conf={'es.resource' : 'index1/type1','es.index.auto.create':'true','es.nodes':'<vip_name>','es.port':'9200','es.net.http.auth.user':'<user>','es.net.http.auth.pass':'<pwd>','es.net.ssl':'true','es.net.ssl.truststore.location':'file:///<path>/mycerts.jks','es.net.ssl.truststore.pass':'<pwd>','es.mapping.id' : 'key_id'})

以下のコマンドを使用してシェルを呼び出しています-

pyspark --jars <path>/elasticsearch-spark-20_2.11-6.2.2.jar --py-files <path>/mycerts.jks

ログ全体を追加しています

Caused by: org.elasticsearch.hadoop.EsHadoopIllegalArgumentException: Expected to find keystore file at [file:///<path>/mycerts.jks] but was unable to. Make sure that it is available on the classpath, or if not, that you have specified a valid URI.
        at org.elasticsearch.hadoop.rest.commonshttp.SSLSocketFactory.loadKeyStore(SSLSocketFactory.Java:193)
        at org.elasticsearch.hadoop.rest.commonshttp.SSLSocketFactory.loadTrustManagers(SSLSocketFactory.Java:224)
        at org.elasticsearch.hadoop.rest.commonshttp.SSLSocketFactory.createSSLContext(SSLSocketFactory.Java:171)
        ... 31 more

Driver stacktrace:
        at org.Apache.spark.scheduler.DAGScheduler.org$Apache$spark$scheduler$DAGScheduler$$failJobAndIndependentStages(DAGScheduler.scala:1609)
        at org.Apache.spark.scheduler.DAGScheduler$$anonfun$abortStage$1.apply(DAGScheduler.scala:1597)
        at org.Apache.spark.scheduler.DAGScheduler$$anonfun$abortStage$1.apply(DAGScheduler.scala:1596)
        at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
        at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
        at org.Apache.spark.scheduler.DAGScheduler.abortStage(DAGScheduler.scala:1596)
        at org.Apache.spark.scheduler.DAGScheduler$$anonfun$handleTaskSetFailed$1.apply(DAGScheduler.scala:831)
        at org.Apache.spark.scheduler.DAGScheduler$$anonfun$handleTaskSetFailed$1.apply(DAGScheduler.scala:831)
        at scala.Option.foreach(Option.scala:257)
        at org.Apache.spark.scheduler.DAGScheduler.handleTaskSetFailed(DAGScheduler.scala:831)
        at org.Apache.spark.scheduler.DAGSchedulerEventProcessLoop.doOnReceive(DAGScheduler.scala:1830)
        at org.Apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:1779)
        at org.Apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:1768)
        at org.Apache.spark.util.EventLoop$$anon$1.run(EventLoop.scala:48)
        at org.Apache.spark.scheduler.DAGScheduler.runJob(DAGScheduler.scala:642)
        at org.Apache.spark.SparkContext.runJob(SparkContext.scala:2034)
        at org.Apache.spark.SparkContext.runJob(SparkContext.scala:2055)
        at org.Apache.spark.SparkContext.runJob(SparkContext.scala:2087)
        at org.Apache.spark.internal.io.SparkHadoopWriter$.write(SparkHadoopWriter.scala:78)
        ... 26 more
Caused by: org.Apache.spark.SparkException: Task failed while writing rows
        at org.Apache.spark.internal.io.SparkHadoopWriter$.org$Apache$spark$internal$io$SparkHadoopWriter$$executeTask(SparkHadoopWriter.scala:155)
        at org.Apache.spark.internal.io.SparkHadoopWriter$$anonfun$3.apply(SparkHadoopWriter.scala:83)
        at org.Apache.spark.internal.io.SparkHadoopWriter$$anonfun$3.apply(SparkHadoopWriter.scala:78)
        at org.Apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87)
        at org.Apache.spark.scheduler.Task.run(Task.scala:109)
        at org.Apache.spark.executor.Executor$TaskRunner.run(Executor.scala:345)
        at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1149)
        at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:624)
        ... 1 more
Caused by: org.elasticsearch.hadoop.EsHadoopIllegalStateException: Cannot initialize SSL - Expected to find keystore file at [file:///<path>/mycerts.jks] but was unable to. Make sure that it is available on the classpath, or if not, that you have specified a valid URI.
        at org.elasticsearch.hadoop.rest.commonshttp.SSLSocketFactory.createSSLContext(SSLSocketFactory.Java:173)
        at org.elasticsearch.hadoop.rest.commonshttp.SSLSocketFactory.getSSLContext(SSLSocketFactory.Java:158)
        at org.elasticsearch.hadoop.rest.commonshttp.SSLSocketFactory.createSocket(SSLSocketFactory.Java:127)
        at org.Apache.commons.httpclient.HttpConnection.open(HttpConnection.Java:707)
        at org.Apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.Java:387)
        at org.Apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.Java:171)
        at org.Apache.commons.httpclient.HttpClient.executeMethod(HttpClient.Java:397)
        at org.Apache.commons.httpclient.HttpClient.executeMethod(HttpClient.Java:323)
        at org.elasticsearch.hadoop.rest.commonshttp.CommonsHttpTransport.execute(CommonsHttpTransport.Java:478)
        at org.elasticsearch.hadoop.rest.NetworkClient.execute(NetworkClient.Java:112)
        at org.elasticsearch.hadoop.rest.RestClient.execute(RestClient.Java:380)
        at org.elasticsearch.hadoop.rest.RestClient.execute(RestClient.Java:344)
        at org.elasticsearch.hadoop.rest.RestClient.execute(RestClient.Java:348)
        at org.elasticsearch.hadoop.rest.RestClient.get(RestClient.Java:158)
        at org.elasticsearch.hadoop.rest.RestClient.getHttpNodes(RestClient.Java:115)
        at org.elasticsearch.hadoop.rest.InitializationUtils.discoverNodesIfNeeded(InitializationUtils.Java:92)
        at org.elasticsearch.hadoop.rest.RestService.createWriter(RestService.Java:579)
        at org.elasticsearch.hadoop.mr.EsOutputFormat$EsRecordWriter.init(EsOutputFormat.Java:173)
        at org.elasticsearch.hadoop.mr.EsOutputFormat$EsRecordWriter.write(EsOutputFormat.Java:149)
        at org.Apache.spark.internal.io.HadoopMapReduceWriteConfigUtil.write(SparkHadoopWriter.scala:356)
        at org.Apache.spark.internal.io.SparkHadoopWriter$$anonfun$4.apply(SparkHadoopWriter.scala:130)
        at org.Apache.spark.internal.io.SparkHadoopWriter$$anonfun$4.apply(SparkHadoopWriter.scala:127)
        at org.Apache.spark.util.Utils$.tryWithSafeFinallyAndFailureCallbacks(Utils.scala:1413)
        at org.Apache.spark.internal.io.SparkHadoopWriter$.org$Apache$spark$internal$io$SparkHadoopWriter$$executeTask(SparkHadoopWriter.scala:139)
        ... 8 more
Caused by: org.elasticsearch.hadoop.EsHadoopIllegalArgumentException: Expected to find keystore file at [file:///<path>/mycerts.jks] but was unable to. Make sure that it is available on the classpath, or if not, that you have specified a valid URI.
        at org.elasticsearch.hadoop.rest.commonshttp.SSLSocketFactory.loadKeyStore(SSLSocketFactory.Java:193)
        at org.elasticsearch.hadoop.rest.commonshttp.SSLSocketFactory.loadTrustManagers(SSLSocketFactory.Java:224)
        at org.elasticsearch.hadoop.rest.commonshttp.SSLSocketFactory.createSSLContext(SSLSocketFactory.Java:171)
        ... 31 more

Py-sparkに接続した後、jksファイルを読み取って印刷できます。この問題を解決できません。誰か提案していただけませんか。

9

間違ったオプションを使用していると思います

Pythonの場合、spark-submitの_--py-files_引数を使用して、アプリケーションとともに配布される。py、.Zipまたは.Eggファイルを追加できます。

代わりに、_--files_が必要です

--files FILES: Comma-separated list of files to be placed in the working directory of each executor. File paths of these files in executors can be accessed via SparkFiles.get(fileName)

Executor内の別のパスに配置するには、_#_セパレーターを使用できます

_spark-submit ... --files mycerts.jks#/<path>/mycerts.jks
_

コード内で、ファイルへの絶対パスを返すSparkFiles.get("mycerts.jks")からパスへの参照を取得できます

3
cricket_007

上記のcricket_007で指摘されているように、誤ったオプション--py-filesを使用しています。代わりに、-filesオプションを使用して証明書ファイルをアップロードします。

また、これらのファイルは、これらのエグゼキューターのローカルファイルシステムではなく、HDFSにアップロードされます。したがって、sparkコード内の証明書ファイルに渡すパスも、ローカルファイルシステムを指しているため、正しくありません。

'es.net.ssl.truststore.location':'file:///<path>/mycerts.jks'

spark submitコマンドで#オプションとファイル区切り記号を使用して、HDFS上の指定された場所にファイルをアップロードできます。

spark-submit ... --files mycerts.jks#/<path>/mycerts.jks

sparkコードで同じパスを使用してファイルにアクセスします。

'es.net.ssl.truststore.location':'/<path>/mycerts.jks'
0
Harsh Bafna

スタックメッセージに基づいて、<pathは明らかに間違っているようです。 --jarsおよび--py-filesの後のpath値は正確である必要がありますが、残念ながら現在は正確ではありません。

[file:////mycerts.jks]でキーストアファイルを見つけることが期待されていましたが、見つかりませんでした。クラスパスで使用できることを確認してください。使用できない場合は、有効なURIを指定してください。

0
Always Sunny