基于Hadoop的数据仓库解决方案
Hive是Apache顶级项目
Hive下载安装请查看: Hive安装及单机模式配置.
-e、-f
hive -e "show databases;"
hive -e "create database test1;"
hive -f "hive.sql"
-e、-f、-u
beeline -e "show databases;" -u "jdbc:hive2://hadoop:10000"
beeline -f hive.sql -u "jdbc:hive2://hadoop:10000"
Hive有两种客户端工具:Beeline和Hive命令行(CLI)
有两种模式:命令行模式和交互模式
1)记录数据仓库中模型的定义、各层级间的映射关系
2)存储在关系数据库中
3)HCatalog
hive
nohup hive --service metastore & (启动元数据服务)
nohup hive --service hiveserver2 &
beeline
!connect jdbc:hive2://hadoop:10000
连接成功结果如下:
Connected to: Apache Hive (version 1.1.0-cdh5.14.2)
Driver: Hive JDBC (version 1.1.0-cdh5.14.2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
操作 | HiveServer2 Beeline | HiveServer1 CLI |
---|---|---|
进入方式 | beeline | hive |
连接 | !connect | 无 |
查看所有表 | !table | show tables; |
查看表的所有列 | !column |
desc table_name; |
保存结果记录 | !record |
无 |
执行shell命令 | !sh ls | !ls; |
操作HDFS | dfs -ls | dfs -ls ; |
运行SQL文件 | !run |
source |
检查版本 | !dbinfo | !hive --version; |
退出交互模式 | !quit | quit; |
分为内部表和外部表
1)内部表(管理表)
2)外部表(External Tables)
基本数据类型
类型 | 示例 | 类型 | 示例 |
---|---|---|---|
tinyint | 10 | smallint | 10 |
int | 10 | bigint | 100L |
float | 1.342 | double | 1.234 |
decimal | 3.14 | binary | 1010 |
boolean | true/false | string | ‘Book’ or “Book” |
char | ‘YES’ or “YES” | varchar | ‘Book’ or “Book” |
date | ‘2013-01-31’ | timestamp | ‘2020-01-31 00:13:00.345’ |
集合数据类型
类型 | 格式 | 定义 | 示例 |
---|---|---|---|
array | [‘Apple’,‘Orange’,‘Mongo’] | ARRAY |
a[0] = ‘Apple’ |
map | {‘A’:‘Apple’,‘O’:‘Orange’} | MAP |
b[‘A’] = ‘Apple’ |
struct | {‘Apple’,2} | STRUCT |
c.weight = 2 |
数据结构 | 描述 | 逻辑关系 | 物理存储(HDFS) |
---|---|---|---|
Database | 数据库 | 表的集合 | 文件夹 |
Table | 表 | 行数据的集合 | 文件夹 |
Partition | 分区 | 用于分割数据 | 文件夹 |
Buckets | 分桶 | 用于分布数据 | 文件 |
Row | 行 | 行记录 | 文件中的行 |
Columns | 列 | 列记录 | 每行中指定的位置 |
Views | 视图 | 逻辑概念,可跨越多张表 | 不存储数据 |
Index | 索引 | 记录统计数据信息 | 文件夹 |
Hive
是基于Hadoop
的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的 sql 查询功能,可以将 sql 语句转换为MapReduce
任务进行运行。其优点是学习成本低,可以通过类 SQL 语句快速实现简单的MapReduce
统计,不必开发专门的MapReduce
应用,十分适合数据仓库的统计分析。
Hvie
是建立在Hadoop
上的数据仓库基础架构。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在Hadoop
中的大规模数据的机制。Hive
定义了简单的类 SQL 查询语句,称为HQL
,它允许熟悉SQL的用户查询数据。同时,这个语言也允许熟悉MapReduce
开发者的开发自定义的mapper
和reducer
来处理内建的mapper
和reducer
无法完成的复杂的分析工作。
HQL与SQL的区别
查询语言 | HQL | SQL |
---|---|---|
数据存储位置 | HDFS | Raw Device或者Local FS |
数据格式 | 用户定义 | 系统决定 |
数据更新 | 不支持 | 支持 |
索引 | 无 | 有 |
执行 | Mapreduce | Executor |
执行延迟 | 高 | 低 |
可扩展性 | 高 | 低 |
数据规模 | 大 | 小 |
字段:^A(\001)
集合:^B(\002)
映射:^C(\003)
嵌套:^D(\004)
分隔符可不选,不选则为默认分隔符
create table c(
id int,
name string,
info struct<gender:string,age:int>,
hunji array<string>,
zongmen map<string,int>)
comment 'This is an external table' #表注释,可选
row format delimited
fields terminated by '|' #字段分隔
collection items terminated by ',' #分隔集合和映射
map keys terminated by ':' #属性值分隔
lines terminated by '\n' #行分隔
stored as textfile #文件存储格式()
location '/user/root/employee'; #文件存储路径
创建外部表关键字:external
create external table if not exists employee_external(
name string,
work_place array<string>,
sex_age struct<sex:string,age:int>,
skills_score map<string,int>,
depart_title map<string,array<string>>)
row format delimited
fields terminated by '|'
collection items terminated by ','
map keys terminated by ':'
stored as textfile;
临时表是应用程序自动管理在复杂查询期间生产的中间数据的方法
create temporary table if not exists employee_temp(
name string,
work_place array<string>,
sex_age struct<sex:string,age:int>,
skills_score map<string,int>,
depart_title map<string,array<string>>);
1)CTAS 创建:会插入查询到的数据
create table ctas_employee as select * from employee_external;
2)CTE (CTAS with Common Table Expression) 子查询创建
create table cte_employee as with
r1 as (select * from employee_external limit 1),
r2 as (select * from employee_external where name='Will')
select * from r1 union all select * from r2;
select * from ctas_employee;
3)like 建表
create table like_employee like employee_external;
1)创建数据库
create database DataBaseNmae;
2)删除数据库
drop database DataBaseNmae;
1)删除表
drop table if exists tableName [purge];
2)删除表数据
truncate table tableName;
1)修改表名
alter table oldTableName rename to newTableName;
2)修正表文件格式
alter table tableName set fileformat rcfile; #rcfile文件格式
3)修改分隔符
alter table tableName set serdeproperties ('field.delim' = '$');
4)修改表列名
alter table tableName change old_name new_name string;
5)添加列
alter table tableName add columns (LieName string);
6)替换列
alter table tableName replace columns (name string);
Load 用于在 Hive 中移动数据
关键字:local、overwrite
local:指定文件位于本地文件系统,执行后为拷贝数据,即原文件还在本地
overwrite:表示覆盖表中现有数据,不写代表追加数据到表中
1)导入本地文件到表
load data local inpath '/opt/hiveText/employee.txt'
overwrite into table employee;
2)导入HDFS文件到表
load data inpath '/hive/employee.txt'
overwrite into table employee;
创建分区表
create table if not exists employee_partition(
name string,
work_place array<string>,
sex_age struct<sex:string,age:int>,
skills_score map<string,int>,
depart_title map<string,array<string>>)
partitioned by (month string)
row format delimited
fields terminated by '|'
collection items terminated by ','
map keys terminated by ':'
stored as textfile;
静态分区操作
1)添加分区
alter table employee_partition add partition(month='201906') ;
alter table employee_partition add partition(month='201905') partition(month='201904');
2)删除分区
alter table employee_partition drop partition (month='201904');
alter table employee_partition drop partition (month='201905'), partition (month='201906');
3)加载数据到分区表
load data local inpath '/opt/hiveText/employee.txt'
into table employee_partition partition(month='202012');
创建多级分区
1)创建多级分区表
create table if not exists employee_partition2(
name string,
work_place array<string>,
sex_age struct<sex:string,age:int>,
skills_score map<string,int>,
depart_title map<string,array<string>>)
partitioned by (month string,day string)
row format delimited
fields terminated by '|'
collection items terminated by ','
map keys terminated by ':'
stored as textfile;
2)添加多级分区
alter table employee_partition2 add
partition(month="202012",day="01")
partition(month="202012",day="02")
partition(month="202012",day="03")
partition(month="202012",day="04");
3)加载数据到多级分区表
load data local inpath '/opt/hiveText/employee.txt'
into table employee_partition2 partition(month='202012',day='01');
1)使用动态分区需设定属性
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
2)动态分区建表语句和静态分区相同
create table if not exists employee_hr_partition(
name string,
id int,
num string,
date string)
partitioned by (month string,day string)
row format delimited
fields terminated by '|';
3)动态分区插入数据
创建非分区表
create table if not exists employee_hr(
name string,
id int,
num string,
date string)
row format delimited
fields terminated by '|';
导入数据到非分区表中
load data local inpath '/opt/hiveText/employee_hr.txt'
into table employee_hr;
将非分区表中数据导入到分区表中
insert into table employee_hr_partition partition(month,day)
select name,id,num,date,
month(date) as month,
date(date) as day
from employee_hr;
1)查看分区数
show partitions employee_partition2;
select * from employee_hr_partition where month='9' and day='2017-09-30'
1)分区对应于HDFS中的文件夹
2)分桶对应于HDFS中的文件
3)分桶只有动态分桶
set hive.enforce.bucketing = true;
4)定义分桶
clustered by(employee_id) into 2 buckets;
5)必须使用 insert 方式加载数据
6)创建分桶表
create table if not exists hr_bucket(
name string,
id int,
num string,
time string)
clustered by(id) into 4 buckets
row format delimited
fields terminated by '|';
7)往分桶表中插入数据
-- 清空分桶表数据
truncate table hr_bucket;
-- 往分桶表中插入数据
insert into table hr_bucket select * from employee_hr;
1)随机抽样基于整行数据
select * from hr_bucket tablesample (bucket 3 out of 32 on rand())s;
2)随机抽样基于指定列(使用分桶列更高效)
select * from hr_bucket tablesample (bucket 2 out of 4 on id) s;
概述:
应用场景:
1)创建视图
create view view_hr as
select name,id from employee_hr where id>10;
2)查找视图
show views;(在hive2.2.0以后)
show tables;
3)查看视图定义,查看是否是视图
show create table view_name;
4)删除视图
drop view view_name;
5)更改视图定义
alter view view_name as select statement;
6)更改视图属性
alter view view_name set tblproperties ('comment' = 'This is a view');
使用 lateral view explode实现列转行
select name,wps,skills,score
from employee
lateral view explode(work_place) workplace as wps
lateral view explode(skills_score) sks as skills,score;
事务指一组单元化操作,这些操作要么都执行,要么都不执行
1)ACID 特性:
2)事务的特点和局限性
局限:
1)通过命令行方式开启事务
set hive.support.concurrency = true;
set hive.enforce.bucketing = true;
set hive.exec.dynamic.partition.mode = nonstrict;
set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.compactor.initiator.on = true;
set hive.compactor.worker.threads = 1;
2)通过配置文件设置,全局有效
<property>
<name>hive.support.concurrency</name>
<value>true</value>
</property>
<property>
<name>hive.txn.manager</name> <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
</property>
Hive存储过程(hive2.0以后可用)
1)EXPLAIN
显示查询语句的执行计划,但不运行
语法:
EXPLAIN [EXTENDED|DEPENDENCY|AUTHORIZATION] hive_query
参数说明:
示例:
explain
select dept_num,
count(name) as num,
max(salary) as max_salary,
min(salary) as min_salary,
sum(salary) as sum_salary,
avg(salary) as avg_salary
from employee_contract
group by dept_num;
2)ANALYZE
分析表数据,用于执行计划选择的参考
收集表的统计信息,如行数、最大值等
使用时调用该信息加速查询
语法:
ANALYZE TABLE employee COMPUTE STATISTICS;
1)Job优化 - 本地模式运行
Hive支持将作业自动转换为本地模式运行
开启本地模式
set hive.exec.mode.local.auto=true; --开启本地模式
set hive.exec.mode.local.auto.inputbytes.max=50000000; --输入最大字节数,默认128M
set hive.exec.mode.local.auto.input.files.max=5; --文件个数,默认为4
Job必须满足以下条件才能在本地模式下运行
2)Job优化 - JVM重用(JVM Reuse)
通过JVM重用减少JVM启动的消耗
开启 JVM 重用
set mapred.job.reuse.jvm.num.tasks = 5; -- 默认值为1
3)Job优化 - 并行执行
并行执行可提高集群利用率
开启并行执行
set hive.exec.parallel=true; -- default false
set hive.exec.parallel.thread.number=16; -- default 8,定义并行运行的最大数量
4)查询优化
– 防止数据倾斜
set hive.optimize.skewjoin=true;
– 启用CBO(Cost based Optimizer)
set hive.cbo.enable=true;
set hive.compute.query.using.stats=true;
set hive.stats.fetch.column.stats=true;
set hive.stats.fetch.partition.stats=true;
– 启动Vectorization(矢量化)
set hive.vectorized.execution.enabled = true;
set hive.vectorized.execution.reduce.enabled = true;
5)防止数据倾斜
某些节点计算的能力较差或者由于此节点需要计算的数据比较多,导致数据倾斜
在hive中产生数据倾斜的场景:
(1)group by产生数据倾斜
(2)大表和小表进行join操作
(3)空值产生的数据倾斜
(4)小文件过多或文件过于复杂
6)压缩数据
常用压缩方法对比
压缩方式 | 可分割 | 压缩后大小 | 压缩解压速度 |
---|---|---|---|
gzip | 否 | 中 | 中 |
lzo | 是 | 大 | 快 |
snappy | 中 | 大 | 快 |
bzip2 | 是 | 小 | 慢 |
Hive高级语法请查看: Hive高级语法、Hive函数.