日复一日伐树的熊哥

日复一日伐树的熊哥

JDBC

HiveServer2 有一个 JDBC 驱动程序。它支持对 HiveServer2 的嵌入式和 remote 访问。 Remote HiveServer2 模式建议用于 production 使用,因为它更安全,不需要为用户授予直接 HDFS/metastore 访问权限。

连接 URL
连接 URL 格式

HiveServer2 URL 是一个 string,语法如下:

jdbc:hive2://<host1>:<port1>,<host2>:<port2>/dbName;initFile=<file>;sess_var_list?hive_conf_list#hive_var_list
  • :,:是要连接的服务器实例或以逗号分隔的服务器实例列表(如果启用了动态服务发现)。如果为空,将使用嵌入式服务器。
  • dbName是初始数据库的 name。
  • 是 init 脚本文件的路径(Hive 2.2.0和更高版本)。此脚本文件使用 SQL statements 编写,将在连接后自动执行。此选项可以为空。
  • sess_var_list是以分号分隔的 key=value 对 session 变量(e.g. ,user=foo;password=bar)的列表。
  • hive_conf_list是这个 session 的 key=value 对 Hive configuration 变量的分号分隔列表
  • hive_var_list是此 session 的 key=value 对 Hive 变量的分号分隔列表。

如果需要,sess_var_list, hive_conf_list, hive_var_list参数值中的特殊字符应使用 URL 编码进行编码。

Remote 或嵌入模式的连接 URL

JDBC 连接 URL 格式的前缀为jdbc:hive2://,Driver class 为org.apache.hive.jdbc.HiveDriver。请注意,这与旧的HiveServer不同。

  • 对于 remote 服务器,URL 格式为jdbc:hive2://:/;initFile=(HiveServer2 的默认 port 为 10000)。
  • 对于嵌入式服务器,URL 格式为jdbc:hive2:///;initFile=(无 host 或 port)。

initFile选项在Hive 2.2.0及更高版本中可用。

当 HiveServer2 在 HTTP 模式下 Running 时连接 URL

JDBC 连接 URL:jdbc:hive2://:/;transportMode=http;httpPath=<http_endpoint>,其中:

  • <http_endpoint>是hive-site.xml中配置的相应 HTTP 端点。默认 value 是cliservice。
  • HTTP 传输模式的默认 port 是 10001。

早于 0.14 的版本
在早于0.14的版本中,这些参数过去分别被称为hive.server2.transport.mode和hive.server2.thrift.http.path,并且是 hive_conf_list 的一部分。这些版本已被弃用,以支持新版本(它们是 sess_var_list 的一部分),但现在仍在继续使用。

在 HiveServer2 中启用 SSL 时的连接 URL

JDBC 连接 URL:

jdbc:hive2://<host>:<port>/<db>;ssl=true;sslTrustStore=<trust_store_path>;trustStorePassword=<trust_store_password>
  • < 1 >是 client 的信任库文件所在的路径。
  • < 1 >是访问信任库的密码。

在 HTTP 模式下:

jdbc:hive2://<host>:<port>/<db>;ssl=true;sslTrustStore=<trust_store_path>;trustStorePassword=<trust_store_password>;transportMode=http;httpPath=<http_endpoint>
启用 ZooKeeper 服务发现时的连接 URL

Hive 0.14.0(HIVE-7935)中引入的 ZooKeeper-based 服务发现可实现 HiveServer2 的高可用性和滚动升级。需要使用指定的 JDBC URL 来使用这些 features。
随着 Hive 2.0.0 和 1.3.0(未发布,HIVE-11581)的进一步更改,需要指定其他 configuration 参数,例如身份验证模式,传输模式或 SSL 参数,因为它们是从 ZooKeeper 条目和主机名一起检索的。
JDBC 连接 URL:

jdbc:hive2://<zookeeper quorum>/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2

与 HiveServer2 使用的 hive-site.xml/hivserver2-site.xml 中 hive.zookeeper.quorum configuration 参数的 value 相同。
查询所需的其他运行时参数可以在 URL 中提供,如下所示,方法是将其附加到? 和以前一样。
JDBC 连接 URL:

jdbc:hive2://<zookeeper quorum>/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2?tez.queue.name=hive1&hive.server2.thrift.resultset.serialize.in.tasks=true
命名连接 URL

从 Hive 2.1.0(HIVE-13670)开始,Beeline 现在还通过使用环境变量来支持命名的 URL 连接 strings。如果您尝试将!connect设置为不像 URL 的 name,则 Beeline 将尝试查看是否存在名为 BEELINE_URL_ 的环境变量。例如,如果指定!connect blue,它将查找 BEELINE_URL_BLUE,并使用它进行连接。这应该使系统管理员更容易为用户指定环境变量,并且用户无需在每个 time 时键入完整的 URL 进行连接。

重新连接

传统上,!reconnect已经努力刷新已经建立的连接。 !close运行后,无法进行全新连接。从 Hive 2.1.0(HIVE-13670)开始,Beeline 会记住在 session 中成功连接的最后一个 URL,并且即使已经 run 也可以重新连接。此外,如果用户执行!save,则会将其保存在 beeline.properties 文件中,然后允许!reconnect在多个Beeline会话中连接到此已保存的 last-connected-to URL。这也允许使用命令 line 中的beeline -r在启动时重新连接。

使用 hive-site.xml 自动连接到 HiveServer2

从 Hive 2.2.0(HIVE-14063)开始,Beeline 添加了对使用 classpath 中存在的 hive-site.xml 的支持,以根据 hive-site.xml 中的 configuration properties 和其他用户 configuration 文件自动生成连接 URL。并非所有的 URL properties 都可以从 hive-site.xml 派生,因此在 order 中使用此 feature 用户必须创建一个名为“beeline-hs2-connection.xml”的 configuration 文件,这是一个 Hadoop XML 格式文件。此文件用于为连接 URL 提供 user-specific 连接 properties。 Beeline 在$ {中查找此 configuration 文件。 516} /.beeline/(基于 Unix 的 OS)或$ {。 517}\beeline \目录(如果是 Windows)。如果在上述位置找不到该文件,则 Beeline 会在$ {中查找该文件。 518}位置和/etc/hive/conf(检查HIVE-16335,它在 Hive 2.2.0 中的/etc/conf/hive 中修复此位置)在该 order 中。找到文件后,Beeline 将 beeline-hs2-connection.xml 与 class 路径中的 hive-site.xml 结合使用以确定连接 URL。
beeline-hs2-connection.xml 中的 URL 连接 properties 必须具有前缀“beeline.hs2.connection”。后跟 URL property name。对于 order 中的 example 以提供 property ssl,beeline-hs2-connection.xml 中的 property key 应为“beeline.hs2.connection.ssl”。下面的 sample beeline.hs2.connection.xml 为 Beeline 连接 URL 提供了用户和密码的 value。在这种情况下,使用 class 路径中的 hive-site.xml 来获取 properties 的 rest,如 HS2 主机名和 port 信息,Kerberos configuration properties,SSL properties,传输模式等。如果密码为空,则应删除 beeline.hs2.connection.password property。在大多数情况下,beeline-hs2-connection.xml 中的以下 configuration 值和 classpath 中正确的 hive-site.xml 应足以建立与 HiveServer2 的连接。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
 <name>beeline.hs2.connection.user</name>
 <value>hive</value>
</property>
<property>
 <name>beeline.hs2.connection.password</name>
 <value>hive</value>
</property>
</configuration>

如果 beeline-hs2-connection.xml 和 hive-site.xml 中都存在 properties,则从 beeline-hs2-connection.xml 派生的 property value 优先。对于下面的示例 beeline-hs2-connection.xml 文件,在启用 Kerberos 的环境中为 Beeline 连接提供了 value。在这种情况下,就连接 URL 而言,beeline.hs2.connection.principal 的 property value 会从 hive-site.xml 覆盖 HiveConf.ConfVars.HIVE_SERVER2_KERBEROS_PRINCIPAL 的 value。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
 <name>beeline.hs2.connection.hosts</name>
 <value>localhost:10000</value>
</property>
<property>
 <name>beeline.hs2.connection.principal</name>
 <value>hive/dummy-hostname@domain.com</value>
</property>
</configuration>

如果是 properties beeline.hs2.connection.hosts,beeline.hs2.connection.hiveconf 和 beeline.hs2.connection.hivevar,则 property value 是一个 comma-separated 值列表。对于 example,以下 beeline-hs2-connection.xml 以逗号分隔格式提供 hiveconf 和 hivevar 值。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
 <name>beeline.hs2.connection.user</name>
 <value>hive</value>
</property>
<property>
 <name>beeline.hs2.connection.hiveconf</name>
 <value>hive.cli.print.current.db=true, hive.cli.print.header=true</value>
</property>
<property>
 <name>beeline.hs2.connection.hivevar</name>
 <value>testVarName1=value1, testVarName2=value2</value>
</property>
</configuration>

当 beeline-hs2-connection.xml 存在且没有提供其他 arguments 时,Beeline 会自动连接到使用 configuration files 生成的 URL。当提供连接 arguments(-u,-n 或-p)时,Beeline 使用它们并且不使用 beeline-hs2-connection.xml 自动连接。删除或重命名 beeline-hs2-connection.xml 会禁用此 feature。

使用 beeline-site.xml 自动连接到 HiveServer2

除了使用 hive-site.xml 和 beeline-hs2-connection.xml 来导出从 Beeline 连接到 HiveServer2 时使用的 JDBC 连接 URL 的上述方法之外,用户可以选择将 beeline-site.xml 添加到 classpath,并且在 beeline-site.xml 中,她可以指定完整的 JDBC URL。用户还可以指定多个命名 URL 并使用beeline -c <named_url>连接到特定 URL。当相同的 cluster 具有多个 HiveServer2 实例 running 具有不同的配置时,这尤其有用。其中一个命名的 URL 被视为默认值(这是用户只需键入beeline时使用的 URL)。 example beeline-site.xml 如下所示:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
  <name>beeline.hs2.jdbc.url.tcpUrl</name>
  <value>jdbc:hive2://localhost:10000/default;user=hive;password=hive</value>
</property>

<property>
  <name>beeline.hs2.jdbc.url.httpUrl</name>
  <value>jdbc:hive2://localhost:10000/default;user=hive;password=hive;transportMode=http;httpPath=cliservice</value>
</property>

<property>
  <name>beeline.hs2.jdbc.url.default</name>
  <value>tcpUrl</value>
</property>
</configuration>

在上面的例子中,只需 typing beeline打开一个到jdbc:hive2://localhost:10000/default;user=hive;password=hive的新 JDBC 连接。如果 classpath 中同时存在 beeline-site.xml 和 beeline-hs2-connection.xml,则通过在 beeline-hs2-connection.xml 派生的 URL properties 之上应用 beeline-hs2-connection.xml 中指定的 properties 来创建最终 URL。作为示例,请考虑以下 beeline-hs2-connection.xml:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
 <name>beeline.hs2.connection.user</name>
 <value>hive</value>
</property>
<property>
  <name>beeline.hs2.connection.password</name>
  <value>hive</value>
</property>
</configuration>

考虑以下 beeline-site.xml:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
  <name>beeline.hs2.jdbc.url.tcpUrl</name>
  <value>jdbc:hive2://localhost:10000/default</value>
</property>

<property>
  <name>beeline.hs2.jdbc.url.httpUrl</name>
  <value>jdbc:hive2://localhost:10000/default;transportMode=http;httpPath=cliservice</value>
</property>

<property>
  <name>beeline.hs2.jdbc.url.default</name>
  <value>tcpUrl</value>
</property>
</configuration>

在上面的例子中,只需 typing beeline打开一个到jdbc:hive2://localhost:10000/default;user=hive;password=hive的新 JDBC 连接。当用户键入beeline -c httpUrl时,连接将打开jdbc:hive2://localhost:10000/default;transportMode=http;httpPath=cliservice;user=hive;password=hive。

使用 JDBC

您可以使用 JDBC 访问存储在关系数据库或其他表格格式中的数据。

  • 加载 HiveServer2 JDBC 驱动程序。从1.2.0 applications 开始,不再需要使用 Class.forName()显式加载 JDBC 驱动程序。
    例如:
Class.forName("org.apache.hive.jdbc.HiveDriver");
  • 通过使用 JDBC 驱动程序创建Connection object 来连接数据库。
    例如:
Connection cnct = DriverManager.getConnection("jdbc:hive2://<host>:<port>", "<user>", "<password>");

默认是 10000.在 non-secure 配置中,为查询指定以 run 为。在 non-secure 模式中忽略字段 value。

Connection cnct = DriverManager.getConnection("jdbc:hive2://<host>:<port>", "<user>", "");

在 Kerberos 安全模式下,用户信息基于 Kerberos 凭据。

  • 通过创建Statement object 并使用其executeQuery()方法将 SQL 提交到数据库。
    例如:
Statement stmt = cnct.createStatement();
ResultSet rset = stmt.executeQuery("SELECT foo FROM bar");

  • 如有必要,处理结果集。
    这些步骤在下面的 sample code 中说明。
JDBC Client Sample Code
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveJdbcClient {
  private static String driverName = "org.apache.hive.jdbc.HiveDriver";

  /**
   * @param args
   * @throws SQLException
   */
  public static void main(String[] args) throws SQLException {
      try {
      Class.forName(driverName);
    } catch (ClassNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      System.exit(1);
    }
    //replace "hive" here with the name of the user the queries should run as
    Connection con = DriverManager.getConnection("jdbc:hive2://localhost:10000/default", "hive", "");
    Statement stmt = con.createStatement();
    String tableName = "testHiveDriverTable";
    stmt.execute("drop table if exists " + tableName);
    stmt.execute("create table " + tableName + " (key int, value string)");
    // show tables
    String sql = "show tables '" + tableName + "'";
    System.out.println("Running: " + sql);
    ResultSet res = stmt.executeQuery(sql);
    if (res.next()) {
      System.out.println(res.getString(1));
    }
       // describe table
    sql = "describe " + tableName;
    System.out.println("Running: " + sql);
    res = stmt.executeQuery(sql);
    while (res.next()) {
      System.out.println(res.getString(1) + "\t" + res.getString(2));
    }

    // load data into table
    // NOTE: filepath has to be local to the hive server
    // NOTE: /tmp/a.txt is a ctrl-A separated file with two fields per line
    String filepath = "/tmp/a.txt";
    sql = "load data local inpath '" + filepath + "' into table " + tableName;
    System.out.println("Running: " + sql);
    stmt.execute(sql);

    // select * query
   sql = "select * from " + tableName;
    System.out.println("Running: " + sql);
    res = stmt.executeQuery(sql);
    while (res.next()) {
      System.out.println(String.valueOf(res.getInt(1)) + "\t" + res.getString(2));
    }

    // regular hive query
    sql = "select count(1) from " + tableName;
    System.out.println("Running: " + sql);
    res = stmt.executeQuery(sql);
    while (res.next()) {
      System.out.println(res.getString(1));
    }
  }
}

运行 JDBC Sample Code
# Then on the command-line
$ javac HiveJdbcClient.java

# To run the program using remote hiveserver in non-kerberos mode, we need the following jars in the classpath
# from hive/build/dist/lib
#     hive-jdbc*.jar
#     hive-service*.jar
#     libfb303-0.9.0.jar
# 	  libthrift-0.9.0.jar
# 	  log4j-1.2.16.jar
# 	  slf4j-api-1.6.1.jar
#	  slf4j-log4j12-1.6.1.jar
# 	  commons-logging-1.0.4.jar
#
#
# To run the program using kerberos secure mode, we need the following jars in the classpath 
#     hive-exec*.jar
#     commons-configuration-1.6.jar (This is not needed with Hadoop 2.6.x and later).
#  and from hadoop
#     hadoop-core*.jar (use hadoop-common*.jar for Hadoop 2.x)
#
# To run the program in embedded mode, we need the following additional jars in the classpath
# from hive/build/dist/lib
#     hive-exec*.jar
#     hive-metastore*.jar
#     antlr-runtime-3.0.1.jar
#     derby.jar
#     jdo2-api-2.1.jar
#     jpox-core-1.2.2.jar
#     jpox-rdbms-1.2.2.jar
# and from hadoop/build
#     hadoop-core*.jar
# as well as hive/build/dist/conf, any HIVE_AUX_JARS_PATH set,
# and hadoop jars necessary to run MR jobs (eg lzo codec)

$ java -cp $CLASSPATH HiveJdbcClient

或者,您可以运行以下 bash 脚本,该脚本将调用数据文件并在调用 client 之前 build 您的 classpath。该脚本还添加了在嵌入模式下使用 HiveServer2 所需的所有其他 jars。

#!/bin/bash
HADOOP_HOME=/your/path/to/hadoop
HIVE_HOME=/your/path/to/hive

echo -e '1\x01foo' > /tmp/a.txt
echo -e '2\x01bar' >> /tmp/a.txt

HADOOP_CORE=$(ls $HADOOP_HOME/hadoop-core*.jar)
CLASSPATH=.:$HIVE_HOME/conf:$(hadoop classpath)

for i in ${HIVE_HOME}/lib/*.jar ; do
    CLASSPATH=$CLASSPATH:$i
done

java -cp $CLASSPATH HiveJdbcClient

安全 Cluster 的 JDBC Client 设置

使用 Kerberos 身份验证连接到 HiveServer2 时,URL 格式为:

jdbc:hive2://<host>:<port>/<db>;principal=<Server_Principal_of_HiveServer2>

在 connecting 之前,client 需要在票证缓存中具有有效的 Kerberos 票证。
注意:如果 port 编号后面没有“/”,则 jdbc 驱动程序不会解析主机名,并且_End up running HS2 处于嵌入模式。因此,如果要指定主机名,请确保在 port 编号后面有“/”或“/ ”。
对于 LDAP,CUSTOM 或 PAM 身份验证,client 需要将有效的用户 name 和密码传递给 JDBC 连接 API。

To use sasl.qop, add the following to the sessionconf part of your HiveJDBC hive connection string, e.g.
jdbc:hive://hostname/dbname;sasl.qop=auth-int

Multi-User 场景和程序化登录 Kerberos KDC

在当前使用 Kerberos 的方法中,您需要在 connecting 之前在票证缓存中拥有有效的 Kerberos 票证。这需要静态登录(使用 kinit,key tab 或 ticketcache)以及每个 client 限制一个 Kerberos 用户。这些限制限制了中间件系统和其他 multi-user 场景的使用,以及 client 希望以编程方式登录 Kerberos KDC 的情况。
缓解 multi-user 场景问题的一种方法是使用安全代理用户(请参阅HIVE-5155)。从 Hive 0.13.0 开始,对安全代理用户的支持有两个组成部分:

  • 特权 Hadoop 用户的直接代理访问(HIVE-5155)。这使特权用户可以在连接期间直接指定备用 session 用户。如果 connecting 用户具有 Hadoop level 特权来模拟请求的用户标识,则 HiveServer2 将_seun 运行 session 作为请求的用户。
  • Oozie(OOZIE-1457)的基于委托令牌的连接。这是 Hadoop 生态系统组件的 common 机制。

Hadoop 生态系统中的代理用户权限与用户名和主机相关联。也就是说,该特权可用于某些主机的某些用户。如果您从一台授权(祝福)机器连接,之后您需要从另一台 non-blessed 机器建立连接,则应使用 Hive 中的委派令牌。您从受祝福的计算机获取委派令牌,并使用来自 non-blessed 计算机的委派令牌进行连接。主要用例是 Oozie,它从服务器计算机获取委托令牌,然后从 Hadoop 任务节点获取另一个连接。
如果您只是从单个受保护的计算机作为特权用户建立 JDBC 连接,则直接代理访问是更简单的方法。您可以使用 hive.server2.proxy.user = 参数传递您需要在 JDBC URL 中模拟的用户。
参见ProxyAuthTest.java中的示例。
使用 HiveServer2 二进制传输模式hive.server2.transport.mode支持委托令牌从 0.13.0 开始可用;在HIVE-13169中添加了对具有 HTTP 传输模式的 feature 的支持,这应该是 Hive 2.1.0 的一部分。
另一种方法是使用 pre-authenticated Kerberos 主题(请参阅HIVE-6486)。在此方法中,从 Hive 0.13.0 开始,Hive JDBC client 可以使用 pre-authenticated 主题对 HiveServer2 进行身份验证。这使得中间件系统能够在用户运行 client 时运行查询。

将 Kerberos 与 Pre-Authenticated 主题一起使用

要使用 pre-authenticated 主题,您需要进行以下更改。

  • 除了常规的 Hive JDBC jars(不需要 commons-configuration-1.6.jar 和 hadoop-core * .jar)之外,还要将 hive-exec * .jar 添加到 classpath。
  • 除了具有“principal”url property 之外,还要添加 auth=kerberos 和 kerberosAuthType=fromSubject JDBC URL properties。
  • 在 Subject.doAs()中打开连接。
    以下 code 片段说明了用法(请参阅HIVE-6486以获取完整的测试用例):
static Connection getConnection( Subject signedOnUserSubject ) throws Exception{
       Connection conn = (Connection) Subject.doAs(signedOnUserSubject, new PrivilegedExceptionAction<Object>()
           {
               public Object run()
               {
                       Connection con = null;
                       String JDBC_DB_URL = "jdbc:hive2://HiveHost:10000/default;" ||
                                              "principal=hive/localhost.localdomain@EXAMPLE.COM;" || 
                                              "kerberosAuthType=fromSubject";
                       try {
                               Class.forName(JDBC_DRIVER);
                               con =  DriverManager.getConnection(JDBC_DB_URL);
                       } catch (SQLException e) {
                               e.printStackTrace();
                       } catch (ClassNotFoundException e) {
                               e.printStackTrace();
                       }
                       return con;
               }
           });
       return conn;
}

10-21 02:31