PySpark读取Keystore文件失败:Hive转PySpark迁移ES数据报错
解决PySpark写入Elasticsearch时信任库文件找不到的问题
我来帮你分析问题根源,并给出针对性的解决方案:
问题核心原因
你遇到的错误本质是Elasticsearch-Hadoop库在Spark Executor节点上无法访问到指定的信任库文件,具体有两个关键问题:
- 你用
--py-files参数传递证书文件,但这个参数是专门用来分发Python脚本/模块的,不会将文件放到Executor的工作目录或类路径中,Executor进程根本找不到它。 - 配置里的
file:///<path>/mycerts.jks是Driver节点的本地路径,在分布式Spark集群中,Executor节点(尤其是运行在不同机器上的)无法直接访问Driver的本地文件系统,哪怕Driver能读取到该文件,Executor也不行。
具体解决方案
步骤1:正确分发证书到所有Executor节点
启动PySpark时,替换--py-files为--files参数,这个参数专门用于分发通用资源文件,Spark会自动把文件复制到每个Executor的工作目录:
pyspark --jars <path>/elasticsearch-spark-20_2.11-6.2.2.jar --files <path>/mycerts.jks
步骤2:修改PySpark配置中的信任库路径
因为Spark已经把证书文件放到了Executor的当前工作目录,所以不需要再使用全路径,直接填写文件名即可:
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':'mycerts.jks', # 改为文件名即可 'es.net.ssl.truststore.pass':'<pwd>', 'es.mapping.id' : 'key_id' } )
可选验证步骤
如果还是有疑问,可以在PySpark中验证文件是否被正确分发:
# 在Driver端查看当前目录文件 import os print(os.listdir('.')) # 应该能看到mycerts.jks # 在Executor端验证(通过RDD触发分布式执行) sc.parallelize([1]).map(lambda x: os.listdir('.')).collect()
如果Executor的返回结果里包含mycerts.jks,说明文件分发成功,此时再运行写入ES的代码应该就能正常工作了。
内容的提问来源于stack exchange,提问作者RAVITEJA SATYAVADA
相关产品推荐
相关产品推荐

