Hive 技术体系结构

# hive 安装
安装指南

hive 架构

体系结构图

工作原理

SQL生成执行计划

	(1).词法、语法分析
	使用antlr将SQL解析成Abstract syntax tree

	(2).语义分析
	 从Metastore获取模式信息,验证SQL语句中列表,列名以及数据类型检查和隐式转换,以及hive提供的函数和用户自定义函数(udf/udaf)

	(3).逻辑计划生成
	生成逻辑计划-算子树(MR对应的MapReduce处理程序,spark对应的算子)

	(4).逻辑计划优化
	对算子树进行优化,包括列剪枝,分区剪枝,谓词下推
	
	(5).物理计划生成
	将逻辑计划生成包含MapReduce任务组成的DAG物理计划
	
	(6).返回结果

组成部分

  • hive配置文件
配置与hdfs,spark,tez等连通交互的方式,hive日志、指标跟踪,问题诊断
  • hive命令行
执行HQL,使用近似SQL(使用antlr解析SQL)语句进行数据查询、处理、
  • hive组件:
beeline:提高访问hive的并发度,可同时对hive数据DML操作
hive-cli:使用HQL进行对数据进行操作,执行DML操作
Hcatalog:为多种工具提供一种通用模式环境,运行多种工具(sqoop,flume,spark,MR等)连接,进而从hive仓库读取、写入数据,跨工具共享数据,为Hadoop数据创建一种关系结构,抽象出数据存储的方式和位置,使模式和存储的更改对用户不可见
hiveserver2:提供使用ODBC、JDBC连接hive之外的方式,支持Kerberos、自定义身份验证及通过LDAP身份验证
hplsql:执行HQL语句、文件
schematool:在RDBMS或Derby中初始化hive元数据,一般选用MySQL,PstorageSQL,Oracle数据库
  • 执行引擎
MapReduce,Tez,Spark(推荐,使用内存、缓存处理数据,效率更高)
  • WebChat
可以用来提交Hadoop MapReduce(or Yarn),Pig,Hive jobs到hive的服务,也可以使用HTTP(Rest接口去执行hive 元数据操作

数据类型

全部有Java实现

基本数据类型

数值型

  • TINYINT (1-byte signed integer, from -128 to 127)
  • SMALLINT (2-byte signed integer, from -32,768 to 32,767)
  • INT/INTEGER (4-byte signed integer, from -2,147,483,648 to 2,147,483,647)
  • BIGINT (8-byte signed integer, from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)
  • FLOAT (4-byte single precision floating point number)
  • DOUBLE (8-byte double precision floating point number)
  • DOUBLE PRECISION (alias for DOUBLE, only available starting with Hive 2.2.0)
  • DECIMAL
 Introduced in Hive 0.11.0 with a precision of 38 digits
 Hive 0.13.0 introduced user-definable precision and scale
  • NUMERIC (same as DECIMAL, starting with Hive 3.0.0)

日期/时间行

  • TIMESTAMP (Note: Only available starting with Hive 0.8.0 **)
  • DATE (Note: Only available starting with Hive 0.12.0 **)
  • INTERVAL (Note: Only available starting with Hive 1.2.0 **)

String

  • STRING
  • VARCHAR (Note: Only available starting with Hive 0.12.0 )
  • CHAR ** Note: Only available starting with Hive 0.13.0 )

Boolean

  • BOOLEAN
  • BINARY (Note: Only available starting with Hive 0.8.0 )

复杂数据类型

  • arrays: ARRAY<data_type> ( Note: negative values and non-constant expressions are allowed as of Hive 0.14. )
定义ITEMS数组:

ITEMS   ARRAY<"Bread","Butter","Organic Eggs">

取值 --下标从0开始
ITEMS[0] : "Bread"  
ITEMS[2] : "Organic Eggs"  
  • maps: MAP<primitive_type, data_type> (Note: negative values and non-constant expressions are allowed as of Hive 0.14.)
定义Basket 键/值对集合
Basket MAP<'string','int'>
Basket MAP<'eggs','12'>

create table demo1(id int,basket MAP<string,int>);

取值:
Basket("eggs")
  • structs: STRUCT<col_name : data_type [COMMENT col_comment], …>
  • union: UNIONTYPE<data_type, data_type, …> (Note: Only available starting with Hive 0.7.0.)




# DDL





## 数据库操作(多模数据库)



## 数据表操作
 - 建库
CREATE DATABASE IF NOT EXISTS  geo  COMMENT  ' practice demo'   LOCATION  '/jerry/hive/dw/geo' 
 WITH DBPROPERTIES('purpose'='stage');

 - 查看数据库
  (1)查看某个数据库
  hive>  DESCRIBE DATABASE EXTENDED geo;
  OK
  geo        hdfs://jerry:9000/user/hive/warehouse/geo.db    jerry    USER    
  Time taken: 0.468 seconds, Fetched: 1 row(s)
   (2)查看所有所有数据
   SHOW DATABASES;      

- 修改数据库属性

ALTER DATABASE geo
SET DBPROPERTIES(‘HOSTNAME’=‘NAMENODE’);


- 删除数据库

级联删除(级联删除所有内部表,外部表)
DROP DATABASE geo CASCADE;
RESTRICT删除(如果有数据表,则删除失败,无法删除):
DROP DATABASE geo;


# 内部表

## 概念

是由hive管理的表,hive进行删除时,会将表结构和数据一并删除

## 内部表操作
- 加载数据表

hdfs dfs -mkdir -p /user/jerry/demo/iris
hdfs dfs -put iris.csv /user/jerry/demo/iris


- 创建内部表来访问文件state.txt中数据

CREATE TABLE iris(sepalLength double,sepalWidth double,petalLength double,petalWidth double)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’ LINES TERMINATED BY ‘\n’
STORED AS TEXTFILE LOCATION ‘/user/jerry/demo/iris’
TBLPROPERTIES (‘table_comment’=‘iris data’);


- 查看数据表的属性

(1). 查看表结构
hive> describe iris;
OK
sepallength double
sepalwidth double
petallength double
petalwidth double
Time taken: 0.058 seconds, Fetched: 4 row(s)

(2).查询详细信息
hive> desc formatted iris;
OK

col_name data_type comment

sepallength double
sepalwidth double
petallength double
petalwidth double

Detailed Table Information

Database: default
OwnerType: USER
Owner: jerry
CreateTime: Mon Nov 25 18:50:13 CST 2019
LastAccessTime: UNKNOWN
Retention: 0
Location: hdfs://jerry:9000/user/jerry/demo/iris
Table Type: MANAGED_TABLE
Table Parameters:
bucketing_version 2
numFiles 1
table_comment iris data
totalSize 2700
transient_lastDdlTime 1574679013

Storage Information

SerDe Library: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
InputFormat: org.apache.hadoop.mapred.TextInputFormat
OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Compressed: No
Num Buckets: -1
Bucket Columns: []
Sort Columns: []
Storage Desc Params:
field.delim ,
line.delim \n
serialization.format ,
Time taken: 0.07 seconds, Fetched: 34 row(s)



## 外部表
## 概念
- 是由hive管理的表,hive进行删除时,只将表结构删除,无法管理从外部链接的表数据

外部表操作

  • 上传文件
 hdfs dfs -mkdir -p /user/jerry/demo/public
hdfs dfs -put  public_Y.csv  /user/jerry/demo/public
  • 创建外部表
CREATE EXTERNAL TABLE public(id int,checking int,duration int,history int,purpose int,amount double,savings int,employed int,installp int,marital int,coapp int,resident int,property int,age int,other int,housing int,existcr int,job int,depends int,telephon string,foreigns int,checkingstr string,historystr string,GEO_Y int)
 ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' 
LINES TERMINATED BY '\n' 
STORED AS TEXTFILE LOCATION '/user/jerry/demo/public' 
TBLPROPERTIES("table_comment"="text_data");
  • 加载数据
(1).加载本地数据
LOAD DATA LOCAL INPATH '/user/jerry/demo/public' INTO TABLE public PARTITION (checkingstr);
(2).加载hdfs数据
LOAD DATA INPATH '/user/jerry/demo/public' INTO TABLE public PARTITION (checkingstr);
  • 查询
hive> select * from public limit 2;
OK
733	2	8	2	3	760.0	1	4	4	2	3	2	1	44	3	2	1	2	1	1	1	jiaoche	CHN	0
829	1	36	2	1	8335.0	5	5	3	3	1	4	4	47	3	3	1	3	1	1	1	kache	CHN	1
Time taken: 0.137 seconds, Fetched: 2 row(s)
  • 删除数据表后文件仍然存在
hive> drop table public;
OK
Time taken: 0.542 seconds
hdfs dfs -ls   /user/jerry/demo/public/
Found 1 items
-rw-r--r--   3 jerry supergroup      63213 2019-11-26 10:56 /user/jerry/demo/public/public.csv

分区

  • 概念
一个表根据分区列的列值,会有一个或多个分区键,基于这些键,数据被分割成若干逻辑块并存在单独的路径中。
每个分区都为表的存储添加了一个目录层结构,插入数据时指定分区列的列值,查询时指定分区列值。
常用在RDBMS中,提高性能和高效管理数据,hive分区功能与其无差别。
  • 适用场景
数据过大,分区后,可以将数据均匀分布到每个分区中,分区大小越大越好(避免小于1G)
  • 注意事项
分区列只能出现PARTITIONED BY后面,不需要加在表定义(create table public(..列名..))中,否则会报错:FAILED:Error in semantic analysis: Column repeated in partitioning columns
  • 创建分区表
CREATE EXTERNAL TABLE public(id int,checking int,duration int,history int,purpose int,amount double,savings int,employed int,installp int,marital int,coapp int,resident int,property int,age int,other int,housing int,existcr int,job int,depends int,telephon string,foreigns int,historystr string,GEO_Y int) 
PARTITIONED BY (checkingstr string comment "purchaseThingsType") 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' 
STORED AS TEXTFILE 
LOCATION '/user/jerry/demo/public' TBLPROPERTIES("table_comment"="text_data");
  • 插入分区表
hive> insert into public PARTITION(checkingstr="jiaoche") values(141,3,6,2,0,709,4,2,2,4,1,2,1,27,3,2,1,1,1,1,2,'CNN',0);
Query ID = jerry_20191126120510_7b90ba60-9bd2-4c95-b821-aae3aeaa4aaa
Total jobs = 1
Launching Job 1 out of 1
In order to change the average load for a reducer (in bytes):
  set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
  set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
  set mapreduce.job.reduces=<number>
Hive on Spark Session Web UI URL: http://jerry:4040
Query Hive on Spark job[1] stages: [2, 3]
Spark job[1] status = RUNNING
STAGES   ATTEMPT        STATUS  TOTAL  COMPLETED  RUNNING  PENDING  FAILED  
Stage-2 ........         0      FINISHED      1          1        0        0       0  
Stage-3 ........         0      FINISHED      3          3        0        0       0  
STAGES: 02/02    [==========================>>] 100%  ELAPSED TIME: 2.03 s     
Spark job[1] finished successfully in 2.03 second(s)
Loading data to table geo.public partition (checkingstr=jiaoche)
OK
Time taken: 3.997 seconds
  • Best Practice
(1).一般选取数据分布较集中,选择性较高的列(日期(YYYY-MM-DD),地域,省份,职业等特)作为分区,减少数据筛选数量,提高查询命中率
(2).避免分区小于1GB(越大越好).
(3).挑选一列作为分区键,其唯一值的个数应在较地值和中间值之间
(4).当分区较多时,调整HiveServer2 和 Hive Metastore内存
(5).当使用多列作为分区键时,对于每个分区键列的组合都要创建一个子目录的嵌套树,故应避免深入嵌套,导致太多的f分区,进而使创建的文件非常小
(6).hive流处理插入数据数据时,如果多个会话向相同的分区写入数据,那么就会导致锁闭.
(7).可以修改某分区表的模式,但是结构一旦发生改变,无法在已有分区修改数据
(8).数据并行插入多个分区,开启hive动态分区 set hive.optimize.sort.dynamic.partition=true;
  • 例子(使用日期做分区)
(1) 查询特定日期
SELECT * FROM t_order WHERE updateTime in ('2015-01-01','2019-01-02','2018-09-09')
(2)查询一年中所有的日期
SELECT * FROM t_order WHERE updateTime LIKE '2015-%';
(3)查询一年中2月所有的日期
SELECT * FROM t_order WHERE updateTime LIKE '2015-02-%';
(4)查询所有以5结尾的日期
SELECT * FROM t_order WHERE updateTime LIKE '%-%-%5';
(4)查询某段时间的数据(2019-01-01 至 2019-10-01)
SELECT * FROM t_order where updateTime BETWEEN '2019-01-01'  AND  '2019-01-01;

##分桶

  • 概念
另一种将数据切分为更小片段的方式.
将作为分桶列的列值作为桶,
  • 适用场景
若数据过大,且分区后数据分布不均匀,导致出现大量非常小的分区.因为分区建的每个都没多少行数据

DML

查询

新增

修改

删除

问题总结

数据倾斜

发生原因

在map任务完成后,某些map任务输出文件数据过少,某些过多,造成reducer端某些reduce task处理时间过长,甚至失败

发生情况

join 时null值过多

  • 发生原因
map输出后,reduce task运行时,所有null都在一个reduce.null过多,会造成与null关联的分区数据过多,造成任务运行时间过长
  • 解决方法

管理时不让null值进行关联(使用union all将结果进行null关联和非null关联的结果合并),先join不为空值的(通过获取A中userid不空的列,与B表中userid相等的列来实现),然后join为null的值(通过在A表中判断B中的userid为空的方式获取)

select  * from TableA a  join TableB b on  ( a.userid=b.userid ) where   a.userid IS NOT NULL  UNION ALL select * from TableA where  b.userid IS NULL  ;

对null提前处理,添加随机数

null:null123 null:789 ...
hive内置函数

关联的时候数据类型不统一

  • 发生原因
管理时数据类型不一致,表示范围小的数据类型(ru id :String ,userid int,in 是小类型)会是一个分区
大的数据类型在reduce端是一个分区,数据过多会造成数据倾斜
  • 解决方法
将二者类型在管理时转换成一致
 (cast id as int)

大小表关联

  • 发生原因
 大小表关联,大表作为驱动表时,数据过多会进行shuffle,造成计算时间过长
  • 解决方法
(1).map端join
(2).效率高,并行度高,不易产生数据倾斜
(3).开启map端join后,并设置map join的阈值(低于25MB会进行map端join):set hive.auto.convert.join = true,set hive.mapjoin.smalltable.filesize = 25000000 
(4).开启map端join后,默认会把小表放在缓存中。如果最小表大于设置的阈值,默认走reduce端的join。
(5)大表 join大表处理数据倾斜:
切分其中一个大表。一对多。切多的表。26MB 1GB默认 reduce端join 强制走map端join 。
/*+mapjoin(a)*/ ,a表示需要加载到缓存中的表。只要小表大小内存可以承受。/*+mapjoin(a)*/
select a.*.b.* from a join b on a.id = b.id

参考来源

发布了150 篇原创文章 · 获赞 15 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/dymkkj/article/details/103305575