Hive笔记整理

目录

1.hive简介

1.1 什么是hive

1.2 hive的元数据存储

1.3 hive与传统数据库的区别

2.hive原理 

3.hive的数据管理

3.1 hive中的内部表和外部表

3.2 hive中的分区表

3.3 hive中的分桶表

4.hive的调优

4.1 hive job的优化——表优化

4.2 hive job的优化——并行化执行

4.3  hive job的优化——本地化执行

4.4 hive job的优化——job合并输入\输出小文件

4.4 hive job的优化——jvm重用

4.5 hive job的优化——压缩数据


1.hive简介

1.1 什么是hive

hive是一种基于Hadoop的数据仓库工具,它可以将结构化的数据文件映射为一张数据表,并提供类sql查询功能。它可以将sql语句转换为MapReduce任务进行运行。hive主要是利用HDFS来存储数据,利用MapReduce来查询分析数据。它的本质是将sql转换成MapReduce程序,比直接用MapReduce开发效率更高。hive在运行时,实际的源数据存在HDFS上,而描述数据的元数据存放在关系型数据库中(有三种存储方式,建议存在关系型数据库中)。

1.2 hive的元数据存储

hive的元数据存储方式:

1.内存数据库 derby,安装小,但是数据存在内存,不稳定

2.mysql数据库,数据存储模式可以自己设置,持久化好,查看方便。

hive中元数据包括表的名字,表的列和分区以及属性,表的属性(是否为外部表),表的数据所在目录等。

1.3 hive与传统数据库的区别

  1. 查询语言。由于sql被广泛应用在数据仓库中,因此,专门针对hive的特性设计了类sql的查询语言hql。
  2. 数据存储位置。hive是建立在hadoop之上的,所有hive的数据都是存储在HDFS中的。而数据库则可以将数据保存在块设备或本地文件系统中。
  3. 数据格式。Hive中没有定义专门的数据格式,由用户指定,需要指定三个属性:列分隔符,行分隔符,以及读取文件数据的方法(hive中默认有三个文件格式textfile、sequencefile、rcfile)。数据库中,存储引擎定义了自己的数据格式。所有数据都会按照一定的组织存储。
  4. 数据更新。Hive的内容是读多写少的,因此,不支持对数据的改写和删除,数据都在加载的时候中确定好的。数据库中的数据通常是需要经常进行修改。
  5. 索引。hive在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中某些key建立索引。由于MapReduce的引入,hive可以并行访问数据,因此即使没有索引,对于大数据量的访问,hive仍然可以体现出优势。数据库中,通常会针对一个或者几个列建立索引,因此对于少量的特定条件的数据的访问,数据库可以有很高的效率。
  6. 执行延迟。Hive在查询数据的时候,需要扫描整个表(或分区),因此延迟较高,只有在处理大数据是才有优势。数据库在处理小数据是执行延迟较低。
  7. 执行。Hive是MapReduce,数据库是Executor
  8. 数据规模。Hive大,数据库小。

2.hive原理 

 

3.hive的数据管理

hive中所有的数据都存储在HDFS中,没有专门的数据存储格式。我们只需要在建表的时候告诉hive数据中的列分隔符和行分隔符,hive就可以解析数据。

3.1 hive中的内部表和外部表

内部表:未被external修饰的表。表数据由hive自身管理,表数据存储的位置是默认的hive.metastore.warehouse.dir,删除表会直接删除元数据以及存储数据、对表的修改会将修改直接同步给元数据的内部表。

create table student(sno int,sname string,sage int) row format delimited fields terminated by '\t';

外部表:被external修饰的表,表数据有hdfs管理、表数据的存储位置有自己指定、删除表仅仅删除元数据,hdfs上的文件并不会被删除。

create external table student_ext(sno int,sname string,sage int) row format delimited fields terminated by '\t' location '/stu';

生成环境中为什么建议使用外部表?

  • 外部表不会加载数据到hive的hdfs目录,减少数据传输,数据还能共享。
  • hive不会修改数据,所以不需要担心数据的损坏,删除表时只删除表结构,不会删除数据。 

3.2 hive中的分区表

为了避免select查询时出现的全表扫描问题,hive提出了分区表(partitioned by),通俗讲,就是给文件归类打上标识,标识不能为表中已有的字段。

分区表又分为静态分区和动态分区。

创建静态单分区表:
create table day_table (id int,content string) partitioned by (dt string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;
创建静态多分区表:
		create table day_hour_table (
		id int, 
		content string
		) 
			partitioned by (dt int,hour int)   -- 按照dt,hour分区
			ROW FORMAT DELIMITED 
			FIELDS TERMINATED BY '\t' ;
静态分区表加载数据必须指定分区:
		insert into day_table partition (dt = "9-26") values(1,"anb");
		insert into day_hour_table partition(dt=9,hour=1) values(1,"a2 bc");
		load data local inpath "/root/ceshi" into table day_table partition (dt="9-27");
		load data local inpath "/root/ceshi" into table day_table partition (dt=10,hour=10);
删除分区:
		ALTER TABLE day_table DROP PARTITION (dt="9-27");
		ALTER TABLE day_table DROP PARTITION (dt=10,hour=10);
查询表的分区:
		SHOW PARTITIONS table_name;

静态分区在插入的时候必须要知道有什么分区类型,而且每个分区写一个load data,太麻烦。动态分区可以根据查询到的数据动态分配到分区里。 

创建动态分区表之前的操作
开启支持动态分区
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;默认是strict,不允许分区列全部是动态的

静态分区与动态分区创建表的语句是一模一样的
		CREATE TABLE gfstbl_dynamic(
  		id INT,
 		 name STRING,
		  gfs ARRAY<STRING>,
		  address MAP<STRING,STRING>,
		  info STRUCT<country:String,province:String,shi:String>
		)
			partitioned by (sex string,age INT)
			ROW FORMAT DELIMITED 
			FIELDS TERMINATED BY ' ' 
			COLLECTION ITEMS TERMINATED BY ','
			MAP KEYS TERMINATED BY ':' 
			LINES TERMINATED BY '\n';
动态分区表加载数据:(不可以使用load,它只是将数据上传到HDFS指定目录中,而动态分区是自动分区的)
		from gfstbl_pt
		insert into gfstbl_dynamic partition(sex,age)
		select id,name,gfs,address,info,sex,age;
查看分区数:
		show partitions gfstbl_dynamic;

3.3 hive中的分桶表

为了提高join查询时的效率,减少笛卡尔积的数量,出现了分桶表。分桶表是对数据进行哈希取值,然后放到不同文件中存储。

之前要开启分桶表的支持:set hive.enforce.bucketing=true;
创建分桶表
		create table bucket_user (id int,name string)
		clustered by (id) into 4 buckets
		ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
插入数据:
		insert into table bucket_user  partition(id) select id, name from original;
抽样:
		select * from bucket_user tablesample(bucket x out of y on id);
		y必须是table总bucket数的倍数或者因子。
		x表示从哪个bucket开始抽取。
		分桶数/y 指的是抽取几个桶的数据。
		例如,table总bucket数为32,tablesample(bucket 3 out of 16),表示总共抽取(32/16=)2个bucket的数据,分别为第3个bucket和第(3+16=)19个bucket的数据。

分桶+分区表
		CREATE TABLE psnbucket_partition( id INT, name STRING, age INT) 
		PARTITIONED BY(height DOUBLE) 
		CLUSTERED BY (age) INTO 4 BUCKETS 
		ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

4.hive的调优

核心思想:把Hive SQL当作Map Reduce程序去优化
但是不是所有的SQL都会被转化为MapReduce来执行

  1. select仅查询本表字段。如select * from table;
  2. where只对本表字段做条件过滤

4.1 hive job的优化——表优化

对表进行分区处理。静态分区和动态分区,上面介绍过。

4.2 hive job的优化——并行化执行

hive执行过程中是按照默认的顺序来执行的,如果没有太大的依赖关系,最好并行执行,减少执行时间,每个查询被hive转化为多个阶段,有些阶段关联性不大,则可以并行执行,减少执行时间。

set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=16;默认8

4.3  hive job的优化——本地化执行

set hive.exec.mode.local.auto=true;

当一个job满足如下条件的时候,才能真正使用本地模式。

1.job的输入数据大小必须小于参数  hive.exec.mode.local.inputbytes.max 默认为128m

2.job的map数必须小于参数 hive.exec.mode.local.auto.tasks.max 默认4

3.job的reduce数量必须为0或1. 

4.4 hive job的优化——job合并输入\输出小文件

在集群中面临这样的问题,集群中很多的小文件,而且这些小文件的执行时间特别短,造成集群的资源没有好好利用。

解决

set hive.input.format=oar.apache.hadoop.hive.ql.io.CombineHiveInputFormat

这样做后,就会把多个split分片合并成一个。合并的文件数由mapred.max.split.size限制的大小决定。

4.6 

 

4.4 hive job的优化——jvm重用

  • 适用场景:
    1. 小文件个数过多
    2. task个数过多
  • 通过set mapred.job.reuse.jvm.num.tasks=n;来设置,n为task插槽个数

4.5 hive job的优化——压缩数据

中间压缩就是处理hive查询的多个job之间的数据。减少网络传输的数据量。

4.6 hive job的优化——数据倾斜

  • 操作

Join
           Group by
           Count Distinct

  • 原因

key分布不均导致的
          人为的建表疏忽
          业务数据特点

  • 症状

          任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。查看未完成的子任务,可以看到本地读写数据量积累非常大,通常超过10GB可以认定为发生数据倾斜。

  • 倾斜度

           平均记录数超过50w且最大记录数是超过平均记录数的4倍。
最长时长比平均时长超过4分钟,且最大时长超过平均时长的2倍。

  • 万能方法

          hive.groupby.skewindata=true

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值