Hive的执行流程
Hive安装大法
- 上传hiive压缩包到虚拟机
使用xftp上传
使用命令rz(需要安装lrzsz — yum install lrzsz -y)
- 解压该压缩包
tar -zxvf hive-1.2.1.tar.gz
- 安装mysql数据库(推荐使用yum在线安装)
//编写脚本:内容如下
#!/bin/bash
mydir=`pwd`
cd /etc/yum.repo.d/
rm -rf *.repo
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
cd $mydir
rpm -e --nodeps mysql-libs-5.1.73-5.el6_6.x86_64
yum -y install mysql-server
chkconfig mysqld on
service mysqld start
编写脚本,复制以上代码,有网的情况下自动去下载mysql,并启动
默认没有密码,进去mysql后执行set password=password(‘root’);//可以设置密码
(执行下面的语句 .:所有库下的所有表 %:任何IP地址或主机都可以连接)
>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
>FLUSH PRIVILEGES;
- 进入conf目录下将hive-env.sh.template复制重命名为hive-env.sh,并配置
配置其中的$hadoop_home的值为hadoop的绝对路径
- 将 hive-default.xml.template复制重命名为 hive-site.xml,并配置
将其中的<configuration></configuration>标签内的内容删除(光标放到第一个property标签左边,输入:.,$-1d回车,会一次删除)
复制以下代码
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>username to use against metastore database</description>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
<description>password to use against metastore database</description>
</property>
- 复制lib下的jline-2.12.jar到hadoop的绝对路径/share/hadoop/yarn/lib/下
cp hive/lib/jline-2.12.jar hadoop的绝对路径/share/hadoop/yarn/lib/
- 装hive和mysq完成后,将mysql的连接jar包拷贝到$HIVE_HOME/lib目录下
例子:引入mysql-connector-java-5.1.39.jar
通过rz或者xftp上传
Hive介绍
- Hive 构建在基于静态批处理的Hadoop 之上,Hadoop 通常都有较高的延迟并且在作业提交和调度的时候需要大量的开销。因此,Hive 并不能够在大规模数据集上实现低延迟快速的查询
- hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能
- Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据
- 使用sql 语句— 懒人推动世界发展
- 只会写sql的人也能处理大数据
- 不写mapreduce,就可以处理大数据
Hive内部执行流程(执行查询时)在MapReduce进行查询,在hdfs进行其他
- 解析 — 找出语句中的关键字
- 优化 — 将select进行优化,形成树
- 编译 — 对selete 重选编译,形成相应的逻辑计划
- 执行 — 将逻辑计划进行实现,转变成物理计划
Hive的介绍
- 表的创建 — 表创建默认为内部的表格,存放在hdfs中,其中外部表在hdfs中有备份
- 与mysql的关系— mysql中存放了hive的元数据
- 数据库的连接
- 直接进数据库
- 外部连接
Hive的元数据存放位置
- derby — hive内部的数据库,不能多用户同时访问
- 本地
- 存放在外部的数据库(最安全)
Hive 中的四大表
- 内部表
指默认创建的表都是内部表,存储在hdfs,删除的时候,元数据及数据都会丢失(表及表中的数据) - 外部表
将表创建在hdfs中,通过hdfs来存放元数据及数据,但是会额外存储一个数据的备份,删除的时候,备份的数据会保留在hdfs内 - 分区表
在创建表的时候可以在后面加入 partitioned by(要分的区名字,类型····)不能与前面的字段重名,分区的顺序决定了谁是父目录,谁是子目录(by后面的字段,一个字段为一个目录)。- 静态分区:插入的时候必须首先要知道有什么分区类型,而且每个分区写一个load data。
- 动态分区:可以根据查询得到的数据动态分配到分区里。与静态分区区别就是不指定分区目录,由系统自己选择(执行动态分区之前需要设置set hive.exec.dynamic.partition=true)。
- 分桶表(方便抽样、提高join联查效率,按照某个字段对桶数取余将相同余数的值分到同一个桶中)
- 让hive强制分桶,自动按照分桶表的bucket 进行分桶。(推荐):set hive.enforce.bucketing = true;
- 手动指定reduce数量:set mapreduce.job.reduces = num;
- 分桶就是对分桶的字段做了hash 然后存放到对应文件中,所以说如果原有数据没有按key hash ,需要在插入分桶的时候hash, 也就是说向分桶表中插入数据的时候必然要执行一次MAPREDUCE,这也就是分桶表的数据基本只能通过从结果集查询插入的方式进行导入
- 分桶的原理:
- MR中:按照key的hash值去模除以reductTask的个数
- Hive中:按照分桶字段的hash值去模除以分桶的个数
- Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
Hive的操作大全
新建数据库:create database 数据库名字;
使用改数据库:use 数据库名字;
上传数据:
- 上传虚拟机本地数据:load data local inpath ‘虚拟机的文件的绝对路径’ into table tablename;
- 上传hdfs数据:load data inpath ‘hdfs://hdfs节点名字(namenode名字):9000/文件绝对路径’ into table tablename;
- 区别在于 有local和没有local
- 上传的数据根建表时的行格式分隔符上传:
- row format delimited: 代表以下为行格式分隔语句
- fields terminated by ’ ’ : 字段之间使用空格分隔
- collection items terminated by ‘-’ : 集合(就是这的数据)使用-分隔
- map keys terminated by ‘:’ : 键值对使用冒号分隔
- lines terminated by ‘\n’ : 记录之间使用换行分隔
- select * from tablename; 查看表中是否有上传的数据
新增数据:
- insert into tablename values(与字段对应的类型的值);
- from tablename insert into tablename2 select * ;//根据后面的select 查询的字段,将tablename对应的值添加到 tablename2表中对应的值中。
- select * from tablename; 查看表中是否有新增的数据
- insert into table tablename select id,name,age from tablename2;将表tablename2中的数据添加到tablename中,但tablename2不能为空,且2个表的结构要一致。
- 加载数据
insert into table tablename select id,name,age from tablename1;将tablename1中的select后面的字段添加到表tablename中,注意是否有这个字段。
创建表:
ps: 内部表–删除之后数据全部丢失,外部表–删除元数据之后源数据还存在。
- 内部:create table [if not exists] tablename(字段名 字段类型,···);
- 外部:create external table [if not exists] tablename location hdfs_path;(不加location及后面的路径的话,则保存在hdfs中的默认路径)。
- create temporary table tablename;定义一张临时表,在当前进程中可以对数据进行相应的操作,但是退出hive时,就自动删除。
- show tables; 查看表是否创建成功。
- 行格式分隔符
- row format delimited: 代表以下为行格式分隔语句
- fields terminated by ’ ’ : 字段之间使用空格分隔
- collection items terminated by ‘-’ : 集合(就是这的数据)使用-分隔
- map keys terminated by ‘:’ : 键值对使用冒号分隔
- lines terminated by ‘\n’ : 记录之间使用换行分隔
- select * from tablename; 查看表中是否有上传的数据
查看表:
- desc tablename;查看表的结构,可以看到每个字段的类型以及分区。
Hive 分区表partition:
必须在表定义时指定对应的partition字段,分区字段在创建表后不能增删改
- 设置开启动态分区
- 修改权限
set hive.exec.dynamic.partiton=true //开启动态分区 - 修改默认状态
set hive.exec.dynamic.partiton.mode=nostrict //默认strict。至少有一个静态分区
- 修改权限
- 分区建表语句:create table tablename (id int)partitioned by(分区字段名 分区字段类型,···);//分区中的字段不能与表中的字段重复,分区后以目录的形式显示,后一个分区字段目录为前一个分区字段目录的子目录。
- 使用load上传:load data local inpath ‘虚拟机文件绝对路径’ into table tablename partition (分区字段名=值,···);//区别为 后面添加partition ();
- 粗细力度分区:根据业务需求,提前进行相应的设定 年月日时分秒,子目录分区越多代表越细。
- 分区目录的修改
例子:
- alter table hour add partition(dt=10,hour=40);//增加dt=10的目录,且在dt=10下增加hour=40的子目录,如果在这个基础再次执行alter table hour add partition(dt=10,hour=50);,则在dt=10下增加hour=50的子目录,若是再次执行alter table hour add partition(dt=20,hour=50);,则增加dt=20的目录,且在dt=10下增加hour=50的子目录。
- alter table tablename drop partition (dt=10,hour=40),则删除dt=10的目录下的hour=40目录,如果hour=40删除之后,dt=10目录为空,则会递归性的将dt=10也删除
Hive 分桶表 bucket
- 设置开启分桶
set hive.enforce.bucketing=true - 创建分桶
create table tablebucketname(
id int,
name string,
age int)
clustered by (age) into 4 buckets//通关age字段去设置分桶,分桶数为4,算法:将age对桶数取余,相同余数的在一个桶内 - 加载数据//在表中添加数据,系统会自行分桶(最好使用l上传以及加载去增加数据)
insert into table tablebucketname select id,name,age from tablebucketname2;(tablebucketname2表中要有数据) - 抽样
select * from buckettablename tablesample(bucket 1 out of 4 on 字段名)
桶的个数从1开始计数。因此,前面的查询从4个桶的第一个中获取所有的用户。 对于一个大规模的、均匀分布的数据集,这会返回表中约四分之一的数据行。我们 也可以用其他比例对若干个桶进行取样(因为取样并不是一个精确的操作,因此这个 比例不一定要是桶数的整数倍)。
Hive连接JDBC
连接方式
- 开启hive的对外连接
有环境变量的情况下执行hiveserver2 - 在类中加载驱动
//加载驱动信息
Class.forName("org.apache.hive.jdbc.HiveDriver");
- 建立JDBC与Hive的连接,获取连接对象
Connection con = DriverManager.getConnection(
"jdbc:hive2://hive所在的linux的ip:10000/连接的数据库", "root", "root");
- 通过连接对象获取执行对象
Statement stmt = con.createStatement();
执行对象的一些API
stmt.execute("drop table if exists " + tableName);
//excute返回值为boolean,可以用来执行一些建表,判断表存不存在等等
stmt.executeQuery("select * from tablename");
//executeQuery的返回值为 一个结果集对象(ResultSet),可以用来查询某个表
if (ResultSet.next()) {
System.out.println(res.getString(1));
}
//用来遍历结果集对象ResultSet
stmt.executeUpdate("delect from tablename");
//返回值为 int 类型,可以用来执行增删改
Hive自定义函数
UDF简介
UDF是用户的自定义函数类,分为2大种类,UDAF(用户自定义聚合函数)和UDTF(用户自定义表生成函数)。
自定义函数实现
-
继承UTF类,重写evaluate方法。
-
根据想要的结果定义返回值,并调用一些基本JAVA方法对传来的参数进行操作,返回结果。
-
将此项目打成jar包,吧jar包上传Linux中。
永久函数- 将打包好的号上传到hive目录的lib目录下。
- 进入hive目录的conf目录下,配置hive-site.xml
添加该配置: <property> <name>hive.aux.jars.path</name> <value>file://jar包的绝对路径</value> 例: <value>file:///opt/hive/lib/*.jar</value> 若是多个值,则用逗号间隔 </property>
- 启动hive,添加函数
create function functionname as "jar包中的类的全限定名";
临时函数,关闭hive后就会消失
- 将jar包添加到linux中
- 在hive中,添加jar包,在添加函数
add jar jar包所在的绝对路径 ; create temporary function functionname as 'jar包中的类的全限定名';\ //temporary 为临时的意思