文章目录
Hive简介
- Hive是构建在Hadoop之上的数据仓库平台。
- Hive是SQL解析引擎,它将SQL语句转译为MapReduce作业,并在Hadoop上运行。
- Hive表是HDFS的文件目录,一个表对应一个目录名,如果有分区的话,则分区值对应子目录。
对比
Mysql
随着数据量增加某些查询需要几个小时甚至几天才能完成。当 数据达到1T时,MySql进程跨掉
Oracle
可以支撑几个T的数据,但每天收集用户点击流数据(每天约 400G)时,Oracle开始撑不住。
Hadoop
有效解决了大规模数据的存储与统计分析的问题,但是 MapReduce程序对于普通分析人员的使用过于复杂和繁琐。
Hive
对外提供了类似于SQL语法的HQL语句数据接口,自动将HQL 语句编译转化为MR作业后在Hadoop上执行。降低了分析人员 使用Hadoop进行数据分析的难度
Hive体系结构
用户接口
CLI(命令行界面)
Cli 启动的时候,会同时启动一个 Hive 副本。
JDBC客户端
封装了Thrift,java应用程序,可以通过指定的主机和端口连接到在另一个进程中运行的hive服务器
ODBC客户端
ODBC驱动允许支持ODBC协议的应用程序连接到Hive。
Thrift服务器
基于socket通讯,支持跨语言。Hive Thrift服务简化了在多 编程语言中运行Hive的命令。绑定支持C++,Java,PHP,Python 和Ruby语言。
解析器
编译器
完成 HQL 语句从词法分析、语法分析、编译、优化以及执行计划的生成。
优化器
是一个演化组件,当前它的规则是:列修剪,谓词下压。
执行器
会顺序执行所有的Job。如果Task链不存在依赖关系,可以采 用并发执行的方式执行Job。
元数据库
Hive的数据由两部分组成:数据文件和元数据。元数据用于存放Hive库的基础信息,它存储在关系数据库中,如 mysql、derby。元数据包括: 数据库信息、表的名字,表的列和分区及其属性,表的属性,表的数据 所在目录等。
Hive运行机制
- 用户通过用户接口连接Hive,发布Hive SQL。
- Hive解析查询并制定查询计划。
- Hive将查询转换成MapReduce作业。
- Hive在Hadoop上执行MapReduce作业。
优点VS缺点
优点
- 解决了传统关系数据库在大数据处理上的瓶颈。适合大数据 的批量处理。
- 充分利用集群的CPU计算资源、存储资源,实现并行计算。
- Hive支持标准SQL语法,免去了编写MR程序的过程,减少 了开发成本。
- 具有良好的扩展性,拓展功能方便。
缺点
- Hive的HQL表达能力有限:有些复杂运算用HQL不易表达。
- Hive效率低:Hive自动生成MR作业,通常不够智能;
- HQL 调优困难,粒度较粗;可控性差。
适用场景
- 海量数据的存储处理
- 数据挖掘
- 海量数据的离线分析
不适用场景
- 复杂的机器学习算法
- 复杂的科学计算
- 联机交互式实时查询
针对Hive运行效率低下的问题,促使人们去寻找一种更快, 更具交互性的分析框架。 SparkSQL 的出现则有效的提高了 Sql在Hadoop 上的分析运行效率。
Hive连接
HiveServer2
HiveServer2 目前Hive的Thrift(接口描述语言和二进制通信协议)服务端通常使用HiveServer2,它是HiveServer改进版本,它提供了新的ThriftAPI来处理JDBC或者ODBC客户端,可以进行Kerberos身份验证,支持多个客户端并发。
Beeline
HiveServer2还提供了新的CLI:BeeLine,它是Hive 0.11引入的新的交互式CLI,基于SQLLine,可以作为Hive JDBC Client 端访问HievServer2。通过beeline连接hive:jdbc:hive2://192.168.88.104:10000/hiveTest
Cli
Hive VS 传统数据库
托管表和外部表
托管表 | 外部表 | |
---|---|---|
数据存储 | 仓库目录 | HDFS任何目录 |
数据删除 | 删除元数据和数据 | 只删除元数据 |
创建表语句 | CREATE EXTERNAL TABLE table_name(attr1 STRING) LOCATION ‘/usr/tom/tablea; |
分区和桶
一种将数据分片的方式,可以加快查询速度。表->分区->桶。
分区
- 分区列并非实际存储的列数据,分区只是表目录下嵌套的目录。
- 可以按照各种维度对表进行分区。
- 分区可以缩小查询范围。
- 分区是在创建表的时候用PARTITION BY子句定义的。
- 加载数据到分区使用LOAD语句,且要显示的指定分区值。
- 使用SHOW PARTITIONS语句查看Hive表下有哪些分区。
- 使用SELECT语句中指定分区,Hive只扫描指定分区数据。
Hive表分区分为两种,静态分区和动态分区。
静态分区和动态分区的区别在于导入数据时,是手动输入分区名称,还是通过数据来判断数据分区。对于大数据批量导入来说,显然采用动态分区更为简单方便。
动态分区需要配置:
hive.exec.dynamic.partition=true
hive.exec.dynamic.partition.mode=nostrict
动态分区只能通过insert overwrite table table_name select …这 样的语句导入数据。
静态分区可以通过多种方式导入数据:load/ITS/hdfs拷贝等。
静态分区导入不灵活,导入前要预先知道导入的分区。
桶
-
桶是表或分区上的进一步划分,可以提高查询效率。有利于做map-side-join。
-
使“取样”更方便高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
-
Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
create table bucketed_user(id int,name string) clustered by (id) into 4 buckets;
-
对桶中的数据可以做排序。使用SORTED BY子句。
create table bucketed_user(id int, name string) clustered by(id) sorted by (id asc) into 4 buckets;
-
不建议我们自己分桶,建议让Hive划分桶。
-
向分桶中填充数据前,需要设置hive.enforce.bucketing设置为true。
insert overwrite table bucket_users select * from users;
- 实际上桶对应于MapReduce的输出文件分区:一个作业产生的桶和reduce任务个数相同。
Hive储存格式
Hive从两个维度对表的存储进行管理:“行格式”(row format)和“文件格式”(file format)。
行格式
一行中数据的存储格式。按照hive的术语,行格式的定义由SerDe定义,即序列化和反序列 化。也就是查询数据时,SerDe将文件中字节形式的数据行反序列化为Hive内部操作数据行时使用的 对象形式。Hive向表中插入数据时,序列化工具会将Hive的数据行内部表示形式序列化为字节形式并 写到输出文件中去。
文件格式
最简单的文件格式是纯文本文件,但是也可以使用面向列的和面向行的二进制文件格式。 二进制文件可以是顺序文件、Avro、RCFile、ORC、parquet文件。
- 默认存储格式-分隔的文本。
- Hive内部默认使用LazySimpleSerDe处理分隔文本。
HiveQL简介
HiveQL视图
和其他数据库一样,hive从0.6版本之后也支持了视图功能。但是hive中的视图和关系数据库中的视图是 有区别的。
- 只有逻辑视图,没有物化视图。
- 视图只能查询,不能Load/Insert/Update/Delete数据;
- 视图在创建时候,只是保存了一份元数据,当查询视图的时候,才开始执行视图对应的那些子查询;
用户定义函数
Hive中有三种UDF。
- UDF(user-defined function) 操作作用于单个数据行,且产生了一个数据行作为输出。大多数函数(数学函数和字符串 函数)都属于这一类。
- UDAF(user-definde aggregate function) 用户定义聚集函数,接受多个输入数据行,并产生一个输出数据行。像COUNT和MAX这 样的函数都是聚集函数。
- UDTF(user-defined table-generating function) 用户定义表生成函数,表生成函数接受0个或多个输入,然后产生多行或多列输出。
order by、sort by、distribute by、 cluster by区别
order by:全局排序
order by会对输入做全局排序,因此只有一个Reducer(多个Reducer无法保证全局有序),然而只有一个Reducer,会导致当输入规模较大时,消耗较长的计算时间。关于order by的详细介绍请参考这篇文章:Hive Order by操作。
sort by:部分排序
sort by不是全局排序,其在数据进入reducer前完成排序,因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只会保证每个reducer的输出有序,并不保证全局有序。sort by不同于order by,它不受hive.mapred.mode属性的影响,sort by的数据只能保证在同一个reduce中的数据可以按指定字段排序。使用sort by你可以指定执行的reduce个数(通过set mapred.reduce.tasks=n来指定),对输出的数据再执行归并排序,即可得到全部结果。
distribute by:将map输出指定到某个reducer
distribute by是控制在map端如何拆分数据给reduce端的。hive会根据distribute by后面列,对应reduce的个数进行分发,默认是采用hash算法。sort by为每个reduce产生一个排序文件。在有些情况下,你需要控制某个特定行应该到哪个reducer,这通常是为了进行后续的聚集操作。distribute by刚好可以做这件事。因此,distribute by经常和sort by配合使用。
对于distribute by进行测试,一定要分配多reduce进行处理,否则无法看到distribute by的效果。
注:Distribute by和sort by的使用场景
-
Map输出的文件大小不均。
-
Reduce输出文件大小不均。
-
小文件过多。
-
文件超大。
cluster by:distribute by + sort by
cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是升序,不能指定排序规则为ASC或者DESC。