另外,这里对于 hive 元数据的创建还需要注意一下,一般情况下我们会选择使用 utf8 作为数据库默认的字符集(应该是为了支持中文),但是如果你使用 utf8 字符集 hive 会出现很多莫名其妙的错误,让人摸不到头脑,所以需要再创建 hive 数据库的时候需要指定字符集为 latin1,另外还可以让 hive 自动帮你创建(我没有尝试过,不知道是否可行)。 接下来还需要配置一些关于 kerberos 认证的东西,具体的配置内容如下:
- <property>
- <name>
- hive.metastore.warehouse.dir
- </name>
- <value>
- /user/intern/
- </value>
- <description>
- location of default database for the warehouse
- </description>
- </property>
- <property>
- <name>
- javax.jdo.option.ConnectionURL
- </name>
- <value>
- jdbc:mysql://127.0.0.1:3306/HIVE
- </value>
- <description>
- JDBC connect string for a JDBC metastore
- </description>
- </property>
- <property>
- <name>
- javax.jdo.option.ConnectionDriverName
- </name>
- <value>
- com.mysql.jdbc.Driver
- </value>
- <description>
- Driver class name for a JDBC metastore
- </description>
- </property>
- <property>
- <name>
- javax.jdo.option.ConnectionUserName
- </name>
- <value>
- root
- </value>
- <description>
- username to use against metastore database
- </description>
- </property>
- <property>
- <name>
- javax.jdo.option.ConnectionPassword
- </name>
- <value>
- root
- </value>
- <description>
- password to use against metastore database
- </description>
- </property>
这三个配置项分别是配置 hiveserver2 的认证方式,如果配置不得当客户端会出现很多问题,默认情况下认证方式是 CUSTOM,这里我们配置成 KERBEROS,然后配置 kerberos 认证需要的 keytab 文件和 principal,一般情况下我们执行 kinit 也就是需要这两样东西,不过不同的是这里的 principal 需要指定完成的,而不只是 @符号前面的东西(kinit 的时候只指定前面的东西就可以了),另外需要注意的是这里的 keytab 对应的用户必须在 hadoop 上具有可代理执行的权限,这是 hiveserver2 所需要的,也就是说其实 hiveserver2 只是一个指定代理的服务器,不同的用户通过 jdbc 连接到 hiveserver2,根据客户端不同的 keytab 用户代理不同的用户执行具体的操作。如果该用户没有代理的权限,在使用 jdbc 和 hiveserver2 建立连接的时候会出现认证错误,错误的堆栈为:
- <property>
- <name>
- hive.server2.authentication
- </name>
- <value>
- KERBEROS
- </value>
- <description>
- Client authentication types. NONE: no authentication check LDAP: LDAP/AD
- based authentication KERBEROS: Kerberos/GSSAPI authentication CUSTOM: Custom
- authentication provider (Use with property hive.server2.custom.authentication.class)
- PAM: Pluggable authentication module.
- </description>
- </property>
- <property>
- <name>
- hive.server2.authentication.kerberos.principal
- </name>
- <value>
- hive/xxx@HADOOP.XXX.COM
- </value>
- <description>
- Kerberos server principal
- </description>
- </property>
- <property>
- <name>
- hive.server2.authentication.kerberos.keytab
- </name>
- <value>
- /home/hzfengyu/hive.keytab
- </value>
- <description>
- Kerberos keytab file for server principal
- </description>
- </property>
这里我用的是 hive 用户,这个用户具有代理权限,而我使用 jdbc 连接的机器使用的用户是 intern,首先在 hive 机器上执行启动 hiveserver2 的命令:
- 15 / 05 / 01 17 : 32 : 33[main] : ERROR transport.TSaslTransport: SASL negotiation failure javax.security.sasl.SaslException: GSS initiate failed[Caused by GSSException: No valid credentials provided(Mechanism level: Server not found in Kerberos database(7) - UNKNOWN_SERVER)] at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(GssKrb5Client.java: 212) at org.apache.thrift.transport.TSaslClientTransport.handleSaslStartMessage(TSaslClientTransport.java: 94) at org.apache.thrift.transport.TSaslTransport.open(TSaslTransport.java: 253) at org.apache.thrift.transport.TSaslClientTransport.open(TSaslClientTransport.java: 37) at org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport$1.run(TUGIAssumingTransport.java: 52) at org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport$1.run(TUGIAssumingTransport.java: 49) at java.security.AccessController.doPrivileged(Native Method)
然后再客户端的机器上通过 hive 自带的 beeline 进行连接:
- . / bin / hive--service hiveserver2
然后使用 connect 命令连接 hiveserver2:
- . / bin / beeline
连接的时候需要指定 jdbc 的 url(默认的端口号为 10000,也可以在 hiveserver2 的配置文件中配置),另外还需要制定服务器的 principal,也就是在上面配置的那个 hive.server2.authentication.kerberos.principal,而客户端用户使用的用户就是客户端的当前用户,可以使用 klist 查看。 除了使用自带的 beeline 连接,还可以在程序中使用 jdbc 进行连接,测试代码如下:
- beeline > !connect jdbc: hive2: //hiveserver2-ip:10000/foodmart;principal=hive/xxx@HADOOP.XXX.COM;
- scan complete in 34ms Connecting to jdbc: hive2: //bitest0.server.163.org:10000/foodmart;principal=hive/app-20.photo.163.org@HADOOP.HZ.NETEASE.COM;
- Enter username
- for jdbc: hive2: //bitest0.server.163.org:10000/foodmart;principal=hive/app-20.photo.163.org@HADOOP.HZ.NETEASE.COM;:
- Enter password
- for jdbc: hive2: //bitest0.server.163.org:10000/foodmart;principal=hive/app-20.photo.163.org@HADOOP.HZ.NETEASE.COM;:
- Connected to: Apache Hive(version 0.14.0) Driver: Hive JDBC(version 0.14.0) Transaction isolation: TRANSACTION_REPEATABLE_READ 0 : jdbc: hive2: //bitest0.server.163.org:10000/>
- import java.io.IOException;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.sql.Statement;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.security.UserGroupInformation;
- public class TestHive {
- public static void main(String[] args) throws SQLException {
- try {
- Class.forName("org.apache.hive.jdbc.HiveDriver");
- } catch(ClassNotFoundException e) {
- e.printStackTrace();
- }
- Configuration conf = new Configuration();
- conf.setBoolean("hadoop.security.authorization", true);
- conf.set("hadoop.security.authentication", "kerberos");
- UserGroupInformation.setConfiguration(conf);
- try {
- UserGroupInformation.loginUserFromKeytab("intern/bigdata", "C:\\Users\\Administrator\\Desktop\\intern.keytab");
- } catch(IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- Connection conn = DriverManager.getConnection("jdbc:hive2://hiveserver2-ip:10000/foodmart;principal=hive/xxx@HADOOP.XXX.COM;User=;Password=;", "", "");
- Statement stmt = conn.createStatement();
- String sql = "select * from account limit 10";
- System.out.println("Running: " + sql);
- ResultSet res = stmt.executeQuery(sql);
- while (res.next()) {
- System.out.println(String.valueOf(res.getInt(1)) + "\t" + res.getString(2));
- }
- }
- }
最后在 google 找了一下相关的错误,发现了 HIVE 的这个 bug: 不知道我遇到的是不是这个问题,但是无论如何就是解决不了这个问题(其实可以说是束手无策),我就换了一下 hive 的版本,上看说在 0.14.0 已经解决,我就换成了新的版本,果然这个问题不再出现了,至于到底是否由这个 bug 引起也不得而知了。
- 2015 - 04 - 30 17 : 02 : 22,
- 602 ERROR[Thread - 6] : thrift.ThriftCLIService(ThriftBinaryCLIService.java: run(93)) - Error: java.lang.NoSuchFieldError: SASL_PROPS at org.apache.hadoop.hive.thrift.HadoopThriftAuthBridge20S.getHadoopSaslProperties(HadoopThriftAuthBridge20S.java: 126) at org.apache.hive.service.auth.HiveAuthFactory.getSaslProperties(HiveAuthFactory.java: 116) at org.apache.hive.service.auth.HiveAuthFactory.getAuthTransFactory(HiveAuthFactory.java: 133) at org.apache.hive.service.cli.thrift.ThriftBinaryCLIService.run(ThriftBinaryCLIService.java: 43) at java.lang.Thread.run(Thread.java: 701) 2015 - 04 - 30 17 : 02 : 22,
- 605 INFO[Thread[Thread - 7, 5, main]] : delegation.AbstractDelegationTokenSecretManager(AbstractDelegationTokenSecretManager.java: updateCurrentKey(222)) - Updating the current master key
- for generating delegation tokens 2015 - 04 - 30 17 : 02 : 22,
- 612 INFO[Thread - 3] : server.HiveServer2(HiveStringUtils.java: run(623)) - SHUTDOWN_MSG:
- /************************************************************
- SHUTDOWN_MSG: Shutting down HiveServer2 at bitest0.server.163.org/10.120.36.85
- ************************************************************/
来源: http://lib.csdn.net/article/hive/49978