hive复习日记-持续更新

hive

一、 概念

1.hive是一个构建在hadoop上的数据仓库管理工具(框架),可以将结构化数据文件映射成一张数据表,并使用类sql的方式对这样的文件进行操作。 hive的执行引擎 可以是 mapreduce spark tez
2.hive的元数据存储在数据库 hive的数据存储在HDFS上 hive的计算是基于mr的

二、优缺点

1.学习成本低: 提供类sql查询语言,避免直接写mr程序
2.可扩展性好:基于hadoop的
3.适合做离线分析处理(OLAP):hive的延迟性比较高
4.延展性:hive支持用户自定义函数
5.良好的容错性:基于hadoop 某个节点有问题hql仍可完成执行
6.统一管理:提供了统一元数据的管理 默认是debry

三、架构

架构体系:
	1.用户连接接口:shell命令行,jdbc/odbc,web	ui
	2.thriftserver:软件框架服务,允许客户端通过编程的方式远程访问hive
	3.元数据:hive将元数据存储在数据库 derby、mysql中
	4.驱动器(Driver):
		1)解析器 SQLParser:将hql语句转换成抽象语法树AST,并对抽象语法树进行语法分析
		2)编译器 Compilier:对hql语句进行词法,语法,语义的编译,需要与元数据关联,编译后生成一个有向无环执行计划 即是 一个mr的job
		3)优化器 Optimizer:将执行计划优化,减少不必要的列,使用分区,索引等。优化job
		4)执行器 Executer:将优化后的计划提交给hadoop的yarn上执行。提交job
注意事项:包含 * 的全表查询,不会生成mr任务 eg: select * from table limit 
对于简单的查询,就只是select,不带count,groupby,sum等这样子的聚合函数,都不走mr,直接读取hdfs的文件并进行过滤,可以在hive-site.xml中配置
hive.fetch.task.conversion = more  简单查询不走mr
hive.fetch.task.conversion = minimal 任何简单的都走mr

四、工作原理

1.用户提交任务给Driver
2.驱动程序将hql发送给编译器,检查语法和生成查询计划
3.编译器根任务需求到Metastore中获取hive的元数据信息
4.编译器根据元数据信息对任务进行编译,首先将hql转换抽象语法树,然后将抽象语法树转换成查询块,再将查询块转化为逻辑的查询计划,重写逻辑查询计划,将逻辑查询计划转换为物理计划 即 mapreduce
5.优化器对执行计划进行优化,将最终的计划提交给Driver
6.Dirver将计划转交给ExecutionEngine执行
7.执行作业的过程就是一个mapreduce工作 在执行时执行引擎可以通过Metastore执行元数据操作
8.执行引擎接收来自数据节点的结果 将结果发送给驱动程序,驱动程序将结果发送到hive接口

五、与传统型数据库的区别

1.hive是为了数据仓库而设计的
2.hive不适用于联机事务处理(OTLP),它最适合于基于大量不可变数据的批处理作业

六、hive中库,表的注意事项

1.创建数据库的本质就是创建目录,目录名字为 库名.db。 在元数据库mysql中创建表的相应描述信息
2.创建表的本质在对应的数据库目录下创建子目录 目录名为表名
3.元数据库 在创建库或者表的时候,还会再mysql中(元数据库)添加元数据
4.导入数据:
	1)将数据文件放到对应的表目录下
	2)使用load命令
	3)动态加载 insert into select
	4)加载数据的本质:如果数据在本地,加载数据就是将数据copy到hdfs的表目录下
       				如果数据在hdfs上,就是移动数据到hdfs的表目录下
5.复制表数据  create table  as select 
  复制表结构	 create table  like
6.row format || row format delimited 代表使用自带的serde,列格式
7.stored as  TEXTFILE|SEQUENCEFILE|RCFILE|ORCFILE 指定文件数据格式
8.内部表与外部表的区别
	创建外部表 使用external  location path 指定路径 默认跟内部表路径一致
	删除表时:
		1.内部表和外部表的元数据都会被删除
		2.内部表的表目录会被删除,但是外部表的表目录不会被删除 即文件数据还存在

七、hql的基本用法

1.执行顺序
from->on->join->where->group by->distribute by->having->select->distinct->order by->limit
2.join:内连接 外连接(左外连接,右外连接,全外连接) 注意:hive只支持等值连接 =,and 不支持<> != or
3.left semi join 半开连接,只查询满足条件的左表的信息,相当于exists的用法
4.map-side join:分布式缓存文件,读到内存中
使用场景:存在非常大的表和非常小的表时,将小表缓存到内存中。在maptask执行前将其发送到此次job需要启动map的机器上。 意义:减少map端到reduce端的数据传输 
hive.auto.convert.join=true 默认开启
hive.mapjoin.smalltable.filesize=25000000 23.8MB
5.where 字句中不能使用 =子查询
6.group by 查询的字段要么出现在分组中,要么出现在聚合函数中
执行效率:列名为主键 count(列名)>count(1),否则 count(1)>count(列名)
    	如果列中多列但是没有主键 count(1)>count(*)
    	如果有主键 count(主键)效率是最高的
7.union:将两个或者多个结果集合并,去重并排序
  union all:将两个或者多个结果集合并
8.join操作中,如果多个表关联字段是一样的,则产生一个mr任务
多表连接,会转换成多个MR Job,每一个MR Job在Hive中称为JOIN阶段(Stage)。在每一个Stage,按照JOIN顺序中的最后一个表应该尽量是大表,因为JOIN前一阶段生成的数据会存在于Reducer的buffer中,通过stream最后面的表,直接从Reducer的buffer中读取已经缓冲的中间结果数据(这个中间结果数据可能是JOIN顺序中,前面表连接的结果的Key,数据量相对较小,内存开销就小),这样,与后面的大表进行连接时,只需要从buffer中读取缓存的Key,与大表中的指定Key进行连接,速度会更快,也可能避免内存缓冲区溢出。

八、数据类型

1.自动转换(隐式转换)
	小范围类型的数据会自动转换为大范围类型的数据,再做运算
	tinyint-->smallint-->int-->bigint-->float-->double
	纯数字的string-->double
2.cloName array<type> 小标从0开始,越界不报错 值为null  取值 cloName[index] 
3.cloName map<T,T> 取值 cloName["key"]
4.cloName struct<subname1:type,subname2:type,......> 取值 cloName.["subname1"]
5.展开函数 
	explode(cloName)接受一个数据行,然后返回多个数据行
	lateral view:虚拟表 将UDTF函数生成的多行数据放到一个虚拟表中,然后这个虚拟表默认通过join和输入行进行聚合 eg: select clo  from table explode(cloName)ex as clo

九、窗口函数

1.目的:计算基于组的各种聚合值,对于每个组返回多行 而聚合函数对于组每次返回一行
2.功能:窗口函数兼具分组和排序
	   关键字 distribute by sort by || partition by order by
3.排名函数:相当于多加一列 值为排名
	1)row_number 没有并列名次 顺序递增 相同的根据原数据的顺序
	2rank() 有并列,顺序跳跃递增
	3dense_rank() 有并列,顺序递增
4.聚合函数搭配窗口函数
	1) max(colName) over(distribute by colName1 sort by colName1)
	2) min(colName) over(distribute by colName1 sort by colName1)
	3) sum(colName) over(distribute by colName1 sort by colName1)
	4) avg(colName) over(distribute by colName1 sort by colName1)
	5) count(colName) over(distribute by colName1 sort by colName1)
5.windows字句:默认的窗口范围是从起始行到当前行,可以通过windows字句定义窗口范围
	1)preceding:向前
	2)following:向后
	3)current row:当前行
	4)unbounded:起点,没有边界
	5)unbounded preceding:向上没有边界
	6)unbounded following:向下没有边界
6.常用范围 举例说明
	a)sum(cloName) over() 所有行的cloName相加
	b)sum(cloName) over(partition by cloName) 按照cloName分组,组内所有数据相加
	c)sum(cloName) over(partition by cloName order by cloName)按照cloName分组,逐行累加
	d)sum(cloName) over(partition by cloName order by cloName rows between 1 preceding and current row) 当前行与前一行相加的值
7.first_value:取分组内排序后,第一个值
  last_value:取分组内排序后,最后一个值
  要求的版本数据是null 则需要加上 ignore nulls
8.lag(cloName,n):取出前第n行的数据(取一行,第n行)
  lead(cloName,n):取出后第n行的数据(取一行,第n行)

十、自定义函数

1.分类:
		UDF: 用户自定义函数, 一对一的输入输出
		UDAF:用户自定义聚合函数 多对一的输入输出
		UDTA:用户自定义表生产函数,一对多的输入输出
2.实现UDF方式
		1)继承UDF,重写evaluate(),允许重载
		2)继承GenriuUDF,重写initlizer(),getDisplay(),evaluate()方法
3.使用方式
	第一种:
		1)将项目打包,将jar包添加到hive的classpath
		add jar path
		2)创建临时函数
		create temporary function Name as '类的全限定名'
        3)show functions 查看是否成功
        4)删除 drop temporary function Name
     第二种:
     	1)自定义配置文件,将上述中的两条语句添加到文件中 文件的位置没有要求
     	2)在启动hive时,指定加载该配置文件
     	3)若想永久使用该函数 则将配置文件名改为 .hiverc 并放到hive的bin目录下

十一、分区表

1.分区表的意义:避免全表扫描 本质:表的目录或者是分区的目录下创建目录 分区的目录名位指定字段=2.如何分区:根据业务需求,通常使用 年 月 日 小时 地区等
3.语法 partitioned by 
4.分区名不区分大小写,不支持中文
5.分区字段是一个伪列,但是可以用来操作
6.加载数据时 load .....  partition(cloName='')
7.分区的种类:
		1)静态分区:直接加载数据文件到指定的分区
		2)动态分区:数据未知,根据分区的值来确定需要创建的分区
		3)混合分区:静态和动态的都有
8.分区属性:
		1)严格模式 hive.exec.dynamic.partition.mode=strict/nonstrict
		严格模式下会阻止以下查询:
		1.对分区表查询,where条件中过滤字段不是分区字段
		2.笛卡尔积的join不适用on或者where条件
		3.对order by查询不带limit
9.动态分区加载数据 不能使用load 只能使用	insert into
10.如果分区过多,则会导致namenode和yarn的性能瓶颈。

十二、分桶

1.为什么要分桶:当分区不能更细粒度的划分数据  本质:分区是创建文件夹 分桶是创建文件
2.分桶的原理:与mr中的partitoner的原理一样。 
			hive分桶使用分桶字段的hash值对分桶数量取模
3.分桶的意义:
		1)适合做数据抽样
		2)join操作可以提高mr的查询效率 在map端进行高效的连接操作
		3)为了保存分桶查询结果的分桶结构
4.分桶的操作
		1)clustered by(cloName) [sorted by (cloName) into x buckets]
		2)加载数据只能使用insert into  distribute by || cluster by
		3)在加载数据前要设置reduce个数与分桶数量相同
		set mapreduce.job.reduces
		4)设置强制分桶
		set hive.enforce.bucketing=true 默认是false
		5)强行排序
		set hive.enforce.sorting
5.分桶的查询
		1tablesample(bucket x out of y on cloName) 总共分y桶,从第x桶开始查询
		2)查询第一桶
    		select * from student tablesample(bucket 1 out of 4 on sno);
		3)查询第一桶和第三桶
    		select * from student tablesample(bucket 1 out of 2 on sno);
		4)查询第二桶和第四桶的数据
    		select * from student tablesample(bucket 2 out of 2 on sno);        
		5)查询对8取余的第一桶的数据:
    		select * from student tablesample(bucket 1 out of 8 on sno);
		6)查询三行数据
    		select * from student limit 3;
    		select * from student tablesample(3 rows);
		7)查询百分比的数据
    		select * from student tablesample(13 percent);
		8)查询固定大小的数据
    		select * from student tablesample(68b); 单位(K,KB,MB,GB...9)随机抽三行数据
    		select * from student order by rand() limit 3;
注意:分区是表外字段,分桶是表内字段
	 分桶更加细粒度的管理数据,更多的用来抽样,join

十三、Serde与存储格式

1.文件读取/解析的方式:hive在解析文件时,涉及到两个类
	1)一个类用于从文件中读取一条一条的记录(根据记录分隔符确定一条记录)
	row format:指定用什么inputformat去读数据
	delimited:表示使用org.apache.hadoop.mared.TextInputFormat去读数据行 回车作为行分割符
	2)一个类从上面读到的记录中且分出一个一个的字段(根据指定字符作为分隔符)
	fields terminated by:表示用什么serde类型去解析一行中的数据
	默认使用 org.apache.hadoop.hive.serde2.lazy.LazySimpleSerde 行分隔符 \n 列分隔符 ^A
注意:hive在select时 是将字节序列转换为hive中的对象
		  insert into 是将对象转换为字节序列
2.Serde
	1)hive使用Serde来读/写表的row对象
	2)HDFS文件->InputFileFormat-><key,value>->Deserializer->Row对象
	   Row对象->Serializer-><key,value>->OutputFileFormat->HDFS文件
3.常用Serde:	csv:逗号分隔符 tsv:tab分隔符  json:json格式的数据  regexp:数据需要符合正则
4.hive的存储分为:纯文本文件,二进制文件存储
	1)textfile:纯文本文件,不压缩 默认存储格式
	2)二进制文件
		a)sequencefile:会压缩,不能使用load方式加载数据
		b)rcfile:行列混合存储,会压缩,不能load,查询性能高,所需内存大,计算量大
		c)orc:rc的升级版
		d)parquet:会压缩,不能使用load

十四、索引、视图

索引文件的特点:索引数据有序,并且数据量小 index
语法:create index name on table cloName as 'compact' //索引文件存储格式 with deferred rebuild 索引能够重建
注意:新建索引必须要重建索引 alter index name on table rebuild;

十五、hive的压缩

1.hive的压缩实际就是对底层mr在处理数据时的压缩设置
2.hive在map阶段的压缩
	1)shuffle阶段对mapper产生的中间数据进行压缩,优先选择一个低cpu开销的算法
	2)hive在reduce阶段的压缩:对reduce输出结果进行压缩
3.常用的压缩格式:bzip2、gzip、snappy、lzo(需要建立索引)

十六、数据导出

1.导出到目录下:insert overwrite local directory 'inpath' select 
2.直接导入到本地系统的文件中 hive -e 'select ' >> inpath 
3.修改导出后的列分隔符
insert overwrite local directory 'inpath' row format delimited fields terminated by '\t'

十七、企业级调优

1.环境方面:修改相关服务器的配置,容器的配置,环境搭建
2.具体软件配置参数
3.代码级别的优化
 1)	explain:只有对hql语句的解释
 	 explain extended:对hql语句的解释,以及抽象表达树的生成
 	 stage 相当于一个job,一个stage可以是limit、也可以是一个子查询、也可以是group by等。
	 hive默认一次只执行一个stage,但是如果stage之间没有相互依赖,将可以并行执行。
	 任务越复杂,hql代码越复杂,stage越多,运行的时间一般越长。
  2)join 小结果集驱动大结果集
  	 注意hive是否配置普通join转换成map端join,以及mapjoin小表文件大小的阀值
  3)limit的优化
  	 hive.limit.row.max.size=100000 
	 hive.limit.optimize.limit.file=10 
	 hive.limit.optimize.enable=false (如果limit较多时建议开启) 						       	    hive.limit.optimize.fetch.max=50000
  4)并行执行
  	 hive.exec.parallel=false (建议开启)
	 hive.exec.parallel.thread.number=8
  5)严格模式 hive.mapred.mode=nonstrict
  6)mapper和reducer的个数:不是mapper和redcuer个数越多越好,也不是越少越好。
     将小文件合并处理(将输入类设置为:CombineTextInputFormat) 通过配置将小文件合并:
	 mapred.max.split.size=256000000
	 mapred.min.split.size.per.node=1
	 mapred.min.split.size.per.rack=1
	 hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
	 set mapred.map.tasks=2; 
	 set mapred.reduce.tasks=10
	 hive.exec.reducers.max=1009
   7)配置jvm重用
     mapreduce.job.jvm.numtasks=1 ###
	 mapred.job.reuse.jvm.num.tasks=1
   8)数据倾斜
   	 数据倾斜:由于key分布不均匀造成的数据向一个方向偏离的现象。 本身数据就倾斜
	 join语句容易造成
	 count(distinct col) 很容易造成倾斜
	 group by 也可能会造成
	 找到造成数据倾斜的key,然后再通过hql语句避免。
	 hive.map.aggr=true
	 hive.groupby.skewindata=false (建议开启)
	 hive.optimize.skewjoin=false
	9)索引是一种hive的优化 想要索引在查询时,生效,还得设置使用索引:默认是不使用的。
	 SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
	 SET hive.optimize.index.filter=true;
	 SET hive.optimize.index.filter.compact.minsize=0;
	10)分区
	11)job的数量:一般是一个查询产生一个job,然后通常情况一个job、可以是一个子查询、一个join、一个		 group by 、一个limit等一些操作。

十八、hive和mysql的对比

- mysql用自己的存储存储引擎,hive使用的hdfs来存储。
- mysql使用自己的执行引擎,而hive使用的是mapreduce来执行。
- mysql使用环境环境几乎没有限制,hive是基于hadoop的。
- mysql的低延迟,hive是高延迟。
- mysql的handle的数据量较小,而hive的能handle数据量较大。
- mysql的可扩展性较低,而hive的扩展性较高。
- mysql的数据存储格式要求严格,而hive对数据格式不做严格要求。
- mysql可以允许局部数据插入、更新、删除等,而hive不支持局部数据的操作。
- mysql是严格的写时模式,在写的时候进行检查
- hive是严格的读时模式,加载数据时不检查数据的完整新,读时如果数据不匹配,使用null来代替

十九、hive的数据倾斜

1.什么是hive的数据倾斜?
最本质的就是 数据分布不均衡,一个或几个reduce节点运行很慢,导正整个程序处理时间很长,是因为这个或者这几个节点的key的条数比其他的多很多。
2.容易出现数据倾斜的操作
	1)join
	原因:对于普通的join,会在map端根据key的值,shuffle到一个reduce上去,在reduce端做join操作,内存中缓存join左边的表,遍历右边的表,依次做join操作。当数据量比较大,并且key分布的不均匀,大量的key都shuffle到一个reduce上,就出现了数据倾斜。
	现象:reduce节点大部分执行完毕,但是一个或者几个执行的很慢,导致整个程序运行时间很长。
	解决办法:
	1.hive都是从左向右执行,要注意讲小表在前大表在后。将小表作为驱动表  这里小表指的是 关联记录少的表 这样可以触发reduce端更少的操作次数,减少运行时间。
	2.使用map join 但是前提是:小表驱动大表(如果是大表关联则无法使用)
       map join相当于在map使用combiner,进行join操作
       使用mapjoin将小表放入内存,在map端和大表逐一匹配。从而省去reduce。
    3.大表对大表的时候,可以过滤到一些空值 
      设置 hive.optimize.skewjoin.compiletime=true; 不影响结果的话可以过滤空值
	2)group by
	解决办法:如果是group by过程出现倾斜应将此项设置true
			hive.groupby.skewindata=true;
      开启为true后,会至少开启两个MapReduce,执行时间比开启一个长,因此最好出现数据倾斜之后在开启。

你可能感兴趣的:(大数据)