基於0.14.0版本配置HiveServer2,0.14.0hiveserver2

來源:互聯網
上載者:User

基於0.14.0版本配置HiveServer2,0.14.0hiveserver2
      項目中需要訪問hive作為mondrian的異種資料來源執行MDX查詢,而我一般使用hive的時候都是直接通過hive命令列的方式直接執行SQL,或者通過hive的jar包在程式中訪問,在這種方式的使用過程中,訪問的hadoop叢集都是公司的叢集,之前測試hive的過程中記得自己對hive的jdbc源碼進行了修改,主要是修改了一些hive在實現jdbc中沒有實現但是拋出異常的介面,而mondrian會調用這些介面導致下面的流程走不下去了,整體的修改應該說還是比較簡單的。另外一個問題是當時的hive是沒有使用任何認證機制的,包括hadoop也是沒有認證機制的,現在在公司的hadoop叢集上跑需要使用kerberos認證,這一塊自己還不熟悉,還只是知道怎麼用,所以還需要惡補了一下關於kerberos認證的知識。      下面介紹一下我對hive幾種使用方式的理解,首先是hive的中繼資料庫,它分為三種形式的,第一種是內嵌的derby資料庫,這種方式由於derby會在目前的目錄建立一個目錄,所以智能啟動一個hive執行個體,第二種方式是使用遠端資料庫,也就是使用一個關聯式資料庫系統,例如mysql等(目前只測試了mysql),hive通過jdbc串連mysql擷取中繼資料資訊,還有一種方式是hive內建的metaserver,這個server是用來關係中繼資料的,相當於在真正的中繼資料管理器之前又搭了一個服務。      在使用的過程中主要有兩種方式使用hive,第一種就是僅僅把hive作為一個可以對檔案使用SQL查詢的根據來使用,也就是直接使用hive命令列,亦或者在程式中使用hive提供的函數啟動,在這種情況下我們只需要配置好hive中繼資料服務器(告訴hive儲存了哪些資料庫和表以及其屬性)和hive的資料倉儲目錄(一般是一個HDFS的目錄),經過測試資料倉儲的目錄只是在建立資料庫的時候有作用,在建立表的時候會在所在資料庫的目錄下建立表的目錄,另外還需要指定hadoop的設定檔和jar包,畢竟hive依賴於hadoop執行任務。      第二種方式就是講hive作為一個提供了SQL介面的資料庫使用,我們可以通過jdbc的方式訪問它,類似於使用mysql的方式,本文主要介紹的就是如何配置這個伺服器並且使用hive內建的用戶端以及使用jdbc的方式串連使用。
      接下來就是對hive進行環境配置了,對於hive,我的一般使用方式是使用遠端mysql做為來源資料伺服器。而不使用hive內建的matestore伺服器,貌似後者能支援更大的並發,這個暫時沒需求就簡單的來,除了中繼資料庫還有一個重點就是資料倉儲地址,我配置的我的個人使用者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中繼資料的建立還需要注意一下,一般情況下我們會選擇使用utf8作為資料庫預設的字元集(應該是為了支援中文),但是如果你使用utf8字元集hive會出現很多莫名其妙的錯誤,讓人摸不到頭腦,所以需要再建立hive資料庫的時候需要指定字元集為latin1,另外還可以讓hive自動幫你建立(我沒有嘗試過,不知道是否可行)。
接下來還需要配置一些關於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>

      這三個配置項分別是配置hiveserver2的認證方式,如果配置不得當用戶端會出現很多問題,預設情況下認證方式是CUSTOM,這裡我們配置成KERBEROS,然後配置kerberos認證需要的keytab檔案和principal,一般情況下我們執行kinit也就是需要這兩樣東西,不過不同的是這裡的principal需要指定完成的,而不只是@符號前面的東西(kinit的時候只指定前面的東西就可以了),另外需要注意的是這裡的keytab對應的使用者必須在hadoop上具有可代理執行的許可權,這是hiveserver2所需要的,也就是說其實hiveserver2隻是一個指定代理的伺服器,不同的使用者通過jdbc串連到hiveserver2,根據用戶端不同的keytab使用者代理程式不同的使用者執行具體的操作。如果該使用者沒有代理的許可權,在使用jdbc和hiveserver2建立串連的時候會出現認證錯誤,錯誤的堆棧為:
15/05/01 17:32:33 [main]: ERROR transport.TSaslTransport: SASL negotiation failurejavax.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 34msConnecting 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_READ0: 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:\\Users\\Administrator\\Desktop\\intern.keytab");} catch (IOException e) {// TODO Auto-generated catch blocke.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));    }  }}

      好了,這裡說完了如何搭建一個使用kerberos認證的hiveserver2,下一篇在介紹如何使用hive作為mondrian的資料來源執行MDX查詢。
      最後的最後,介紹一下遇到的一個最大的問題,在配置kerberos認證的時候,我使用的hive版本是0.13.1,按照上面的配置出現了如下的問題:
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 tokens2015-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************************************************************/

        最後在google找了一下相關的錯誤,發現了HIVE的這個bug:https://issues.apache.org/jira/browse/HIVE-7620不知道我遇到的是不是這個問題,但是無論如何就是解決不了這個問題(其實可以說是束手無策),我就換了一下hive的版本,上看說在0.14.0已經解決,我就換成了新的版本,果然這個問題不再出現了,至於到底是否由這個bug引起也不得而知了。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.