从这篇笔记开始我们开始进入Hive的高级部分,这其中包括HiveServer2、Hive数据压缩、hive数据存储、hive企业优化等。
首先看一下HiveServer2,该工作作为Hive的一个server端进行启动,供其他的工具使用。之前的hive基础知识部分的笔记都是以hive client为基础的,如果想用其他的工具比如jdbc、spark sql来使用hive就需要启动HiveServer2,。启动HiveServer2之后就可以通过远程进行连接hive,执行hive中常见的查询和分析语句。
1.Beeline方式访问Hive
通过CM管理界面给集群增加HiveServer2角色,本文的例子是将该角色安装在node3上,HiveServer2启动之后,可以通过beeline来连接hive,beeline的命令和hive的命令在同一目录下,启动该命令后还需要通过指定连接串才能够正常连接到HiveServer2上,连接串的格式如下:
!connect jdbc:hive2://node3:10000 hive hive org.apache.hive.jdbc.HiveDriver
其中HiveServer2默认启动的端口是10000,后面跟的用户名和密码是安装hive集群的用户名和密码,最后面跟的是驱动类,根据自己的实际情况修改上述的连接串之后,笔者试过,这个用户名和密码不输入也是可以正常连接的。在beeline的命令行中执行该连接串,就可以连接到HiveServer2上。之后对表的操作是和client模式下的一样的。beeline的显示风格有点类似mysql的风格,对输出的内容的格式做了一定的优化,看着比client模式下要清爽一些。
登录beeline的执行情况如下:
[root@node3 ~]# beeline
Beeline version 1.1.0-cdh5.15.2 by Apache Hive
beeline> !connect jdbc:hive2://node3:10000 hive hive org.apache.hive.jdbc.HiveDriver
Connecting to jdbc:hive2://node3:10000
Connected to: Apache Hive (version 1.1.0-cdh5.15.2)
Driver: Hive JDBC (version 1.1.0-cdh5.15.2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://node3:10000> show tables;
+------------+--+
| tab_name |
+------------+--+
| dept |
| dept_cats |
| dept_part |
| emp |
| emp_ext |
| emp_ext2 |
| emp_in |
| emp_part |
+------------+--+
8 rows selected (0.29 seconds)
0: jdbc:hive2://node3:10000> select * from emp;
+------------+------------+------------+----------+---------------+----------+-----------+-------------+--+
| emp.empno | emp.ename | emp.job | emp.mgr | emp.hiredate | emp.sal | emp.comm | emp.deptno |
+------------+------------+------------+----------+---------------+----------+-----------+-------------+--+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.0 | NULL | 20 |
.....
+------------+------------+------------+----------+---------------+----------+-----------+-------------+--+
在beeline模式下,日志不显示在客户端,这个可以在CM管理界面中进行配置,将日志级别调整为WARN就不会显示日志信息,这样客户端只显示最终的结果信息。如果将日志级别调整为INFO,则在beeline中还是会显示相应的日志信息的。
2.jdbc方式访问Hive
HiveServer2有一个jdbc的驱动,它支持嵌入式和远程访问HiveServer2。
下面就是通过jdbc来访问HiveServer2的一个例子,官方文档的例子在如下网址:JDBC Client Sample Code,这个例子中有删除表、创建表、查看表、加载数据等操作示例,在这里我们只举一个查询数据的例子,改写后的例子的代码如下:
package com.example.hive.jdbc;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
public class TestHiveQuery {
private static final String driverName = "org.apache.hive.jdbc.HiveDriver";
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);
}
Connection con = DriverManager.getConnection("jdbc:hive2://node3:10000/default", "hive", "hive");
Statement stmt = con.createStatement();
String tableName = "default.emp";
// select * query
String sql = "select * from " + tableName;
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));
}
}
}
将上面的代码保存到文件:TestHiveQuery.java,上传到目录:/opt/datas/com/example/hive/jdbc,然后用javac进行编译,执行结果如下:
[root@node3 datas]# javac -classpath .:/opt/cloudera/parcels/CDH-5.15.2-1.cdh5.15.2.p0.3/jars/* com/example/hive/jdbc/TestHiveQuery.java
编译没有错误的话,就可以执行该java类:
[root@node3 datas]# java -classpath .:/opt/cloudera/parcels/CDH-5.15.2-1.cdh5.15.2.p0.3/jars/* com/example/hive/jdbc/TestHiveQuery
Running: select * from default.emp
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
可以看出,通过jdbc将emp表中的数据查询出来。
这种方式适合通过前端页面连接hive查询结果集。当hive中分析的结果集比较小的时候,再通过工具导入oracle或者mysql进行存储比较麻烦,就可以通过jdbc直接进行访问,然后再将结果展示在页面中。我们知道在hive中进行全表查询是比较快的,所以这种方式一般在企业中比较常用。
3.遇到的错误
在运行jdbc的程序的时候遇到如下两个错误,供大家参考:
一是官方文档中给出的例子的driver的name是org.apache.hadoop.hive.jdbc.HiveDriver,而本人安装的jdbc版本所对应的driver的name是org.apache.hive.jdbc.HiveDriver,少了一个hadoop,这应该是官方文档没有及时更新的缘故。如果不修改的话,执行的时候会报如下的错误:
[root@node3 datas]# java -classpath .:/opt/cloudera/parcels/CDH-5.15.2-1.cdh5.15.2.p0.3/jars/* com/example/hive/jdbc/TestHiveQuery
java.lang.ClassNotFoundException: org.apache.hadoop.hive.jdbc.HiveDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:195)
at com.example.hive.jdbc.TestHiveQuery.main(TestHiveQuery.java:14)
另外一个jdbc的连接串,文档中的例子是:jdbc:hive://localhost:10000/default,我们需要修改为jdbc:hive2://node3:10000/default,需要注意的是需要将hive修改为hive2,否则会报No suitable driver的错误:
[root@node3 datas]# java -classpath .:/opt/cloudera/parcels/CDH-5.15.2-1.cdh5.15.2.p0.3/jars/* com/example/hive/jdbc/TestHiveQuery
Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:hive://node3:10000/default
at java.sql.DriverManager.getConnection(DriverManager.java:596)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at com.example.hive.jdbc.TestHiveQuery.main(TestHiveQuery.java:20)
将这两处进行修改后就可以正常执行这个查询示例了。