无法使用java连接到aws emr上的配置单元

cld4siwp  于 2021-06-02  发布在  Hadoop
关注(0)|答案(3)|浏览(443)

我已经安装了aws emr集群和hive。我想使用java从本地机器连接到hive thrift服务器。我试着遵循代码-

Class.forName("com.amazon.hive.jdbc3.HS2Driver");
con = DriverManager.getConnection("jdbc:hive2://ec2XXXX.compute-1.amazonaws.com:10000/default","hadoop", "");

http://docs.aws.amazon.com/elasticmapreduce/latest/developerguide/hivejdbcdriver.html.as 在开发人员指南中提到,在类路径中添加了与hivejdbc驱动程序相关的jar。但我在尝试连接时遇到了异常。我能够使用上述代码(使用不同的jdbc驱动程序)连接到简单hadoop集群上的hive服务器。如果我遗漏了什么,有人能给我建议吗?是否可以使用配置单元jdbc从本地计算机连接到aws emr上的配置单元服务器?

dbf7pr2w

dbf7pr2w1#

不知道你是否已经解决了这个问题,但它是一个错误,在电子病历刚刚咬我。
对于像您这样的直接jdbc连接,您必须在您的uberjar中包含jdbc驱动程序。对于从dataframes中访问jdbc,您不能访问uber jar中的jar(另一个无关的bug),但必须在命令行中指定它(s3是保存它们的方便地方):
--文件s3://mybucketjar/postgresql-9.4-1201.jdbc4.jar
然而,即使在这之后,如果您特别尝试访问hive,您也会遇到另一个问题。amazon构建了自己的jdbc驱动程序,其类层次结构与普通的hive驱动程序(com.amazon.hive.jdbc41.hs2driver)不同,但是emr集群在其标准路径(org.apache.hive.jdbc.hivedriver)中包含了标准的HiveJDBC驱动程序。
这将自动注册为能够处理jdbc:hive and jdbc:hive2 urls,因此,当您尝试连接到配置单元url时,它会首先找到并使用该url—即使您专门注册了amazon url。不幸的是,这个与amazon的emr构建的hive不兼容。
有两种可能的解决方案:
1:找到有问题的驱动程序并注销它:scala示例:

val jdbcDrv = Collections.list(DriverManager.getDrivers)

for(i <- 0 until jdbcDrv.size) {
  val drv = jdbcDrv.get(i)
  val drvName = drv.getClass.getName

  if(drvName == "org.apache.hive.jdbc.HiveDriver") {
    log.info(s"Deregistering JDBC Driver: ${drvName}")
    DriverManager.deregisterDriver(drv)
  }
}

或2:正如我后来发现的,您可以在尝试连接时将驱动程序指定为连接属性的一部分:
例如:

val hiveCredentials = new java.util.Properties
hiveCredentials.setProperty("user", hiveDBUser)
hiveCredentials.setProperty("password", hiveDBPassword)
hiveCredentials.setProperty("driver", "com.amazon.hive.jdbc41.HS2Driver")

val conn = DriverManager.getConnection(hiveDBURL, hiveCredentials)

这是一个更“正确”的版本,因为它应该覆盖任何预注册的处理程序,即使它们具有完全不同的类层次结构。

5ssjco0h

5ssjco0h2#

(合并评论中的答案)
hive在端口10000上运行,但仅在本地运行,您必须创建一个到emr的ssh隧道。
以下内容来自Hive0.13.1的文档
创建隧道

ssh -o ServerAliveInterval=10 -i path-to-key-file -N -L 10000:localhost:10000 hadoop@master-public-dns-name

连接到jdbc

jdbc:hive2://localhost:10000/default
13z8s7eq

13z8s7eq3#

您可以使用jsch库来使用代码

public static void portForwardForHive() {
    try {
        if(session != null && session.isConnected()) {
            return;
        }

        JSch jsch = new JSch();
        jsch.addIdentity(PATH_TO_SSH_KEY_PEM);
        String host = REMOTE_HOST;
        session = jsch.getSession(USER, host, 22);

        // username and password will be given via UserInfo interface.
        UserInfo ui = new MyUserInfo();
        session.setUserInfo(ui);

        session.connect();
        int assingedPort = session.setPortForwardingL(LPORT, RHOST, RPORT);
        System.out.println("Port forwarding done for the post : " + assingedPort);
    } catch (Exception e) {
        System.out.println(e);
    }
}

相关问题