程序员人生 网站导航

基于0.14.0版本配置HiveServer2

栏目:数据库应用时间:2015-07-02 08:48:26
      项目中需要访问hive作为mondrian的异种数据源履行MDX查询,而我1般使用hive的时候都是直接通过hive命令行的方式直接履行SQL,或通过hive的jar包在程序中访问,在这类方式的使用进程中,访问的hadoop集群都是公司的集群,之前测试hive的进程中记得自己对hive的jdbc源码进行了修改,主要是修改了1些hive在实现jdbc中没有实现但是抛出异常的接口,而mondrian会调用这些接口致使下面的流程走不下去了,整体的修改应当说还是比较简单的。另外1个问题是当时的hive是没有使用任何认证机制的,包括hadoop也是没有认证机制的,现在在公司的hadoop集群上跑需要使用kerberos认证,这1块自己还不熟习,还只是知道怎样用,所以还需要恶补了1下关于kerberos认证的知识。
      下面介绍1下我对hive几种使用方式的理解,首先是hive的元数据库,它分为3种情势的,第1种是内嵌的derby数据库,这类方式由于derby会在当前目录创建1个目录,所以智能启动1个hive实例,第2种方式是使用远程数据库,也就是使用1个关系数据库系统,例如mysql等(目前只测试了mysql),hive通过jdbc连接mysql获得元数据信息,还有1种方式是hive自带的metaserver,这个server是用来关系元数据的,相当于在真实的元数据管理器之前又搭了1个服务。
      在使用的进程中主要有两种方式使用hive,第1种就是仅仅把hive作为1个可以对文件使用SQL查询的根据来使用,也就是直接使用hive命令行,亦或在程序中使用hive提供的函数启动,在这类情况下我们只需要配置好hive元数据服务器(告知hive存储了哪些数据库和表和其属性)和hive的数据仓库目录(1般是1个HDFS的目录),经过测试数据仓库的目录只是在创建数据库的时候有作用,在创建表的时候会在所在数据库的目录下创建表的目录,另外还需要指定hadoop的配置文件和jar包,毕竟hive依赖于hadoop履行任务。
      第2种方式就是讲hive作为1个提供了SQL接口的数据库使用,我们可以通过jdbc的方式访问它,类似于使用mysql的方式,本文主要介绍的就是如何配置这个服务器并且使用hive自带的客户端和使用jdbc的方式连接使用。
      接下来就是对hive进行环境配置了,对hive,我的1般使用方式是使用远程的mysql做为源数据服务器。而不使用hive自带的matestore服务器,貌似后者能支持更大的并发,这个暂时没需求就简单的来,除元数据库还有1个重点就是数据仓库地址,我配置的我的个人用户intern的目录/user/intern,具体配置以下:
<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>

      另外,这里对hive元数据的创建还需要注意1下,1般情况下我们会选择使用utf8作为数据库默许的字符集(应当是为了支持中文),但是如果你使用utf8字符集hive会出现很多稀里糊涂的毛病,让人摸不到头脑,所以需要再创建hive数据库的时候需要指定字符集为latin1,另外还可让hive自动帮你创建(我没有尝试过,不知道是不是可行)。

接下来还需要配置1些关于kerberos认证的东西,具体的配置内容以下:
<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>

      这3个配置项分别是配置hiveserver2的认证方式,如果配置不得当客户端会出现很多问题,默许情况下认证方式是CUSTOM,这里我们配置成KERBEROS,然后配置kerberos认证需要的keytab文件和principal,1般情况下我们履行kinit也就是需要这两样东西,不过不同的是这里的principal需要指定完成的,而不只是@符号前面的东西(kinit的时候只指定前面的东西就能够了),另外需要注意的是这里的keytab对应的用户必须在hadoop上具有可代理履行的权限,这是hiveserver2所需要的,也就是说其实hiveserver2只是1个指定代理的服务器,不同的用户通过jdbc连接到hiveserver2,根据客户端不同的keytab用户代理不同的用户履行具体的操作。如果该用户没有代理的权限,在使用jdbc和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用户,这个用户具有代理权限,而我使用jdbc连接的机器使用的用户是intern,首先在hive机器上履行启动hiveserver2的命令:
./bin/hive --service hiveserver2

然后再客户真个机器上通过hive自带的beeline进行连接:
./bin/beeline

然后使用connect命令连接hiveserver2:
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⑵0.photo.163.org@HADOOP.HZ.NETEASE.COM; Enter username for jdbc:hive2://bitest0.server.163.org:10000/foodmart;principal=hive/app⑵0.photo.163.org@HADOOP.HZ.NETEASE.COM;: Enter password for jdbc:hive2://bitest0.server.163.org:10000/foodmart;principal=hive/app⑵0.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/>

      连接的时候需要指定jdbc的url(默许的端口号为10000,也能够在hiveserver2的配置文件中配置),另外还需要制定服务器的principal,也就是在上面配置的那个hive.server2.authentication.kerberos.principal,而客户端用户使用的用户就是客户真个当前用户,可使用klist查看。

除使用自带的beeline连接,还可以在程序中使用jdbc进行连接,测试代码以下:
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:UsersAdministratorDesktopintern.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)) + " " + res.getString(2)); } } }

      好了,这里说完了如何搭建1个使用kerberos认证的hiveserver2,下1篇在介绍如何使用hive作为mondrian的数据源履行MDX查询。

      最后的最后,介绍1下遇到的1个最大的问题,在配置kerberos认证的时候,我使用的hive版本是0.13.1,依照上面的配置出现了以下的问题:
2015-04⑶0 17:02:22,602 ERROR [Thread⑹]: 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⑶0 17:02:22,605 INFO [Thread[Thread⑺,5,main]]: delegation.AbstractDelegationTokenSecretManager (AbstractDelegationTokenSecretManager.java:updateCurrentKey( 222)) - Updating the current master key for generating delegation tokens 2015-04⑶0 17:02:22,612 INFO [Thread⑶]: server.HiveServer2 (HiveStringUtils.java:run(623)) - SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down HiveServer2 at bitest0.server.163.org/10.120.36.85 ************************************************************/

        最后在google找了1下相干的毛病,发现了HIVE的这个bug:https://issues.apache.org/jira/browse/HIVE⑺620
不知道我遇到的是否是这个问题,但是不管如何就是解决不了这个问题(其实可以说是束手无策),我就换了1下hive的版本,上看说在0.14.0已解决,我就换成了新的版本,果然这个问题不再出现了,至于究竟是否由这个bug引发也不得而知了。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐