Hive学习笔记
Hive学习笔记
1 Hive是什么
Hive基于Hadoop的一个数据仓库工具,可以将结构化数据映射为一张表,一个统一的查询分析层,通过类似SQL查询语句的方式对HDFS上的数据进行查询、统计和分析。
Hive采用的是类似SQL的查询语言,叫HQL(HiveQuery Language)
2 Hive特点
(1) Hive是一个SQL解析引擎,将SQL语句转译成MR Job,然后在Hadoop平台上运行,达到快速开发的目的。
(2) Hive本质是将HQL转化成Mapreduce程序
(3) Hive中的表是纯逻辑表,只有表的定义等,即表的元数据。本质就是Hadoop的目录/文件,达到了元数据与数据存储分离的目的.
(4) Hive本身不存储数据,它完全依赖HDFS和MapReduce。
(5) Hive的内容是读多写少,不支持对数据的改写和删除。
(6) Hive中没有定义专门的数据格式,由用户指定,需要指定三个属性:
- 行分隔符:空格、\t、\001
- 列分隔符:\n
- 文件格式:TextFile、SequenceFile、RCFile
TextFile:
Hive默认格式,优点:可读性强;缺点:数据不压缩,占空间,磁盘消耗大
数据解析开销大。可结合Gzip、Bzip2、Snappy等使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。
SequenceFile:
SequenceFile是HadoopAPI 提供的一种二进制文件,它将数据以<key,value>的形式序列化到文件中。这种二进制文件内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化。它与Hadoop API中的MapFile 是互相兼容的。Hive 中的SequenceFile 继承自HadoopAPI 的SequenceFile,不过它的key为空,使用value 存放实际的值,这样是为了避免MR 在运行map 阶段的排序过程。
RCFile:
RCFile是Hive推出的一种专门面向列的数据格式。 它遵循“先按列划分,再垂直划分”的设计理念。当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。需要说明的是,RCFile在map阶段从 远端拷贝仍然是拷贝整个数据块,并且拷贝到本地目录后RCFile并不是真正直接跳过不需要的列,并跳到需要读取的列, 而是通过扫描每一个row group的头部定义来实现的,但是在整个HDFS Block 级别的头部并没有定义每个列从哪个row group起始到哪个row group结束。所以在读取所有列的情况下,RCFile的性能反而没有SequenceFile高。
其中textfile为默认格式,建表时不指定默认为这个格式,导入数据时会直接把数据文件拷贝到hdfs上不进行处理。SequenceFile,RCFile格式的表不能直接从本地文件导入数据,数据要先导入到textfile格式的表中,然后再从textfile表中用insert导入到SequenceFile,RCFile表中。
(7) Hive处理的数据存储在HDFS
(8) Hive分析数据底层的实现是Mapreduce
(9) 执行程序运行在YARN上
(10)Hive优点
- 支持用户自定义函数,用户可以根据自己的需求来实现自己的函数
- Hive的优势在于处理大数据,对于小数据没有优势,因为Hive执行延迟比较高
- Hive执行延迟比较高,常用于数据分析,实时性要求不高的场合
- 避免了去写Mapreduce,减少开发人员学习成本
- 操作接口采用类SQL写法,提供快速开发能力
(11)Hive缺点
- Hive的HQL表达能力有限,迭代算法无法表达,数据挖掘方面不擅长
- Hive效率比较低,调优比较困难,粒度较粗
3 Hive sql与传统sql对比
(1) HQL是查询语言,SQL不止查询,还可以增删改。
(2) 数据存储:HQL是存储在HDFS/Hbase,SQL是存储在块设备或Local FS (本地文件系统)。
(3) 数据更新:Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。Hive中不支持对数据的改写和添加,所有的数据都是在加载的时候确定好的,而数据库中的数据通常是需要修改的。
(4) 索引:Hive在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,没有对数据中的某些key建立索引,由于mapreduce引入,hive可以并行访问数据,因此即使没有索引,对于大数据量的访问,hive仍然可以体现出优势。数据库中,通常会针对一个或者几个列建立索引。但新版Hive已经有索引。
(5) 执行: Hive查询执行是Mapreduce来实现的,数据库通常有自己的执行引擎。
(6) 执行延迟:MapReduce启动慢,执行也慢,所以它的延迟是非常高的。
(7) 可扩展性中UDF、UDAF、UDTF都是函数,可以自定义;
- UDF:直接应用于select语句,通常查询的时候,需要对字段做一些格式化处理;特点:一进一出,1比1 ,用户自定义普通函数
- UDAF:对比一的场景,用户自定义聚合函数
- UDTF:一对多,用户自定义表生成函数
出现聚合情况:sql语句中出现Group by
(8) 由于Hive建立在集群上并利用Mapreduce进行并行计算,因此可以支持很大的规模;数据库支持的规模就比较小了。
(9) 数据检查(重点)
读时模式:只有hive读的时候才会检查、解析字段和schema(数据结构表达)
优点:load data(加载数据)非常迅速,因为在写的过程中是不需要解析数据,仅仅进行了文件的复制或者移动
写时模式:缺点:写的慢,需要建立一些索引、压缩、数据一致性、字段检查等,
优点:提升查询性能,因为加载的时候,已经做了预先的解析,读的时候会得到优化
(10)Hive的优势在于大数据的分析,数据库在于小数据的增删改查。
4 Hive体系架构
可将Hive体系架构分为三层,从上至下依次为:用户接口、语句转换、数据存储
(1) 用户接口:与客户的交互方式,Clinet终端
shell工具,进行交互式执行SQL:直接与Driver进行交互。
JDBC驱动,作为JAVA的API:JDBC是通过Thift Server来接入,然后发送给Drive。
Web GUI :通过web页面的方式做一些sql的提交查询。
(2) 语句转换:sql--->mapreduce
驱动模块Driver:通过该模块对输入的sql语句进行解析编译,对需求的计算进行优化,然后按照指定的步骤进行(通常启动多个MR任务来执行)。
Hive自身不会生成mr,而是通过一个执行计划来去执行mr(xml文件-->mapper、reduce模块)。
(3) 元数据存储:metastore就相当于一个独立的关系型数据库,保存表模和其他系统元数据,式默认是存储在自带本地数据库derby(单用户模式常用),可以存储到mysql(多用户模式、远程服务模式)。
(4) 下面就是Hadoop平台,Hive数据以文件形式存储在HDFS的指定目录下。
5 Hive数据管理
(1) Hive的表本质就是Hadoop的目录/文件
Hive默认表存放路径一般都是在工作目录的hive目录里面,按表名做文件夹分开,如果有分区表的话,分区值是子文件夹,可以直接在其它的MR job里直接应用这部分数据。
(2) Hive表类型:Table(内部表)、ExternalTable(外部表)、Partition(分区表)、Bucket(分桶表),内部表和外部表合称为普通数据表。
(3) Table在hive里面都会有相对应的目录来存储数据,这个目录就是在hdfs上的,路径格式一般都是数据仓库名字加表名,另外数据仓库名字默认是warehouse,可通过配置文件修改。table不是文件,是目录。
(4) 表的创建过程和加载过程,是两个独立的过程,但也可以同一个语句中完成,实践的数据会移动到数据仓库的目录中
6 内部表vs外部表
(1) Hive的create创建表的时候,选择的创建方式:
创建内部表:create table xxx;
创建外部表:create externaltable xxx;
查询表的类型:desc formattedxxx;
(2) 特点
在导入数据到外部表,数据并没有移动到自己的数据仓库目录下,也就是说外部表中的数据并不是由它自己来管理的!而内部表则不一样;
在删除表的时候,Hive将会把属于表的元数据和数据全部删掉;而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的!
(3) 建议:创建表的时候尽量用外部表
(4) 表恢复:把表重新创建,数据就会自动恢复
7 Partition
(1) Partition是什么:是table下的分区表,就是把数据按照不同属性分成一个个区,类似reduce的概念。
(2) Partition的作用:对table表做优化,辅助查询,缩小查询范围,加快数据的检索速度和对数据按照一定的规格和条件进行管理。
(3) 创建分区表:PARTITIONED BY
(4) 在Hive中,表中的一个Partition对应于表下的一个目录,所有的partition的数据都存储在对应的目录中,是在table下层。
例如:pvs 表中包含 ds 和 city 两个 Partition,则
对应于 ds = 20090801, ctry = US 的 HDFS 子目录为:/wh/pvs/ds=20090801/ctry=US;
对应于 ds = 20090801, ctry = CA 的 HDFS 子目录为;/wh/pvs/ds=20090801/ctry=CA
(5) 先提前指定好哪个字段做分区,它会按照字段里面的内容,每个内容起一个文件夹名字,分出不同的目录桶,并且你要做分区的时候不仅仅是可以对一个字段做分区,也可以对多个字段做分区,一个分区表它对应一个目录。
(6) 不是说所有的字段都可以拿来做分区的,有的字段拿来做分区的话会大大帮你优化整个的查询效率,如果有的字段你拿来当分区的话,反而额外增加了一些集群的压力。
(7) 分区的字段只适合那些取值范围是有限集合的字段。
(8) 举例:工作中常要日志查询,日志字段查询如下,
每天日志记录是按时间分割开的,如下,
现要查询2日中user,item,click内容,语句如下,
select user,item,click from table where date=2日
查询过程:没做partition前,它是先对全部数据进行遍历的,然后把满足条件的where判断做一个过滤器,把2日数据过滤出来,可对每一天数据做一个partition,做了partition后,它会按partition查询,它就直接去2日这里查找,减少数据遍历范围,提升了查询速度。
工作中,应该在数据入库前,对数据做partition,优化数据查询。
(9) 优化:工作中常用的分区字段:时间、地域、流量、手机类型
(10)优化:table--->Partition---->Bucket、table--->Bucket
(11)分区表实际上就是对应一个HDFS文件系统上的独立文件夹,该文件夹下是该分区所有的数据文件。Hive中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过where句子中的表达式选择查询所需要的指定分区,这样的查询效率会提高很多。
(12)分区表下面还可以继续分区,叫二级分区,是一级分区下面的目录,以此类推。
8 Hive中的Bucket
(1) Bucket是什么:bucket也类似是分区表,是hive会针对某一个列进行桶的组织,通常对列值做哈希(hash),类似把一张表拆分成多个表(分库),Partition类似reduce,kucket就类似是reduce输出part0000x。
(2) hive中table可以拆分成partition,table和partition可以通过‘CLUSTEREDBY’进一步分bucket,bucket中的数据可以通过‘SORT BY’ 排序。
• create table bucket_user (idint,name string)clustered by (id) into 4 buckets;
• 'set hive.enforce.bucketing = true'开启bucket
(3) 可以自动控制上一轮reduce的数量从而适配bucket的个数,当然,用户也可以自主设置mapred.reduce.tasks去适配bucket个数
(4) Bucket主要作用:
- 数据sampling(采集、取样)
- 提升某些查询操作效率 mapjoin
(5) 数据分库:表之间做join,自动激活map-side join,提升某些查询操作效率
(6) 数据采集(sampling):
– hive> select * from studenttablesample(bucket 1 out of 2 on id);
– tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUTOF y)
– y必须是table总bucket数的倍数或者因子。 hive根据y的大小,决定抽样的比例。例如,table总共分了64份,当y=32时,抽取(64/32=)2个bucket的数据,当y=128时,抽取(64/128=)1/2个bucket的数据。 x表示从哪个bucket开始抽取。例如,table总bucket数为32,tablesample(bucket 3 outof 16),表示总共抽取(32/16=)2个bucket的数据,分别为第3个bucket和第(3+16=)19个bucket的数据。
9 Hive数据类型
(1) 原生类型/基础类型:(标红的重点)
对应Hive的String类型相当于数据库的varchar类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它可以存储2GB字符数。
(2) 复合类型
Arrays:ARRAY<data_type>
Maps:MAP<primitive_type,data_type>
Structs:STRUCT<col_name:data_type[COMM col_comment],……>
Union:uniontype<data_type,data_type,……>