Hive内容总结
Posted 大数据的那些事
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive内容总结相关的知识,希望对你有一定的参考价值。
Hive是一个数据仓库工具,基于Hadoop,可以将类SQL(HQL)语句转化成MR Job在Hadoop平台上运行。Hive引入的背景是传统的Hadoop等大数据学习成本太高,学习和开发的周期长。而Hive可以将HQL语句转化成MR Job,这样对于很多了解过sql语句但是不懂Hadoop的人同样可以通过这种方式执行一些大数据任务,同样的任务,开发MR Job可能需要大量的代码,但是HQL语句可能只需要几行,达到快速开发的目的,也因此,Hive一经Facebook推出,立马得到了业界的广泛欢迎。Hive不能完全替代MR,Hive主要是用在一些统计任务上,基于一个统一的查询分析层,通过HQL语句对HDFS上的数据进行查询、统计和分析。
1、hive和关系数据库的区别
Hive执行语句从语法上看与关系型数据库差不多,但本质上有很大区别,如下表所示:
Hive |
关系数据库 |
|
执行语句 |
HQL |
SQL |
数据存储 |
HDFS、Hbase |
本地文件系统 |
数据更新 |
不支持(把之前的数据覆盖) |
支持 |
索引 |
有(0.8版本后增加的) |
有 |
延迟 |
高 |
低 |
数据量 |
大 |
小 |
可扩展性 |
高(UDF、UDF、UDF) |
低 |
数据检查 |
读时模式 |
写时模式 |
hive和关系数据库存储文件的系统不同,hive使用的是hadoop的HDFS(hadoop的分布式文件系统),关系数据库则是服务器本地的文件系统;hive使用的计算模型是mapreduce,而关系数据库则是自己设计的计算模型;关系数据库都是为实时查询的业务进行设计的,而hive则是为海量数据做数据挖掘设计的,实时性很差;Hive很容易扩展自己的存储能力和计算能力,这个是继承hadoop的,而关系数据库在这个方面要比数据库差很多;Hive不支持更新或删除某一行数据,hive只支持覆盖和追加,不支持事务和索引
2、Hive的特点:
1)Hive中的表是纯逻辑表,只是表的定义等,包含表的元数据而已。本质还是Hadoop的目录/文件,实现了元数据与数据存储的分离。
2)Hive本身不存储数据,它完全依赖HDFS和MapReduce。
3)Hive的内容是读多写少,不支持对数据的改写和删除。
4)简单的HQL语句并不会启动MapReduce任务。
5)hive默认表存放路径一般都是在你工作目录的hive目录里面,按表名做文件夹分开,如果有分区表的话,分区值是子文件夹,可以直接在其它的M/R job里直接应用这部分数据。
3、Hive的架构:
Hive的架构如下图所示,可以分为如下三部分去理解,
1)用户接口:
CLI:启动的时候,会同时启动一个 Hive 副本,Hive 的客户端,用户连接至 Hive Server
JDBC/ODBC:Hive提供JDBC驱动,作为JAVA的API,通过ThiftServer来接入,然后发送给Driver
GUI:通过浏览器访问 Hive
2)语句转换:
解析器:生成抽象语法树
语法分析器:验证查询语句
逻辑计划生成器(包括优化器):生成操作符树
查询计划生成器:转换为map-reduce任务
3)数据存储:
Hive数据以文件形式存储在HDFS的指定目录下。
Hive语句生成查询计划,由MapReduce调用执行。
元数据:存储在一个独立的关系型数据库,通常时mysql,Hive会在其中保存表模式和其他系统元数据。
4、H i v e 内 部 表 和 外 部 表
Hive表 |
创建 |
删除 |
删后是否可恢复 |
内部表 |
create table |
元数据和数据全被删 |
否 |
外部表 |
create external table |
删元数据,数据会保留 |
是(重建表,自动有数据) |
5、Partition和Buckets
Hive中的一个表对应hdfs中的一个目录,表中的一个 Partition 对应于该目录下的一个子目录,所有的 Partition 的数据都存储在对应的子目录中。Partition的目的是辅助查询,缩小查询范围,加快数据的检索速度和对数据按照一定的规格进行管理。table和partition可以通过‘CLUSTERED BY’进一步分bucket,bucket中的数据可以通过‘SORT BY’排序。
Buckets是对某一列做hash来切分数据的,得到的每个Bucket对应一个文件,这么看来和Partition有什么区别呢?
假设有一张日志表,现在需要按照日期和用户id来分区,目的是为了加快查询谁哪天干了什么,如下:
create table wzp(a String, b String) partitioned by (date String, user_id int);
但是用user_id去做分区的话会产生很多的分区,为了避免产生这么多的小分区,但同时要想加快查询的速度,这时就可以用bucket了。
create table wzp (user_id int, a String, b String) partitioned by (date String) CLUSTERED BY(user_id) into 64 Buckets;
首先按日期分区,然后再按user_id把日志放在64个Buckets中。这样,一个用户的所有日志都会在同一个Buckets,一个Buckets中也会有很多用户的日志。要注意的是在插入数据之前一定要设置hive.enforce.bucketing为true。
以上是关于Hive内容总结的主要内容,如果未能解决你的问题,请参考以下文章