您的位置:首页 > 大数据

大数据_Hive的安装配置(远程模式)

2018-01-14 15:48 459 查看
一、Hive的安装和配置:远程模式(需要MySQL数据库)
(*)在嵌入模式下,在哪个目录下执行的数据库初始化,就应该在哪个目录下执行: hive
(*)远程模式:MySQL
(1)配置MySQL的数据库:http://www.mysqlfront.de/
(2)配置hive-site.xml: JDBC的参数
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/hive?useSSL=false</value>
</property>

<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>

<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hiveowner</value>
</property>

<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>Welcome_1</value>
</property>

</configuration>
(3)把MySQL数据库的驱动放到: Hive/lib下
(4)初始化MySQL数据库
老版本的Hive:第一次运行Hive
新版本的hive:schematool -dbType mysql -initSchema

二、Hive的数据模型(重要): 表的类型 ----> 默认分隔符是:tab键
,MARTIN,SALESMAN,7698,1981/9/28,1250,1400,30

1、内部表:相当于MySQL(Oracle)中表,将数据保存到Hive自己的数据仓库的目录中: /usr/hive/warehouse
create table emp
(empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int,
deptno int
);

导入数据
4000
到表中:本地、HDFS
load语句、insert语句
load语句相当于ctrl+X

load data inpath '/scott/emp.csv' into table emp;   ----> 导入HDFS
load data local inpath '/root/temp/***' into table emp;   ----> 导入本地文件

创建表,并且指定分隔符
create table emp1
(empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int,
deptno int
)row format delimited fields terminated by ',';

创建部门表,保存部门数据
create table dept
(deptno int,
dname string,
loc string
)row format delimited fields terminated by ',';

load data inpath '/scott/dept.csv' into table dept;

2、分区表:提高查询的效率----> 查看SQL的执行计划
分区 ----> 目录

(*)根据员工的部门号建立分区
create table emp_part
(empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int
)partitioned by (deptno int)
row format delimited fields terminated by ',';

往分区表中导入数据:指明分区
insert into table emp_part partition(deptno=10) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=10;
insert into table emp_part partition(deptno=20) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=20;
insert into table emp_part partition(deptno=30) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=30;

(*)Hive SQL的执行计划
(*)补充:Oracle中的索引和执行计划
(*)问题:索引一定可以提高查询的效率吗?
(*)Oracle中索引两种类型:  B树索引(默认)----> 适合:insert  update delete
位图索引      ----> 适合:select


oracleSQL的执行计划

索引:相当于是一本书的目录

查询10号部门的员工   select * from emp where deptno=10;

生成执行计划:
explain plan for select * from emp where deptno=10;

select * from table(dbms_xplan.display);

1、没有索引
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     3 |   261 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |     3 |   261 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

2、有索引   create index myindex on emp(deptno);
---------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |     3 |   261 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP     |     3 |   261 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | MYINDEX |     3 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

看索引计划,都是从上往下,从右往左。

问题: 索引一定可以提高查询的效率么
在什么情况下,不一定会提高查询计划(数据量很少的情况下和数据严重倾斜的时候(99.9%的数据都是10号部门的员工))


3、外部表: external table 相对于内部表
(*)实验的数据
[root@bigdata11 ~]# hdfs dfs -cat /students/student01.txt
1,Tom,23
2,Mary,24
[root@bigdata11 ~]# hdfs dfs -cat /students/student02.txt
3,Mike,26

(*)定义:(1)表结构  (2)指向的路径
create external table students_ext
(sid int,sname string,age int)
row format delimited fields terminated by ','
location '/students';

(*)Oracle中的外部表
数据加载方式:
(1)Oracle SQL*Loader 工具
(2)Oracle的数据泵---> PLSQL程序的一个程序包

4、桶表:本质也是一种分区表,类似Hash分区
桶 ----> 文件
创建一个桶表,按照员工的职位job分桶
create table emp_bucket
(empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int,
deptno int
)clustered by (job) into 4 buckets
row format delimited fields terminated by ',';

使用桶表,需要打开一个开关
set hive.enforce.bucketing=true;

使用子查询插入数据
insert into emp_bucket select * from emp1;

5、视图:view
(*)视图是一个虚表,虚:视图是不存数据的
(*)优点:简化复杂的查询
(*)举例:查询部门名称、员工的姓名
create view myview
as
select dept.dname,emp1.ename
from emp1,dept
where emp1.deptno=dept.deptno;

select * from myview;

(*)补充:视图(Oracle数据库) ----> 物化视图
如果视图可以缓存数据,提高效率

6、Hive的查询
(1)查询所有的员工信息
select * from emp1;

(2)查询员工信息:员工号  姓名  薪水
select empno,ename,sal from emp1;

(3)多表查询:查询部门名称、员工的姓名
select dept.dname,emp1.ename
from emp1,dept
where emp1.deptno=dept.deptno;

(4)子查询:hive只支持:from和where后面的子查询
参考讲义的:P50

(5)内置函数:select max(sal) from emp1;

(6)条件函数  就是一个if else: 做一个报表:涨工资,总裁1000 经理800 其他400
select empno,ename,job,sal,
case job when 'PRESIDENT' then sal+1000
when 'MANAGER' then sal+800
else sal+400
end
from emp1;

select empno,ename,job,sal,
case job when 'PRESIDENT' then sal+1000
when 'MANAGER' then sal+800
else sal+400
end
from emp;

Oracle数据库:decode函数也是条件函数

三、Hive的Java客户端
1、JDBC:Java的标准的访问数据库的接口
启动Hive Server:  hiveserver2

java.lang.RuntimeException: org.apache.hadoop.ipc.RemoteException:User:
root is not allowed to impersonate anonymous
在老版本的Hive中,是没有这个问题的
把Hadoop HDFS的访问用户(代理用户) ---> *
core-site.xml
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>

<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>

2、ODBC、Thrift Client


代码实现

package demo.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

//工具类:(1)获取数据库的链接  (2) 释放数据库资源: Connection, Statement, ResultSet
public class JDBCUtils {

//Hive的驱动
private static String driver = "org.apache.hive.jdbc.HiveDriver";
//Oracle: oracle.jdbc.OracleDriver

//Hive的位置
private static String url = "jdbc:hive2://192.168.157.11:10000/default";

//注册数据库的驱动: Java的反射
static{
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}

//获取数据库链接
public static Connection getConnection(){
try {
return DriverManager.getConnection(url);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}

public static void release(Connection conn,Statement st,ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
}

if(st != null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
st = null;
}
}

if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}
}


package demo.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class DemoTest {

public static void main(String[] args) {
String sql = "select * from emp1";

Connection conn = null;
Statement st = null;
ResultSet rs = null;
try{
conn = JDBCUtils.getConnection();

//得到SQL的运行环境
st = conn.createStatement();
//执行SQL
rs = st.executeQuery(sql);

while(rs.next()){
//姓名 薪水
String name = rs.getString("ename");
double sal = rs.getDouble("sal");
System.out.println(name +"\t" + sal);
}
}catch(Exception ex){
ex.printStackTrace();
}finally{
JDBCUtils.release(conn, st, rs);
}

}

}


四、Hive的自定义函数:内置函数、自定义函数(就是一个Java程序,封装我们的业务逻辑)

UDF: user define function

1、实现关系型数据库中的concat函数: 拼加字符串
select concat('Hello  ' ,'World') from dual;  ----> Hello World

2、根据员工的薪水,判断薪水的级别
(*) sal < 1000   ---> Grade A
(*) 1000<= sal < 3000 ---> Grade B
(*) sal >= 3000 ---> Grade C

3、打包
将jar包加入hive的classpath
add jar /root/temp/myudf.jar;

创建别名(函数名称)
create temporary function myconcat as 'demo.udf.MyConcatString';
create temporary function checksal as 'demo.udf.CheckSalaryGrade';


> 代码实现
```java
package demo.udf;

import org.apache.hadoop.hive.ql.exec.UDF;

//实现关系型数据库中的concat函数: 拼加字符串
public class MyConcatString extends UDF{

//必须重写一个方法,方法的名字:必须叫: evaluate
public String evaluate(String a,String b){
return a + "*************"+b;
}
}

<div class="se-preview-section-delimiter"></div>


“`

java中 a=null 这是什么意思

把a这个对象占用的内存资源释放掉,通过java的垃圾回收(把对象的引用指向了空值)

能不能通过java程序去干预java GC呢?

不可以,但是我们可以通过设置java虚拟机的参数,去影响java垃圾回收的机制。

```java
package demo.udf;

import org.apache.hadoop.hive.ql.exec.UDF;

//根据员工的薪水,判断薪水的级别
public class CheckSalaryGrade extends UDF{

public String evaluate(String salary){
int sal = Integer.parseInt(salary);

if(sal<1000) return "Grade A";
else if(sal>=1000 && sal<3000) return "Grade B";
else return "Grade C";
}
}


java中 a=null 这是什么意思

把a这个对象占用的内存资源释放掉,通过java的垃圾回收(把对象的引用指向了空值)

能不能通过java程序去干预java GC呢?

不可以,但是我们可以通过设置java虚拟机的参数,去影响java垃圾回收的机制。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: