Hive开发规范

[复制链接]
发表于 : 2018-11-27 17:29:03 最新回复:2019-07-24 14:28:48
1108 2

规则

Hive JDBC驱动的加载

客户端程序以JDBC的形式连接HiveServer时,需要首先加载Hive的JDBC驱动类org.apache.hive.jdbc.HiveDriver。

故在客户端程序的开始,必须先使用当前类加载器加载该驱动类。

如果classpath下没有相应的jar包,则客户端程序抛出Class Not Found异常并退出。

如下:

Class.forName("org.apache.hive.jdbc.HiveDriver").newInstance();

获取数据库连接

使用JDK的驱动管理类java.sql.DriverManager来获取一个Hive的数据库连接。

Hive 的数据库URL为

url="jdbc:hive2://xxx.xxx.xxx.xxx:24002,xxx.xxx.xxx.xxx:24002,xxx.xxx.xxx.xxx:24002/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver;sasl.qop=auth-conf;auth=KERBEROS;principal=hive/hadoop.hadoop.com@HADOOP.COM;user.principal=hive/hadoop.hadoop.com;user.keytab=conf/hive.keytab";

以上已经经过安全认证,所以Hive数据库的用户名和密码为null或者空。

如下:

// 建立连接
connection = DriverManager.getConnection(url, "", "");

执行HQL

执行HQL,注意HQL不能以";"结尾。

正确示例:

String sql = "SELECT COUNT(*) FROM employees_info";
Connection connection = DriverManager.getConnection(url, "", "");
PreparedStatement statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();

错误示例:

String sql = "SELECT COUNT(*) FROM employees_info;";
Connection connection = DriverManager.getConnection(url, "", "");
PreparedStatement statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();

关闭数据库连接

客户端程序在执行完HQL之后,注意关闭数据库连接,以免内存泄露,同时这是一个良好的编程习惯。

需要关闭JDK的两个对象statement和connection。

如下:

finally {
           if (null != statement) {
               statement.close();
          }
           
           // 关闭JDBC连接
           if (null != connection) {
               connection.close();
          }
      }

HQL语法规则之判空

判断字段是否为“空”,即没有值,使用“is null”;判断不为空,即有值,使用“is not null”。

要注意的是,在HQL中String类型的字段若是空字符串, 即长度为0,那么对它进行IS NULL的判断结果是False。此时应该使用“col = '' ”来判断空字符串;使用“col != '' ”来判断非空字符串。

正确示例:

select * from default.tbl_src where id is null;
select * from default.tbl_src where id is not null;
select * from default.tbl_src where name = '';
select * from default.tbl_src where name != '';

错误示例:

select * from default.tbl_src where id = null;
select * from default.tbl_src where id != null;
select * from default.tbl_src where name is null;
select * from default.tbl_src where name is not null;

注:表tbl_src的id字段为Int类型,name字段为String类型。

客户端配置参数需要与服务端保持一致

当集群的Hive、YARN、HDFS服务端配置参数发生变化时,客户端程序对应的参数会被改变,用户需要重新审视在配置参数变更之前提交到HiveServer的配置参数是否和服务端配置参数一致,如果不一致,需要用户在客户端重新调整并提交到HiveServer。例如下面的示例中,如果修改了集群中的YARN配置参数时,Hive客户端、示例程序都需要审视并修改之前已经提交到HiveServer的配置参数:

初始状态:

集群YARN的参数配置如下:

mapreduce.reduce.java.opts=-Xmx2048M

客户端的参数配置如下:

mapreduce.reduce.java.opts=-Xmx2048M

集群YARN修改后,参数配置如下:

mapreduce.reduce.java.opts=-Xmx1024M

如果此时客户端程序不做调整修改,则还是以客户端参数有效,会导致reducer内存不足而使MR运行失败。

多线程安全登录方式

如果有多线程进行login的操作,当应用程序第一次登录成功后,所有线程再次登录时应该使用relogin的方式。

login的代码样例:

  private Boolean login(Configuration conf){
   boolean flag = false;
   UserGroupInformation.setConfiguration(conf);
   
   try {
     UserGroupInformation.loginUserFromKeytab(conf.get(PRINCIPAL), conf.get(KEYTAB));
     System.out.println("UserGroupInformation.isLoginKeytabBased(): " +UserGroupInformation.isLoginKeytabBased());
     flag = true;
  } catch (IOException e) {
     e.printStackTrace();
  }
   return flag;
   
}

relogin的代码样例:

public Boolean relogin(){
       boolean flag = false;
       try {
           
         UserGroupInformation.getLoginUser().reloginFromKeytab();
         System.out.println("UserGroupInformation.isLoginKeytabBased(): " +UserGroupInformation.isLoginKeytabBased());
         flag = true;
      } catch (IOException e) {
           e.printStackTrace();
      }
       return flag;
  }

使用WebHCat的REST接口以Streaming方式提交MR任务的前置条件

本接口需要依赖hadoop的streaming包,在以Streaming方式提交MR任务给WebHCat前,需要将“hadoop-streaming-2.7.0.jar”包上传到HDFS的指定路径下:“hdfs:///apps/templeton/hadoop-streaming-2.7.0.jar”。首先登录到安装有客户端和Hive服务的节点上,以客户端安装路径为“/opt/client”为例:

source /opt/client/bigdata_env

使用kinit登录人机用户或者机机用户。

hdfs dfs -put ${BIGDATA_HOME}/FusionInsight/FusionInsight-Hadoop-2.7.2/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.7.2.jar /apps/templeton/

其中/apps/templeton/需要根据不同的实例进行修改,默认实例使用/apps/templeton/,Hive1实例使用/apps1/templeton/,以此类推。

避免对同一张表同时进行读写操作

目前的版本中,Hive不支持并发操作,需要避免对同一张表同时进行读写操作,否则会出现查询结果不准确,甚至任务失败的情况。

分桶表不支持insert into

分桶表(bucket table)不支持insert into,仅支持insert overwrite,否则会导致文件个数与桶数不一致。

使用WebHCat的部分REST接口的前置条件

WebHCat的部分REST接口使用依赖于MapReduce的JobHistoryServer实例,具体接口如下:

  • mapreduce/jar(POST)

  • mapreduce/streaming(POST)

  • hive(POST)

  • jobs(GET)

  • jobs/:jobid(GET)

  • jobs/:jobid(DELETE)

Hive授权说明

Hive授权(数据库、表或者视图)推荐通过Manager授权界面进行授权,不推荐使用命令行授权,除了“alter databases databases_name set owner='user_name'”场景以外。

不允许创建Hive on HBase的分区表

Hive on HBase表将实际数据存储在HBase上。由于HBase会将表划分为多个分区,将分区散列在RegionServer上,因此不允许在Hive中创建Hive on HBase分区表。

Hive on HBase表不支持INSERT OVERWRITE

HBase中使用rowkey作为一行记录的唯一标识。在插入数据时,如果rowkey相同,则HBase会覆盖该行的数据。如果在Hive中对一张Hive on HBase表执行INSERT OVERWRITE,会将相同rowkey的行进行覆盖,不相关的数据不会被覆盖。


  • x
  • 常规:

点评 回复

跳转到指定楼层
赵穆紫
赵穆紫   发表于 2018-11-27 17:30:12 已赞(0) 赞(0)

建议

HQL编写之隐式类型转换

查询语句使用字段的值做过滤时,不建议通过Hive自身的隐式类型转换来编写HQL。因为隐式类型转换不利于代码的阅读和移植。

建议示例:

select * from default.tbl_src where id = 10001;
select * from default.tbl_src where name = 'TestName';

不建议示例:

select * from default.tbl_src where id = '10001';
select * from default.tbl_src where name = TestName;

说明:

表tbl_src的id字段为Int类型,name字段为String类型。

HQL编写之对象名称长度

HQL的对象名称,包括表名、字段名、视图名、索引名等,其长度建议不要超过30个字节。

Oracle中任何对象名称长度不允许超过30个字节,超过时会报错。PT为了兼容Oracle,对对象的名称进行了限制,不允许超过30个字节。

太长不利于阅读、维护、移植。

HQL编写之记录个数统计

统计某个表所有的记录个数,建议使用“select count(1) from table_name”。

统计某个表某个字段有效的记录个数,建议使用“select count(column_name) from table_name”。

JDBC超时限制

Hive提供的JDBC实现有超时限制,默认是5分钟,用户可以通过java.sql.DriverManager.setLoginTimeout(int seconds)设置,seconds的单位为秒。

UDF管理

建议由管理员创建永久UDF,避免每次使用时都去add jar,和重新定义UDF。

Hive的UDF会有一些默认属性,比如deterministic 默认为true(同一个输入会返回同一个结果),stateful(是否有状态,默认为true)。当用户实现的自定义UDF内部实现了汇总等,需要在类上加上相应的注解,比如如下类

@UDFType(deterministic = false)
Public class MyGenericUDAFEvaluator implements Closeable {

表分区优化建议

  1. 当数据量较大,且经常需要按天统计时,建议使用分区表,按天存放数据。

  2. 为了避免在插入动态分区数据的过程中,产生过多的小文件,在执行插入时,在分区字段上加上distribute by。

存储文件格式优化建议

Hive支持多种存储格式,比如TextFile,RCFile,ORC,Sequence,Parquet等。为了节省存储空间,或者大部分时间只查询其中的一部分字段时,可以在建表时使用列式存储(比如ORC文件)。


  • x
  • 常规:

点评 回复

最后的谜底
最后的谜底   发表于 2019-7-24 14:28:48 已赞(0) 赞(0)

本来hive jdbc都是可以连接的,有段时间没用了再连接就报错:Tried all existing HiveServer2 uris from ZooKeeper;
请问这是怎么回事呢
  • x
  • 常规:

点评 回复

发表回复
您需要登录后才可以回帖 登录 | 注册

警告 内容安全提示:尊敬的用户您好,为了保障您、社区及第三方的合法权益,请勿发布可能给各方带来法律风险的内容,包括但不限于政治敏感内容,涉黄赌毒内容,泄露、侵犯他人商业秘密的内容,侵犯他人商标、版本、专利等知识产权的内容,侵犯个人隐私的内容等。也请勿向他人共享您的账号及密码,通过您的账号执行的所有操作,将视同您本人的行为,由您本人承担操作后果。详情请参看“隐私声明
如果附件按钮无法使用,请将Adobe Flash Player 更新到最新版本!
登录参与交流分享

登录参与交流分享

登录