大数据学习教程SD版第七篇【Hive】

大数据学习教程SD版第七篇【Hive】,第1张

数据学习教程SD版第七篇【Hive】 1. Hive 简介

数据仓库工具,将结构化数据映射成二维表,并提供类SQL查询,底层把HQL转换成MR程序

  • Hive 自带的客户端
  1. hive client
  2. beeline client
  • 特点
  1. HQL 用于数据分析,但处理处理粒度粗
  2. 处理大数据,但延迟高
  3. 支持自定义函数
  • 架构原理

metastore 元数据存储 Client 客户端 MapReduce 计算引擎 HDFS 数据源

  1. 解析器 解析HQL 映射关系,元数据
  2. 编译器 把HQL 转化成MR
  3. 优化器 优化执行的逻辑
  4. 执行器 把执行逻辑 物理化执行
2. Hive vs RDBMS
  1. 查询语言:类似SQL
  2. 数据规模:数据量大
  3. 数据更新:读多写少,导入导出
  4. 执行延迟:量大,延迟高
3. Hive 安装
  1. 下载安装包
  2. 解压安装包
  3. 配置环境变量
  4. 初始化元数据
./schematool -dbType derby -initSchema
  1. 启动测试
# 先启动hadoop,在启动hive
./hive
  • 更改元数据存储位置

hive 默认元数据存在自带的derby 数据库,缺点: 1. 元数据不好查看;2.使用derby 不支持多租户,即不支持多个hive client 同时使用,可以更换元数据存储位置为MySQL

3.1 MySQL安装

此处安装的是rpm的MySQL安装包,所以只适用于redhat系列

  1. 卸载系统自带的MySQL
# 查找
rpm -qa|grep mariadb
rpm -qa|grep mysql
# 卸载,不带依赖的卸载方式
rmp -e --nodeps maridb-libs
  1. 解压tar包并安装rpm包
tar -xvf xx.tar
# 依次安装 common、libs、libs-compat、client、server
rpm -ivh xxx.rpm
# 如果是最小化安装,需要安装额外依赖
rpm install -y libaio
  1. 修改MySQL配置文件
vim /etc/my.cnf # 查看datadir 位置

# 删除datadir 目录下内容
  1. 初始化MySQL
mysqld --initialize --user=mysql

# 查看临时密码
cat /var/log/mysqld.log
  1. 启动MySQL服务并登录
systemctl start mysqld

mysql -u root -pXXX

# 密码需改(可以不修改),各个版本MySQL修改方式不同
set password = password("000000");
  1. 开启MySQL远程连接
# 查看
select host,user from mysql.user;

# 修改
update mysql.user set host='%' where user='root';
flush privileges; 
3.2 Hive metasore

修改元数据存储位置为MySQL

  1. copy 一个MySQL驱动包 到 hive的lib目录下
  2. 在conf下创建一个一个hive-site.xml 配置文件



      
   
		javax.jdo.option.ConnectionURL
		jdbc:mysql://hadoop102:3306/metastore?useSSL=false&allowPublicKeyRetrieval=true
	   
	
		javax.jdo.option.ConnectionDriverName
		com.mysql.jdbc.Driver
	
	
		javax.jdo.option.ConnectionUserName
		root
	 
	
		javax.jdo.option.ConnectionPassword
		000000
	
    
	
	hive.metastore.schema.verification
	false
	
	
	datanucleus.metadata.validate
	false
	

  1. 登录MySQL并创建存储的数据库
create database metastore;
  1. 初始化hive元数据存储库
schematool -initSchema -dbType mysql -verbose
  1. 再次启动hive
hive
3.3 Hive 远程服务

使用元数据服务的方式,开启hive的远程访问

  1. 修改hive-site.xml,添加

    hive.metastore.uris
    thrift://hadoop102:9083

  1. 启动元数据服务
hive --service metastore
4. Hive JDBC

要想使用jdbc连接Hive ,还需要开启hiveserver2的服务

  1. 修改hive-site.xml
         
                hive.server2.thrift.port 
                10000
          
         
                hive.server2.thrift.bind.host
                hadoop102
        
  1. 启动服务
hive --service metastore &
hive --service hiveserver2 &
  • 脚本封装,快速启动

Shell脚本补充知识:

  1. [ 判断 ] && xxx || yyy 前面条件为真,走xxx;为假,走yyy

  2. eval $cmd 执行shell命令

  3. grep -v grep 过滤掉查找的这个grep

#!/bin/bash
HIVE_LOG_DIR=$HIVE_HOME/logs
if [[ ! -d $HIVE_LOG_DIR ]]; then
	mkdir -p $HIVE_LOG_DIR
fi

function check_process(){
	pid=$(ps -ef |grep -v grep |grep -i $1 |awk '{print $2}')
	echo $pid
	[ "$pid" ] && return 0 || return 1
}

function hive_start(){
	metapid=$(check_process Hivemetastore 9083)
	cmd="nohup hive --service metastore > $HIVE_LOG_DIR/metastore.log 2>&1 &"
	[ -z "$metapid" ] && eval $cmd && echo "Hivemetastore Is Starting!" || echo "Hivemetastore Is Running!"
	server2pid=$(check_process HiveServer2 10000)
	cmd="nohup hive --service hiveserver2  >$HIVE_LOG_DIR/HiveServer2.log 2>&1  &"
	[ -z "$server2pid" ] && eval $cmd && echo "Hiveserver2 Is Starting!" || echo "HiveServer2 IS Running!"
}

function hive_stop(){
	metapid=$(check_process Hivemetastore 9083)
	[ "$metapid" ] && kill $metapid && echo "Hivemetastore Is Killing!" || echo "Hivemetastore Not Running!"
	server2pid=$(check_process HiveServer2 10000)
	[ "$server2pid" ] && kill $server2pid && echo "HiveServer2 Is Killing!" || echo "HiveServer2 Not Running!"
}


case $1 in
	"start" )
		hive_start
		;;
	"stop" )
		hive_stop
		;;
	"restart" )
		hive_stop
		sleep 5
		hive_start
		;;
	"status" )
		check_process Hivemetastore 9083 && echo "Hivemetastore Is Running!" || echo "Hivemetastore Not Running!"
		check_process HiveServer2 10000 && echo "HiveServer2 Is Running!" || echo "HiveServer2 Not Running!"
		;;
	* )
		echo "Args Error!"
		;;
esac

两个服务可以通过 jps -ml |grep Hive 查看

5. Hive Shell
hive -e "sql" # 执行SQL
hvie -f query.sql # 执行SQL文件中的SQL
quit;

# 所有的历史 *** 作命令在 当前用户目录下的 .hivehistory 文件中
6. Hive Conf

Hive 的配置优先级:hive client set key=value > hive -hiveconf key=value > hive-site.xml > hive-default.xml

查看Hive配置的值:hive set xxx;

 

    hive.cli.print.header
    true
  
  
    hive.cli.print.current.db
    true
  
7. Hive Type

Hive 日期字符串 能 自动识别成 日期时间戳,并使用对应的函数

复合数据类型 需要指定分隔符,且Array和Map访问时通过下标和Key ,Struct 通过属性名来访问

数据类型JavaHiveIntintintLonglongbigintDoubledoubledoubleStringStringstringDateDatetimestampArrayArrayarray MapMapmap StructClassstruct id:int,name:string
  • 隐式转换

整数类型、String类型 可以隐式的转换成Double类型

  • 强制转换

cast (field as type)

8. Hive SQL 8.1 Hive DDL
# 1.建库
create database [if not exists] xxx
[comment 'xxx']
[location 'xxx'];
# 2.查库
show databases;
show databases like '*xxx*';
desc database xxx;
desc database extended xxx;
# 3.改库,鸡肋
alter database xxx set dbproperties("key"="value");
# 4.删库
drop database xxx;  # 空库
drop database xxx cascade; # 强制删 

表类型分为:管理表(内部表)【默认创建】、外部表

表删除时:内部表会连带删除HDFS上的数据,而外部表则不会,更安全

# 1.建表
create [external] table [if not exists] xxx(
col_name date_type [comment 'col xxx']
)
[comment 'table xxx']
[partitioned by (col type,col2 type2)]
[clustered by (col1,col2)]
[sorted by (col asc|desc) into num_buckets buckets]
[row format delimited fields terminated by 'xxx']
[stored as file_type]
[location file_path]
[as slect_statement];

# 1.m 建表(包含复合类型)
create table test(
name string,
friends array,
children map,
address struct
)
row format delimited fields terminated by ','
collection items terminated by '_'
map key terminated by ':';

# 2.改表
alter table xxx set tblpreperties('EXTERNAL'='TRUE')
alter table xxx rename to new_xxx;
# string 不能改为 int
alter table xxx change old_col new_col type;
# replace 整张表替换为新字段
alter table xxx add|replace columns(col type,col2 type2);
# 删除列,可以使用replace 来间接修改

# 3.查表
show tables;
show create table xxx;
desc xxx;
desc formatted xxx;

# 4.删表
drop table xxx;
8.2 Hive DML
  • 数据导入
# 1.文件导入
load data [local] inpath 'xxx' [overwrite] into table xxx [partition (par_col=par_value)];
# 2.表查询导入
insert into|overwrite table table_name select * from table2_name;
# 3.表创建导入
create table if not exists table_name as select * from table_name2;
# 4.表创建指定路径导入
create table …… location 'xxx';
# 5.import方式导入,路径必须是export导出路径
import table xxx from 'hdfs_path';
  • 数据导出
# 1.insert 导出
insert overwrite [local] directory 'xxx' [row format delimited fields terminated by ','] select * from table_name ;
# 2.get 导出
dfs -get /remote /local
# 3.client 导出
hive -f xxx.sql >> result.txt
# 4.export 导出
export table xxx to 'hdfs_path';

不同数据导入方式count(*)结果的问题:

insert方式:元数据中 numFiles numRows 均改变,不走mr,结果正确

put方式:元数据中上述参数不变,不走mr,结果不对

load方式:元数据中 numFiles 改变,numRows 参数不变,走mr,结果正确

如果load加载的是本地文件,则上传至HDFS对应位置,如果加载的是HDFS文件,则移动文件位置

  • 清空数据
# 只能清空管理表
truncate table xxx;
8.3 Hive DQL

执行顺序:

  1. from
  2. join on
  3. where
  4. group by
  5. avg(),sum()……
  6. having
  7. select
  8. distinct
  9. order by
  10. limit
  • 基础语法
# Hive SQL 大小写不敏感,不用能tab缩进
select * from table_name;
select col1,col2 from table_name;

# 1.alias
as

# 2.数值运算
+ - * /

# 3.聚合函数
count  max min sum avg

# 4.limit
limit x;

# 5.过滤
where

# 6.比较
> >= < <= <>  != is [not] null  in (x,y)
[not] like % _
x<=>y : 一边为null,为false
between xx and yy: 左右皆闭合
and or not

# 7.分组
group by xxx having yyy

# 8.连接
## 1.inner join
xxx join yyy on
## 2.left outer join
xxx left join yyy on
## 3.right outer join
xxx right join yyy on
## 4.full outer join
xxx full join yyy on
## 5.xxx - yyy 左xxx表独有数据
xxx left join yyy on  where xxx.col is null
xxx left join yyy on  where xxx.col not in(select col from yyy)
## 6.yyy - xxx 和上面 *** 作相反 右yyy表独有数据
## 7.xxx 和yyy 各自独有的数据
xxx left join yyy on  where xxx.col is null or yyy.col is null;
## union 连接时两表查询字段必须一致; union all 不去重,效率更高
select mmm from ( ……t1 union ……t2)tmp;

# 9. 排序,全局排序,reduce个数始终是一个
order by xxx asc|desc
## 每个分区内部排序有序,整体无序,分区规则随机,可通过 distribute by 指定
sort by xxx asc|desc
distribute by col sort by xxx asc
## 当 distribute by 和 sort by 字段一致时,限制:只能asc
cluster by xxx

# 10.分区,多目录,可以避免全表扫描,正常按天导入数据
## 1.加分区
alter table table_name add partition(par_name=par_value);
## 2.删分区
alter table table_name drop partition(par_name=par_value);
## 3.查分区
show partitions;
desc formatted table_name;
## 二级分区,两个分区字段
## 分区调整:手动put方式加载到分区表目录,需要修复元数据
msck repair table table_name;
## 动态分区:根据查询结果动态的插入到指定分区中
### 1.关闭严格模式,下面的语句不加[],就可以不关
set hive.exec.dynamic.partition.mode=nonstrict;
### 2.查询的最后一个字段为分区字段
insert into table table_name [partition(par_name)]
select xxx,xxx,par_name from X;

# 11.分桶,多文件,不常用,抽样查询
create table table_name(id int,name string)
clusted by(id)
into 4 buckets
row format delimited fields terminated by 't';
  • 常用函数

按照处理数据的行数,划分:

UDF:一进一出 ,比如:upper、nvl、split、concat

UDAF:多进一出,比如:count、sum、collect_set

UDTF:一进多出,比如:explode

# 显示Hive自带函数
show functions;
desc function fun_name;
desc function extended fun_name;

# 1.nvl
select nvl(col1,col2) from X;

# 2.case when then else end   |   if(condation,x,y)

# 3.concat、concat_ws、collect_set
select concat(col1,str,col2……) from
select concat_ws(sep,str1,str2,arr1,……) from
# set 去重
select collect_set(col) from

# 4.explode、lateral view:侧写
select explode(arr) from

select new_col from old_table
lateral view explode(arr) new_table as new_col

未完待续……

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5679134.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存