从 EMR spark 连接到 EMR presto - 连接失败

Posted

技术标签:

【中文标题】从 EMR spark 连接到 EMR presto - 连接失败【英文标题】:Connecting from EMR spark to EMR presto - Failed to connect 【发布时间】:2020-05-10 21:15:20 【问题描述】:

我在从运行 spark 的 AWS EMR 集群连接到另一个运行 presto 的 AWS EMR 集群时遇到问题。

用python编写的代码是:

jdbcDF = spark.read \
        .format("jdbc") \
        .option("driver", "com.facebook.presto.jdbc.PrestoDriver")\
        .option("url", "jdbc:presto://ec2-xxxxxxxxxxxx.ap-southeast-2.compute.amazonaws.com:8889/hive/data-lake") \
        .option("user", "hadoop") \
        .option("dbtable", "customer") \
        .load()\

通过 aws emr add-steps 使用选项 --packages,\'org.apache.spark:spark-streaming-kinesis-asl_2.11:2.4.0,org.postgresql:postgresql:42.2.9,com.facebook.presto:presto-jdbc:0.60\',\ 部署

部署时会引发以下错误

线程“main”中的异常 java.lang.reflect.UndeclaredThrowableException 在 org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1862) 在 org.apache.spark.deploy.SparkHadoopUtil.runAsSparkUser(SparkHadoopUtil.scala:64) 在 org.apache.spark.executor.CoarseGrainedExecutorBackend$.run(CoarseGrainedExecutorBackend.scala:237) 在 org.apache.spark.executor.CoarseGrainedExecutorBackend$.main(CoarseGrainedExecutorBackend.scala:330) 在 org.apache.spark.executor.CoarseGrainedExecutorBackend.main(CoarseGrainedExecutorBackend.scala) 引起:org.apache.spark.SparkException:在 awaitResult 中抛出异常: 在 org.apache.spark.util.ThreadUtils$.awaitResult(ThreadUtils.scala:226) 在 org.apache.spark.rpc.RpcTimeout.awaitResult(RpcTimeout.scala:75) 在 org.apache.spark.rpc.RpcEnv.setupEndpointRefByURI(RpcEnv.scala:101) 在 org.apache.spark.executor.CoarseGrainedExecutorBackend$$anonfun$run$1.apply$mcV$sp(CoarseGrainedExecutorBackend.scala:250) 在 org.apache.spark.deploy.SparkHadoopUtil$$anon$2.run(SparkHadoopUtil.scala:65) 在 org.apache.spark.deploy.SparkHadoopUtil$$anon$2.run(SparkHadoopUtil.scala:64) 在 java.security.AccessController.doPrivileged(本机方法) 在 javax.security.auth.Subject.doAs(Subject.java:422) 在 org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1844) ... 4 更多 原因:java.io.IOException: 无法连接到 ip-xxxx-xxx.ap-southeast-2.compute.internal/xxx-xxxx:41885 在 org.apache.spark.network.client.TransportClientFactory.createClient(TransportClientFactory.java:245) 在 org.apache.spark.network.client.TransportClientFactory.createClient(TransportClientFactory.java:187) 在 org.apache.spark.rpc.netty.NettyRpcEnv.createClient(NettyRpcEnv.scala:198) 在 org.apache.spark.rpc.netty.Outbox$$anon$1.call(Outbox.scala:194) 在 org.apache.spark.rpc.netty.Outbox$$anon$1.call(Outbox.scala:190) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 在 java.lang.Thread.run(Thread.java:748) 引起:io.netty.channel.AbstractChannel$AnnotatedConnectException:连接被拒绝:ip-xxxxxxxxx.ap-southeast-2.compute.internal/xxxxxx:41885 在 sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) 在 sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717) 在 io.netty.channel.socket.nio.NiosocketChannel.doFinishConnect(NioSocketChannel.java:323) 在 io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:340) 在 io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:633) 在 io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized (NioEventLoop.java:580) 在 io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) 在 io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) 在 io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) 在 io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138) ... 1 更多 引起:java.net.ConnectException:连接被拒绝 ... 11 更多 日志类型结束:stderr

虽然我已经编辑了上面的 IP 地址(安全第一),但它与 spark 从属实例上的内部 IP 地址相同。它似乎正在连接到自身并出现连接问题。

我在 AWS EC2 安全组中开放了端口,允许从 spark 主/从访问 presto 实例。

如果有帮助,编写用于测试连接性的快速节点脚本可以工作

var client = new presto.Client(
  host: prestoEndpoint,
  user: 'hadoop',
  port: 8889,
);

client.execute(
  query: 'select * from customer',
  catalog: 'hive',
  schema: 'data-lake',
  source: 'nodejs-client',
  state: function(error, query_id, stats) 
     console.log( message: 'status changed', id: query_id, stats: stats );
  ,
  columns: function(error, data) 
     console.log( resultColumns: data );
  ,
  data: function(error, data, columns, stats) 
    console.log(data, columns);
  ,
  success: function(error, stats) 
     console.log(error);
     console.log(JSON.stringify(stats, null,2));
  ,
  error: function(error) 
    console.log(error);
  ,
);

错误信息的关键部分似乎是

原因:io.netty.channel.AbstractChannel$AnnotatedConnectException:连接被拒绝:ip-xxxxxxxxx.ap-southeast-2.compute.internal/xxxxxx:41885

【问题讨论】:

什么是com.facebook.presto:presto-jdbc:0.60? EMR 的 Presto 版本应为 0.2xx,如 0.219、0.225 等。 0.60 寻找真正旧的 presto 版本。 有趣,我会试试@Lamanus。谢谢。 @Lamanus 回到甲板上并试一试,看起来您可以使用版本号进行操作。我已经更新到 0.255,我收到一条新的错误消息AttributeError: 'DataFrame' object has no attribute '_get_object_id'' 我会继续挖掘并更新我发现的内容。再次感谢。 @Lamanus 上面提到的错误是完全不相关的。版本升级成功了。现在工作! 【参考方案1】:

问题是 prest-jdbc 驱动的版本号

我将它从 com.facebook.presto:presto-jdbc:0.60 更新为 com.facebook.presto:presto-jdbc:0.225 所以完整的包参数是

--packages,\'org.apache.spark:spark-streaming-kinesis-asl_2.11:2.4.0,org.postgresql:postgresql:42.2.9,com.facebook.presto:presto-jdbc:0.255\',\

感谢@Lamanus 发现了那个

【讨论】:

以上是关于从 EMR spark 连接到 EMR presto - 连接失败的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Pyspark 从 EMR 集群连接到雪花

无法使用Pyspark从EMR群集连接到Snowflake

EMR LinkageError 上的 Spark + Cassandra

在 emr 集群上安装 com.databricks.spark.xml

用于 Apache Hadoop 的 emr-dynamodb-connector

为啥我们在启用 Kerberos 的 EMR 集群上使用直线连接到 Hive 时使用 Hive 服务主体?