Hive简介(上)
一,Hive及数据仓库简介
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张hive数据库表,并提供了简单的sql查询功能,可以将sql语句转换为MapReduce任务执行。
Hive的出现使Java编程者可以对HDFS数据做mapreduce操作(无需清楚文件的存储和任务的运行)。使用SQL来快速实现简单的Mapreduce统计,不必开发专门的MapReduce程序,学习的成本非常低,十分适合数据仓库的统计分析。
数据仓库(Data WareHouse),简写为DW或DWH.是为企业所有级别的决策制定过程,提供所有类型数据支持的战略集合。它是单个数据存储,出于分析性报告和决策支持目的而创建。为需要业务智能的企业,提供指导业务流程改进、监视时间、成本、质量以及控制.
数据处理大致分为两大类:联机事务处理OLTP(on-linetransction processing) , 联机分析处理OLAP(On-line Analytical Processing)
OLTP是传统的关系型数据库的主要应用,主要是基本的,日常的事务处理,例如银行交易。
OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。
OLTP系统强调数据库内存效率,强调内存各种指标的命令率,强调绑定变量,强调并发操作。
OLAP系统则强调数据分析,强调SQL执行市场,强调磁盘I/O,强调分区等。
简单的说,数据仓库是用来做分析查询的数据库,基本不用来做更新,插入,修改等操作。
HIve: 解释器,编译器,优化器等。
Hive运行时,元数据存储在关系型数据库里面。
编译器将一个HIve SQL转换成操作符,操作符是Hive的最小的处理单元,每一个操作符代表HDFS的一个操作或者一道MapReduce作业
Operator操作
Operator都是hive定义的一个处理过程
Operator都定义有:
Select Operator , TableScanOperator , Limit, File Output Operator
ANTLR词法语法分析工具解析hql
Parser 将HQL 转换成抽象语法树
Semantic Analyzer 将抽象语法树转换成查询快
Logic Plan Generator 将查询块转换成逻辑查询计划
Logiccal Optimizer 重写逻辑查询计划
Physical Plan Generator 将逻辑计划转成物理计划(MR jobs)
Physical Optimizer 选择最佳的策略
二,Hive架构原理
用户接口主要有三个:CLI(命令行) , Client(客户端), WUI(web网页).
上图是 1.x架构中,如果是2.x中 JobTracker换成 ResourceManager
其中最常用的是CLI命令行,Cli启动的时候,会同时启动一个Hive副本;Client是Hive的客户端,用户连接至Hive Server。在启动 Client模式的时候,需要指出Hive Server所在节点,并且在该节点启动Hive Server。 WUI是通过浏览器访问Hive。
Hive将元数据存储在数据库中,如mysql、 derby。 Hive中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。
解释器、编译器、优化器完成HQL查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在HDFS中,并在随后有MapReduce调用执行。
Hive的数据存储在HDFS中,大部分的查询、计算由MapReduce完成(包含*的查询,比如select * from tbl不会生成MapRedcue任务)
原因:
1.当使用 select * from tableName的情况下,Hive可以简单的读取table对应的存储目录下的文件,然后格式输出到控制台。对于where条件中使用分区字段这种情况,也无需使用mapReduce,例如:select * from tableName where partition1=‘’;无论使用limit语句限制记录条数。
2.如果属性 hive.exec.mode.local.auto的值设置为true的话,Hive还会尝试使用本地模式执行其他操作,
注意:最好是将set hive.exec.mode.local.auto=true这个设置增加到$HOME/.hiverc配置文件中。
三,Hive搭建及三种模式
3.1 Hive的安装配置
1、安装Hive
安装环境以及前提说明:首先,Hive是依赖于hadoop系统的,因此在运行Hive之前需要保证已经搭建好hadoop集群环境。
– 安装一个关系型数据库 mysql
yum -y install mysql-server mysql-devel
2.配置环境变量
3.替换和添加相关jar包
– 修改HADOOP_HOME/share/hadoop/yarn/lib目录下的jline-*.jar 将其替换成HIVE_HOME/lib下的jline-2.12.jar(hadoop中的jar版本太低,可能出现不兼容)。
– 将hive连接mysql的jar包:mysql-connector-java-5.1.32-bin.jar
拷贝到hive解压目录的lib目录下
4.修改配置文件(三种模式,下面介绍)
5.启动hive 敲 hive即可,因为已经配置了环境变量
3.2 三种模式
A、内嵌模式(元数据保存在内嵌的derby中,允许一个会话链接,尝试多个会话链接时会报错)【不常用】
B、本地模式(本地安装mysql 替代derby存储元数据)【开发测试阶段】
C、远程模式(远程安装mysql 替代derby存储元数据)
3.2.1 内嵌Derby单用户模式
这种安装模式的元数据是内嵌在Derby数据库中的,只能允许一个会话连接,数据会存放到HDFS上。
这种方式是最简单的存储方式,只需要 hive-site.xml
做如下配置便可(注:使用 derby 存储方式时,运行 hive 会在当前目录生成一个 derby 文件和一个 metastore_db)
进入到hive安装目录下的conf,新建 hive-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:derby:;databaseName=metastore_db;create=true</value> </property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>org.apache.derby.jdbc.EmbeddedDriver</value>
</property>
<property>
<name>hive.metastore.local</name>
<value>true</value>
</property>
<property>
//数据在hdfs上的存储路径
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
</configuration>
3.2.2 本地用户模式
这种安装方式和嵌入式的区别在于,不再使用内嵌的Derby作为元数据的存储介质,而是使用其他数据库比如MySQL来存储元数据且是一个多用户的模式,运行多个用户client连接到一个数据库中。这种方式一般作为公司内部同时使用Hive。这里有一个前提,每一个用户必须要有对MySQL的访问权利,即每一个客户端使用者需要知道MySQL的用户名和密码才行。
这种存储方式需要在本地运行一个 mysql 服务器,并作如下配置(下面两种使用 mysql 的方式,需要将 mysql 的 jar 包拷贝到 $HIVE_HOME/lib 目录下)。
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
//数据存储在hdfs上的路径
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive_rlocal/warehouse</value>
</property>
<property>
//元数据文件存放本地mysql中
<name>hive.metastore.local</name>
<value>true</value>
</property>
<property>
//jdbc的连接地址,没发现数据库会帮你新建一个数据库
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://node01/hive_remote?createDatabaseIfNotExist=true</value>
</property>
<property>
//链接驱动类,指明是mysql
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
//mysql连接用户名
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
//mysql连接密码
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
</configuration>
注意:hive和MySQL不用做HA,单节点就可以。通过设置其他节点可以访问得到数据库。
3.2.3 远程模式
这种存储方式需要在远端服务器运行一个 mysql 服务器,并且需要在 Hive 服务器启动 meta服务。
远程模式分为两种:remote一体,remote分开
remote一体:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse2</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://node01:3306/hive_remote?createDatabaseIfNotExist=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
<property>
//元数据文件不在本地存储
<name>hive.metastore.local</name>
<value>false</value>
</property>
</configuration>
<property>
<name>hive.metastore.uris</name>
<value>thrift://node01:9083</value>
</property>
这里把 hive 的服务端和客户端都放在同一台服务器上了。服务端和客户端可以拆开,
Remote 分开(公司企业经常用)
服务端配置:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://node01:3306/hive?createDatabaseIfNotExist=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
</configuration>
客户端配置:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
<property>
<name>hive.metastore.uris</name>
<value>thrift://node01:9083</value>
</property>
</configuration>
针对这种服务端,客户端节点分离的,启动的命令也不一样。
服务端命令:
hive --service metastore
客户端命令:
hive
四,HQL详解
4.1 DDL语句
4.1.1 创建/删除/修改/使用数据库
创建:
create database databaseName;
删除:
drop database databaseName;
修改(一般不使用):
alter databaseName set property_name=property_value;
使用数据库:
use databaseName;
4.1.2 创建/删除/表
表字段的数据类型:
primitive_type 原始数据类型 — int bigint double string date
array_type 数组类型
map_type Map类型
struct_type
union_type
建表语句实例:
create table abc(
id int,
name string,
age int,
likes array<string>,
address map<string,string>
)
//字段间用,号隔开区分
row format delimited fields terminated by ','
//数组元素用 - 隔开
COLLECTION ITEMS TERMINATED by '-'
//map key和value用 : 隔开
map keys terminated by ':'
//换行符隔开一行数据
lines terminated by '\n';
数据如下:
1,zshang,18,game-girl-book,stu_addr:beijing-work_addr:shanghai
2,lishi,16,shop-boy-book,stu_addr:hunan-work_addr:shanghai
3,wang2mazi,20,fangniu-eat,stu_addr:shanghai-work_addr:tianjing
外部表:
外部关键字EXTERNAL允许您创建一个表,并提供一个位置,以便hive不使用这个表的默认位置。这方便如果你已经生成的数据。当删除一个外部表,表中的数据不是从文件系统中删除。外部表指向任何HDFS的存储位置,而不是存储在配置属性指定的文件夹 hive.metastore.warehouse.dir 中
删除:
drop table tableName;
修改表:
alter table tableName rename to newTableName;
删除删除:
delete from tableName [where expression]
4.2 DML语句
4.2.1 四种插入/导入数据方式
Hive不能很好的支持用insert语句一条一条的进行插入操作,不支持update操作。数据是以load的方式加载到建立好的表中。数据一旦导入就不可以修改。
第一种:
//local代表数据来源是本地还是 hdfs上 overwrite代表是否覆盖表中内容
load data [local] inpath '数据url' [overwrite] into table tableName;
第二种:
//abc 是已存在的表, 向aa中插入数据--->数据个数相同,类型匹配(顺序一致)
insert overwrite table aa
select id, name, age from abc;
第三种:
from person t1
insert overwrite table person1
select t1.id, t1.name, t1.age ;
from放前面好处就是后面可以插入多条语句
FROM abc t1,sufei t2
INSERT OVERWRITE TABLE qidu
SELECT t1.id,t1.name,t1.age,t1.likes,t1.address where…
INSERT OVERWRITE TABLE wbb
SELECT t2.id,t2.name,t2.age,t2.likes,t2.address where…;
本地load数据和从HDFS上load加载数据的过程有什么区别?
本地: local 会自动复制到HDFS上的hive的存储目录下
Hdfs导入 后移动到hive的存储目录下
4.2.2 查询数据并保存
条件查询array类型数据:
//likes在表中的字段类型是 array
SELECT count(1) FROM abc LATERAL VIEW explode(likes) rTable AS realid where realid ='book';
条件查询 map数据类型:
查询时可以按照 aaa[bbb], aaa 是map字段名,bbb是其中的参数名,就可以取到这个参数的值了
当参数名bbb是string时,需要加双引号。
select * from abc where address["stu_addr"]="shanghai";
A.保存数据到本地
insert overwrite local directory '本地路径'
row format delimited fileds terminated by ','
select * from DBName.TableName;
B.保存数据到HDFS
insert overwrite directory 'hdfs路径'
row format delimited fileds terminated by ','
select * from DBName.TableName;
C.shell中将数据重定向到文件中
hive -e 'select * from DBName.TableName;' >> fileUrl
4.2.3 备份数据或还原数据
备份数据:
export table DBName.TAbleName To '只能是hdfs上路径'
删除再还原数据:
drop table tableName;
import from 'hdfs上文件路径';
4.3 Hive SerDe
Serializer and Deserializer SerDe 用于做序列化和反序列化。
例子:
Hive正则匹配:
CREATE TABLE logtbl (
host STRING,
identity STRING,
t_user STRING,
time STRING,
request STRING,
referer STRING,
agent STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) \\[(.*)\\] \"(.*)\" (-|[0-9]*) (-|[0-9]*)"
)
STORED AS TEXTFILE;
数据模板:
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-upper.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-nav.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /asf-logo.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-button.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-middle.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.css HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /asf-logo.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-middle.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-button.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-nav.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-upper.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.css HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.css HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-button.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-upper.png HTTP/1.1" 304 -
导入到hive中,查看:
192.168.57.4 - - 29/Feb/2016:18:14:35 +0800 GET /bg-upper.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:35 +0800 GET /bg-nav.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:35 +0800 GET /asf-logo.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:35 +0800 GET /bg-button.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:35 +0800 GET /bg-middle.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET / HTTP/1.1 200 11217
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET / HTTP/1.1 200 11217
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /tomcat.css HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /tomcat.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /asf-logo.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /bg-middle.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /bg-button.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /bg-nav.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /bg-upper.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET / HTTP/1.1 200 11217
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /tomcat.css HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /tomcat.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET / HTTP/1.1 200 11217
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /tomcat.css HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /tomcat.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /bg-button.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET /bg-upper.png HTTP/1.1 304 -
五,Beeline和Hiveserver2
Hiveserver2直接启动
hiveserver2
启动beeline
beeline
!connect jdbc:hive2:node01:10000 root 123456
六,Hive的JDBC
一般是平台使用展示或接口,服务端启动hiveserver2后,在java代码中通过调用hive的jdbc访问默认端口10000进行连接、访问.
项目导入hive相关jar
package com.shsxt.hive;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class HiveJdbcClient {
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) throws Exception {
Class.forName(driverName);
Connection conn = DriverManager.getConnection("jdbc:hive2://node01:10000/hive","root","123456");
Statement statement = conn.createStatement();
String sql = "select * from abc";
ResultSet res = statement.executeQuery(sql);
while(res.next()){
System.out.println(res.getInt(1)+res.getString(2)+
res.getInt(3)+res.getObject(4)+res.getObject(5));
}
}
}
运行结果: