简体   繁体   English

Hive JDBC连接问题

[英]Hive JDBC connection problems

I am trying to connect to Hive2 server via JDBC with kerberos authentication. 我正在尝试使用Kerberos身份验证通过JDBC连接到Hive2服务器。 After numerous attempts to make it work, I can't get it to work with the Cloudera driver. 经过多次尝试使其工作后,我无法将其与Cloudera驱动程序一起使用。

If someone can help me to solve the problem, I can greatly appreciate it. 如果有人可以帮助我解决问题,我将不胜感激。

I have this method: 我有这种方法:

    private Connection establishConnection() {
    final String driverPropertyClassName = "driver";
    final String urlProperty = "url";
    Properties hiveProperties = config.getMatchingProperties("hive.jdbc");
    String driverClassName = (String) hiveProperties.remove(driverPropertyClassName);
    String url = (String) hiveProperties.remove(urlProperty);
    Configuration hadoopConfig = new Configuration();
    hadoopConfig.set("hadoop.security.authentication", "Kerberos");
    String p = config.getProperty("hadoop.core.site.path");
    Path path = new Path(p);
    hadoopConfig.addResource(path);
    UserGroupInformation.setConfiguration(hadoopConfig);

    Connection conn = null;
    if (driverClassName != null) {
        try {
            UserGroupInformation.loginUserFromKeytab(config.getProperty("login.user"), config.getProperty("keytab.file"));
            Driver driver = (Driver) Class.forName(driverClassName).newInstance();
            DriverManager.registerDriver(driver);
            conn = DriverManager.getConnection(url, hiveProperties);
        } catch (Throwable e) {
            LOG.error("Failed to establish Hive connection", e);
        }
    }
    return conn;
}

URL for the server, that I am getting from the properties in the format described in Cloudera documentation 我从Cloudera 文档中所述格式的属性中获取的服务器URL

I am getting an exception: 我有一个例外:

2018-05-05 18:26:49 ERROR HiveReader:147 - Failed to establish Hive connection
java.sql.SQLException: [Cloudera][HiveJDBCDriver](500164) Error initialized or created transport for authentication: Peer indicated failure: Unsupported mechanism type PLAIN.
    at com.cloudera.hiveserver2.hivecommon.api.HiveServer2ClientFactory.createTransport(Unknown Source)
    at com.cloudera.hiveserver2.hivecommon.api.ZooKeeperEnabledExtendedHS2Factory.createClient(Unknown Source)
...

I thought, that it is missing AuthMech attribute and added AuthMech=1 to the URL. 我以为它缺少AuthMech属性,并向URL添加了AuthMech = 1。 Now I am getting: 现在我得到:

java.sql.SQLNonTransientConnectionException: [Cloudera][JDBC](10100) Connection Refused: [Cloudera][JDBC](11640) Required Connection Key(s): KrbHostFQDN, KrbServiceName; [Cloudera][JDBC](11480) Optional Connection Key(s): AsyncExecPollInterval, AutomaticColumnRename, CatalogSchemaSwitch, DecimalColumnScale, DefaultStringColumnLength, DelegationToken, DelegationUID, krbAuthType, KrbRealm, PreparedMetaLimitZero, RowsFetchedPerBlock, SocketTimeOut, ssl, StripCatalogName, transportMode, UseCustomTypeCoercionMap, UseNativeQuery, zk
    at com.cloudera.hiveserver2.exceptions.ExceptionConverter.toSQLException(Unknown Source)
    at com.cloudera.hiveserver2.jdbc.common.BaseConnectionFactory.checkResponseMap(Unknown Source)
    ...

But KrbHostFQDN is already specified in the principal property as required in the documentation. 但是已经按照文档中的要求在主体属性中指定了KrbHostFQDN。

Am I missing something or is this documentation wrong? 我是否缺少某些内容或此文档有误?

Below is the one of the similar kind of problem statement in Impala (just JDBC engine changes others are same) that is resolved by setting "KrbHostFQDN" related properties in JDBC connection string itself. 下面是Impala中一种类似的问题声明(只是JDBC引擎的其他更改相同),可以通过在JDBC连接字符串本身中设置“ KrbHostFQDN”相关属性来解决。

Try to use the URL below. 尝试使用下面的URL。 Hopefully works for u. 希望为你工作。

String jdbcConnStr = "jdbc:impala://myserver.mycompany.corp:21050/default;SSL=1;AuthMech=1;KrbHostFQDN=myserver.mycompany.corp;KrbRealm=MYCOMPANY.CORP;KrbServiceName=impala"

I suppose that if you are not using SSL=1 but only Kerberos, you just drop that part from the connection string and don't worry about setting up SSL certificates in the java key store, which is yet another hassle. 我想如果您不使用SSL = 1而是仅使用Kerberos,则只需从连接字符串中删除该部分,而不必担心在Java密钥存储区中设置SSL证书,这是另一个麻烦。

However in order to get Kerberos to work properly we did the following: 但是,为了使Kerberos正常工作,我们执行了以下操作:

  • Install MIT Kerberos 4.0.1, which is a kerberos ticket manager. 安装MIT Kerberos 4.0.1,这是一个kerberos票证管理器。 (This is for Windows) (这是用于Windows)

  • This ticket manager asks you for authentication every time you initiate a connection, creates a ticket and stores it in a kerberos_ticket.dat binary file, whose location can be configured somehow but I do not recall exactly how. 每次启动连接时,该票务管理器都会要求您进行身份验证,创建票证并将其存储在kerberos_ticket.dat二进制文件中,该文件的位置可以通过某种方式配置,但我不记得确切的方式。

  • Finally, before launching your JAVA app you have to set an environment variable KRB5CCNAME=C:/path/to/kerberos_ticket.dat . 最后,在启动JAVA应用程序之前,您必须设置环境变量KRB5CCNAME=C:/path/to/kerberos_ticket.dat In your java app, you can check that the variable was correctly set by doing System.out.println( "KRB5CCNAME = " + System.getenv( "KRB5CCNAME" ) ) . 在您的Java应用程序中,可以通过执行System.out.println( "KRB5CCNAME = " + System.getenv( "KRB5CCNAME" ) )来检查变量设置是否正确。 If you are working with eclipse or other IDE you might even have to close the IDE,set up the environment variable and start the IDE again. 如果您正在使用eclipse或其他IDE,则可能甚至必须关闭IDE,设置环境变量,然后再次启动IDE。

    • NOTE: this last bit is very important, I have observed that if this variable is not properly set up, the connection wont be established... 注意:这最后一点非常重要,我观察到,如果未正确设置此变量,则不会建立连接...
  • In Linux, instead MIT Kerberos 4.0.1, there is a program called kinit which does the same thing, although without a graphical interface, which is even more convenient for automation. 在Linux中,取而代之的是MIT Kerberos 4.0.1,它有一个名为kinit的程序,尽管没有图形界面,但它执行相同的功能,这对于自动化来说更加方便。

I wanted to put it in the comment but it was too long for the comment, therefore I am placing it here: I tried your suggestion and got another exception: 我想将其放入评论中,但评论已经太久了,因此我将其放置在这里:我尝试了您的建议,但又遇到了另一个例外:

java.sql.SQLException: [Cloudera]HiveJDBCDriver Error creating login context using ticket cache: Unable to obtain Principal Name for authentication . java.sql.SQLException:[Cloudera] HiveJDBCDriver使用票证缓存创建登录上下文时出错:无法获取用于身份验证的主体名称。

May be my problem is, that I do not have environment variable KRB5CCNAME set. 可能是我的问题是,我没有设置环境变量KRB5CCNAME。 I, honestly, never heard about it before. 老实说,我以前从未听说过它。 What is supposed to be in that ticket file. 该票证文件中应​​该包含什么。 I do have, however, following line in my main method: 但是,我的主要方法确实有以下几行:

System.setProperty("java.security.krb5.conf", "path/to/krb5.conf");

Which is supposed to be used by 应该由哪个使用

UserGroupInformation.loginUserFromKeytab(config.getProperty("login.user"), config.getProperty("keytab.file"));

to obtain the kerberos ticket. 以获得kerberos门票。

To solve this issue update Java Cryptography Extension for the Java version that you use in your system. 要解决此问题,请更新系统中使用的Java版本的Java密码学扩展。

  1. Here's the link when you can download JCE for Java 1.7 当您可以下载JCE for Java 1.7时,这里是链接
  2. Uncompress and overwrite those files in $JDK_HOME/jre/lib/security 解压缩并覆盖$ JDK_HOME / jre / lib / security中的那些文件
  3. Restart your computer. 重启你的电脑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM