Hive是基于静态批处理Hadoop的一个数据仓库工具,通过Hive可以实现将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,同时将sql语句转换为MapReduce任务进行运行,所以其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计。Hive具有sql数据库的外表,但应用场景完全不同,Hive 适合高延迟的查询,Hive并不提供实时的查询和基于行级的数据更新操作,所以Hive 的最佳使用场合是大数据集的批处理作业,例如,网络日志分析
Hive特性
·灵活方便的ETL(extract/transform/load)。
·支持Iez,Spark等多种计算引擎。
·可直接访问HDFS文件以及Hbase。
·易用易编程。
HiveServer Hive对外提供SQL服务的主要进程。
metaStore Hive提供元数据信息的进程,可供HiveServer,SparkSQL,Oozie等组件调用。
Beeline hive 命令行客户端。
JDBC java统一数据库接口。
Thrift一种序列化、通信协议。
ODBC基于C/C++的数据库标准接口。
metaStore:存储表、列和Partition等元数据。
Driver:管理HiveQL执行的生命周期,并贯穿Hive任务整个执行期间。
Compiler :编译HiveOL并将其转化为一系列相互依赖的Map/Reduce任务。
Optimizer:优化器,分为逻辑优化器和物理优化器,分别对HiveQL生成的执行计划和MapReduce任务进行优化。
Executor:按照任务的依赖关系分别执行Map/Reduce任务。
ThriftServer:提供thrift接口,作为JDBC和ODBC的服务端,并将Hive和其他应用程序集成起来。Clients:包含命令行接口Beeline和JDBC/ODBC接口,为用户访问提供接口。
Hive的语句最终在Tez、MapReduce、Spark上执行
Hive数据存储类型
数据库:创建表时如果不指定数据库,则默认为default数据库。
表:物理概念,实际对应HDFS上的一个文件目录。
分区:对应所在表所在目录下的一个子目录。
桶:对应表或分区所在路径的一个文件。
倾斜数据:数据集中于个别字段值的场景,比如按照城市分区时,80%的数据都来自某个大城市。
正常数据:不存在倾斜的数据。
分区: 数据表可以按照某个字段的值划分分区。
每个分区是一个目录。
分区数量不固定。
分区下可再有分区或者桶。
桶: 数据可以根据桶的方式将不同数据放入不同的桶中。
每个桶是一个文件。
建表时指定桶个数,桶内可排序。
数据按照某个字段的值Hash后放入某个桶中。
对于每一个表或者是分区,Hive都可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive是针对某一列进行分桶,Hlve采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶中,分桶的好处是可以获得更高的查询处理效率,使取样更高效
分桶的应用场景:1)数据抽样2)提升某些查询操作效率,
当表格数据量较大时,可对表格进行分区处理(Partition),便于局部数据的查询操作,如按时间分区、按地城分区等,将具有相同性质的数据存储到同一磁盘块上,从而加快查询效率。
创建分桶表时,指定桶的个数和分桶的依据字段,Hive就可以自动将数据分桶存储。查询时只需要遍历一个桶里的数据,或者遍历部分桶,这样就提高了查询效率。
分桶的实质是将数据分成不同的文件,Hive中的分桶和Hadoop中的Reduce个数相同。
分桶表的作用: 1.提高查询效率 2.提高采样效率 3.提高join的效率
分桶原理:是把hive单个数据文件,拆分成均匀大小的数据
1.指定分桶:开启分桶功能
在hive连接中:
set mapreduce.job.reduces=4; # 设置reduce数量是分桶的数量个数set hive.enforce.bucketing=true; #设置自动分桶的开关
创建分桶表(分桶表创建的时候,分桶字段必须是表中的字段)
往创建的分桶表插入数据(插入数据需要是已分桶,且排序的)
#创建临时表为导入分桶表数据准备:create table students1( id string, name string, score1 float, score2 float, score3 float, score float)row format delimited fields terminated by ',';#把原始数据插入到分桶表中,并自动进行分桶insert overwrite table stu_buck select * from students1;
加载数据
load data local inpath '/home/ksheep/data/students.csv' into table stu_buck;
查看数据
select * from students1 cluster by (sno)
导入分桶表数据:不能使用load data方式,没有分桶效果
insert overwrite table stu_buck;select * from students1 cluster by(sno);
外部分桶表
create EXTERNAL table students_external_bucket ( id string, name string, java float, c float, mysql float, hadoop float, sex string) clustered by ( id ) sorted by ( id asc ) into 4 bucketsrow format delimited fields terminated by ','LOCATION '/user/zx/bucket';insert into students_external_bucket select * from students1;
分区分桶表
create table students_p_b ( id string, name string, java float, c float, mysql float, hadoop float) PARTITIonED BY (sex string)clustered by ( id ) sorted by ( id asc ) into 4 bucketsrow format delimited fields terminated by ','
分桶抽样查询对于非常大的数据集,有时用户需要使用的是一个具有代表性的查询结果而不是全部结果。Hive可以通过对表进行抽样来满足这个需求。
select * from 分桶表 tablesample(bucket x out of y on 表中某个字段);
注:tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y) 。
y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例。例如,table总共分了4份,当y=2时,抽取(4/2=)2个bucket的数据,当y=8时,抽取(4/8=)1/2个bucket的数据。
x表示从哪个bucket开始抽取,如果需要取多个分区,以后的分区号为当前分区号加上y。例如,table总bucket数为4,tablesample(bucket 1 out of 2),表示总共抽取(4/2=)2个bucket的数据,抽取第1(x)个和第3(x+y)个bucket的数据。
注意:x的值必须小于等于y的值,否则报错
FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck
可以使用distribute by(sno) sort by(sno asc)或是排序和分桶的字段相同的时候使用Cluster by(字段)
注意使用cluster by就等同于分桶+排序(sort)
Hive可以创建托管表和外部表:
创建Hive表,Hive会将数据移动到数据仓库目录。如果所有处理都由Hive完成,建议使用托管表。
如果要用Hive和其它工具来处理同一个数据集,建议使用外部表。