使用jdbc时spark-submit netty NoSuchMethodError

时间:2017-05-31 09:20:45

标签: scala apache-spark jdbc netty

我一直在尝试使用spark-submit运行我的工作,当我使用jdbc从Postgresql获取DataFrame时我遇到了问题。

首先,jdbc驱动程序在我的工作jar中但我必须在我的代码中加载这样的驱动程序

sparkSession.read.option("driver", "org.postgresql.Driver").jdbc(jdbcdn, query, props)

这很好,并且与数据库建立连接,我知道这一点,因为如果找不到服务器,我会从驱动程序中收到相应的异常。 但是如果连接成功,我总是收到以下异常并且作业挂起:

17/05/31 10:56:16 ERROR server.TransportRequestHandler: Error sending result StreamResponse{streamId=/jars/bibi-1.0.0-spark.jar, byteCount=3345077, body=FileSegmentManagedBuffer{file=/srv/jobs/bibi-1.0.0-spark.jar, offset=0, length=3345077}} to /127.0.0.1:50087; closing connection
io.netty.handler.codec.EncoderException: java.lang.NoSuchMethodError: io.netty.channel.DefaultFileRegion.<init>(Ljava/io/File;JJ)V
    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:651)
    at io.netty.handler.timeout.IdleStateHandler.write(IdleStateHandler.java:266)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:706)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:741)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:895)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:240)
    at org.apache.spark.network.server.TransportRequestHandler.respond(TransportRequestHandler.java:194)
    at org.apache.spark.network.server.TransportRequestHandler.processStreamRequest(TransportRequestHandler.java:150)
    at org.apache.spark.network.server.TransportRequestHandler.handle(TransportRequestHandler.java:111)
    at org.apache.spark.network.server.TransportChannelHandler.channelRead(TransportChannelHandler.java:118)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:254)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at org.apache.spark.network.util.TransportFrameDecoder.channelRead(TransportFrameDecoder.java:85)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:130)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoSuchMethodError: io.netty.channel.DefaultFileRegion.<init>(Ljava/io/File;JJ)V
    at org.apache.spark.network.buffer.FileSegmentManagedBuffer.convertToNetty(FileSegmentManagedBuffer.java:133)
    at org.apache.spark.network.protocol.MessageEncoder.encode(MessageEncoder.java:58)
    at org.apache.spark.network.protocol.MessageEncoder.encode(MessageEncoder.java:33)
    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89)
    ... 34 more

我尝试了以下(我正在使用Gradle)

  • 从我的项目中排除netty依赖项
  • 在我的shadowJar
  • 中加入netty版本
  • 重新定位包含的网络

但我尝试的一切都没有效果。 我想知道的是我在注册驱动程序时遇到的问题,因为你可以在网上找到的所有标准方法都不适用于spark / scala / jdbc,我不得不使用上面的代码。 在我看来,jdbc调用是在它自己的环境中,无论我在我的项目gradle中做什么都没有影响这个环境。

由于option("driver", "org.postgresql.Driver")很难找到,我想知道这里是否存在未记录的内容,以及是否必须找到一种方法来指示jdbc运行时使用哪个netty版本。

1 个答案:

答案 0 :(得分:1)

好的,所以我继续我的搜索,终于找到了发生了什么。 我自己安装了spark-master和hadoop服务器,因为hadoop jar将在同一台服务器上,我安装了没有hadoop的spark。

使用&#34; hadoop classpath&#34;将Hadoop jar添加到spark类路径中命令。

事情是,hadoop 2.7.3船用netty 3.6.2 / 4.0.23Final而火花船用netty 3.8.0 / 4.0.42.Final 最后两人都在类路径上引发了问题。

我所做的是将两个netty jar从spark复制到hadoop中的所有地方,基本上升级了hadoop使用的netty版本。

到目前为止我没有看到问题,但我使用了hadoop可以做的一小部分,可能会出现问题。

编辑:另一个快速解决方法是使用spark-with-hadoop tar并且不添加hadoop类路径,这样两者都使用自己的jar而不会相互冲突。 这实际上是我最终做的,因为我在访问sparkUI时遇到了另一个jar冲突,并且无法通过像我使用netty那样复制jar来纠正它。

结论是:永远不要使用spark-without-hadoop下载。