Hive简介
Hive最初是应Facebook每天产生的海量新兴社会网络数据进行管理和机器学习的需求而产生和发展的,是建立在 Hadoop上的一个分布式、按列存储的数据仓库基础构架。
Hive管理HDFS中存储的数据,并提供基于SQL的查询语言(由运行时引擎翻译成MapReduce作业)用以查询数据。
Hive 是一个基于 Hadoop 文件系统之上的数据仓库架构。它为数据仓库的管理提供了许多功能:数据 ETL (抽取、转换和加载)工具、数据存储管理和大型数据集的查询和分析能力。同时 Hive 还定义了类 SQL的语言 – Hive QL. Hive QL 允许用户进行和 SQL 相似的操作,它可以将结构化的数据文件映射为一张数据库表,并提供简单的 SQL 查询功能。还允许开发人员方便地使用 Mapper 和 Reducer 操作,可以将 SQL 语句转换为 MapReduce 任务运行,这对 MapReduce 框架来说是一个强有力的支持。
Hive设计目的就是用来管理和查询结构化数据,它屏蔽了底层将sql语句转换为MapReduce任务过程,为用户提供的简单的SQL语句,将用户从复杂的MapReduce编程中解脱出来。
官网 http://Hive.apache.org/ 官方手册 https://cwiki.apache.org/confluence/display/Hive/Home
Fackbook开发Hive的经历 Hive是Facebook开发的构建于Hadoop集群之上的数据仓库应用,它提供了类似于SQL语法的HQL语句作为数据访问接口,这使得普通分析人员的应用Hadoop的学习曲线变缓。至于Facebook为什么使用Hadoop和Hive组建其数据仓库,其内部人员分享了他们的一些经历,大致的过程是如下的:
1.Facebook的数据仓库一开始是构建于MySQL之上的,但是随着数据量的增加某些查询需要几个小时甚至几天的时间才能完成。 2.当数据量接近1T的时候,mysqld后台进程宕掉,这时他们决定将他们数据仓库转移到Oracle。当然这次转移的过程也是付出了很大的代价的,比如支持的SQL方言不同,修改以前的运行脚本等等。 3.Oracle应付几T的数据还是没有问题的,但是在开始收集用户点击流的数据(每天大约400G)之后,Oracle也开始撑不住了,由此又要考虑新的数据仓库方案。 4.内部开发人员花了几周的时间建立了一个并行日志处理系统Cheetah,这样的话勉强可以在24小时之内处理完一天的点击流数据。 5.Cheetah也存在许多缺点。后来发现了Hadoop项目,并开始试着将日志数据同时载入Cheetah和Hadoop做对比,Hadoop在处理大规模数据时更具优势,后来将所有的工作流都从Cheetah转移到了Hadoop,并基于Hadoop做了很多有价值的分析。 6.后来为了使组织中的多数人能够使用Hadoop,开发了Hive,Hive提供了类似于SQL的查询接口,非常方便。与此同时还开发了一些其它工具。 7.现在集群存储2.5PB的数据,并且以每天15TB的数据在增长,每天提交3000个以上的作业,大约处理55TB的数据…
现在很多大的互联网公司出于成本考虑都在研究、使用Hadoop;数据的价值正得到越来越多的人的重视,而这种重视,又体现出Hadoop存在的巨大价值。
Hive的特点
1.学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。 2.Hive适合进行相关的静态数据分析,不需要快速响应给出结果,而且数据本身不会频繁变化。 3.Hive不支持记录级别的更新、插入或者删除操作,但用户可以通过查询生成新表或者将查询结果导入到文件中。 4.Hadoop面向批处理,MapReduce任务的启动过程需要消耗较长的时间,所以Hive查询延时比较严重。需要提高查询效率需要使用presto等连接器。 5.Hive不支持事务,不支持OLTP(联机事务处理)所需的关键功能。 6.Hive最适合数据仓库应用程序,可以维护海量数据,而且可以对数据进行挖掘,然后形成意见和报告。 7.可以直接使用存储在Hadoop 文件系统中的数据。 8.不同的存储类型,例如,纯文本文件、HBase 中的文件。 9.内置大量用户函数UDF 来操作时间、字符串和其他的数据挖掘工具,支持用户扩展UDF 函数来完成内置函数无法实现的操作。
Hive与Hadoop的关系
我们之前已经对Hadoop进行了一些了解,参考文章如下:
Hadoop基础—-Hadoop理论(一)—-Hadoop简介
Hadoop基础—-Hadoop理论(二)—–Hadoop学习路线(持续更新)
Hive 是 Hadoop 中的一个重要子项目,属于Hadoop的一种组件,从下图我们就可以大致了解 Hive 在 Hadoop 中的位置和关系。
我们经常一提到Hadoop,就会听别人说到Hive, Pig, HBase, Sqoop, Mahout, Zookeeper等等。 其实这些项目都是Hadoop的一些相关项目。 它们有些是Hadoop的组件,有些是新的Hadoop框架(基于Hadoop原理的架构)。 尽管Hadoop因MapReduce及其分布式文件系统(HDFS,由NDFS改名而来)而出名,但Hadoop这个名字也用于一组相关项目的统称,这些相关项目都使用这个基础平台进行分布式计算和海量数据处理。
Hadoop为什么会需要Hive这样的组件呢?
大数据本质是数据,但是又有了新的特征,包括数据来源广、数据格式多样化(结构化数据、非结构化数据、Excel文件、文本文件等)、数据量大(最少也是TB级别的、甚至可能是PB级别)、数据增长速度快等。 针对以上主要的4个特征我们需要考虑以下问题: 数据来源广,该如何采集汇总?,对应出现了Sqoop,Cammel,Datax等工具。 数据采集之后,该如何存储?,对应出现了GFS,HDFS,TFS等分布式文件存储系统。 由于数据增长速度快,数据存储就必须可以水平扩展。 数据存储之后,该如何通过运算快速转化成一致的格式,该如何快速运算出自己想要的结果? 对应的MapReduce这样的分布式运算框架解决了这个问题;但是写MapReduce需要Java代码量很大,所以出现了Hive,Pig等将SQL转化成MapReduce的解析引擎。
Hive与关系型数据库的区别
Hive 在很多方面与传统关系数据库类似(例如支持 SQL 接口),但是其底层对 HDFS 和 MapReduce 的依赖意味着它的体系结构有别于传统关系数据库,而这些区别又影响着 Hive 所支持的特性,进而影响着 Hive 的使用。
我们可以列举一些简单区别:
1.Hive 和关系数据库存储文件的系统不同,Hive 使用的是 Hadoop 的HDFS(Hadoop的分布式文件系统),关系数据库则是服务器本地的文件系统;
2.Hive 使用的计算模型是 MapReduce,而关系数据库则是自己设计的计算模型;
3.关系数据库都是为实时查询的业务进行设计的,而 Hive 则是为海量数据做数据挖掘设计的,实时性很差;实时性的区别导致 Hive 的应用场景和关系数据库有很大的不同;
4.Hive 很容易扩展自己的存储能力和计算能力,这个是继承 Hadoop 的,而关系数据库在这个方面要差很多。
5.关系数据库里,表的加载模式是在数据加载时候强制确定的(表的加载模式是指数据库存储数据的文件格式),如果加载数据时候发现加载的数据不符合模式,关系数据库则会拒绝加载数据,这个就叫“写时模式”,写时模式会在数据加载时候对数据模式进行检查校验的操作。Hive在加载数据时候和关系数据库不同,Hive在加载数据时候不会对数据进行检查,也不会更改被加载的数据文件,而检查数据格式的操作是在查询操作时候执行,这种模式叫“读时模式”。在实际应用中,写时模式在加载数据时候会对列进行索引,对数据进行压缩,因此加载数据的速度很慢,但是当数据加载好了,我们去查询数据的时候,速度很快。但是当我们的数据是非结构化,存储模式也是未知时候,关系数据操作这种场景就麻烦多了,这时候Hive就会发挥它的优势。
6.关系数据库一个重要的特点是可以对某一行或某些行的数据进行更新、删除操作,Hive不支持对某个具体行的操作,Hive对数据的操作只支持覆盖原数据和追加数据。Hive也不支持事务和索引。更新、事务和索引都是关系数据库的特征,这些Hive都不支持,也不打算支持,原因是Hive的设计是海量数据进行处理,全数据的扫描时常态,针对某些具体数据进行操作的效率是很差的,对于更新操作,Hive是通过查询将原表的数据进行转化最后存储在新表里,这和传统数据库的更新操作有很大不同。
Hive应用场景
通过对 Hive 与传统关系数据库的比较之后,其实我们不难得出 Hive 可以应用于哪些场景。
Hive 构建在基于静态批处理的 Hadoop 之上,Hadoop 通常都有较高的延迟并且在作业提交和调度的时候需要大量的开销。因此,Hive 不适合在大规模数据集上实现低延迟快速的查询。
Hive 并不适合那些需要低延迟的应用,例如,联机事务处理(OLTP)。Hive 查询操作过程严格遵守 Hadoop MapReduce 的作业执行模型,Hive 将用户的 HiveQL 语句通过解释器转换为 MapReduce 作业提交到 Hadoop 集群上,Hadoop 监控作业执行过程,然后返回作业执行结果给用户。Hive 并非为联机事务处理而设计,Hive 并不提供实时的查询和基于行级的数据更新操作。
Hive 的最佳使用场合是大数据集的批处理作业,例如,网络日志分析。
所以 Hive一般作为大数据量的数据仓库来使用,如果需要提高单列的查询效率,需要配合其他连接器,比如presto。
Hive整体架构
Hive 本身的体系结构如下:
从图中我们可以看出Hadoop和mapreduce是Hive架构的根基。Hive基本组成可以分为:
用户接口,包括 CLI, JDBC/ODBC, WebUI
元数据存储,通常是存储在关系数据库如 MySQL, Derby 中
解释器、编译器、优化器、执行器包括Complier、Optimizer和Executor
Hadoop, 用 HDFS 进行存储,利用 MapReduce 进行计算
也可以分为两大类: 服务端组件和客户端组件。
服务端组件:
Driver组件:该组件包括Complier、Optimizer和Executor,它的作用是将我们写的HiveQL(类SQL)语句进行解析、编译优化,生成执行计划,然后调用底层的mapreduce计算框架。
Metastore组件:元数据服务组件,这个组件存储Hive的元数据,Hive的元数据存储在关系数据库里,Hive支持的关系数据库有derby、mysql。元数据对于Hive十分重要,因此Hive支持把metastore服务独立出来,安装到远程的服务器集群里,从而解耦Hive服务和metastore服务,保证Hive运行的健壮性,这个方面的知识,我会在后面的metastore小节里做详细的讲解。
Thrift服务:thrift是facebook开发的一个软件框架,它用来进行可扩展且跨语言的服务的开发,Hive集成了该服务,能让不同的编程语言调用Hive的接口。
客户端组件:
CLI:command line interface,命令行接口。
Thrift客户端:Hive架构的许多客户端接口是建立在thrift客户端之上,包括JDBC和ODBC接口。HiveServer2,thrift服务器,通过JDBC/ODBC可以提供命令行之外的编程接口,如使用java、python等。
WEBGUI:Hive客户端提供了一种通过网页的方式访问Hive所提供的服务。这个接口对应Hive的hwi组件(Hive web interface),使用前要启动hwi服务。
Hive的执行流程如下图所示:
Hive中包含的组件
HCatalog:其是Hive提供的Hadoop存储管理层(storage management layer )服务,支持用户使用不同的数据处理工具–包含Pig和MapReduce–来更加容易的读写数据。
WebHCat:通过HTTP接口(REST风格)的方式提供服务,支持的操作包括:运行MapReduce、Pig、Hive job或者Hive元数据操作等。
Hive数据存储
Hive 的存储是建立在 Hadoop 文件系统之上的。Hive 本身没有专门的数据存储格式,也不能为数据建立索引,因此用户可以非常自由地组织 Hive 中的表,只需要在创建表的时候告诉 Hive 数据中的列分隔符就可以解析数据了。
Hive 中主要包括 4 种数据模型:表(Table)、外部表(External Table)、分区(Partition)以及 桶(Bucket)。
Hive 的表和数据库中的表在概念上没有什么本质区别,在 Hive 中每个表都有一个对应的存储目录。而外部表指向已经在 HDFS 中存在的数据,也可以创建分区。Hive 中的每个分区都对应数据库中相应分区列的一个索引,但是其对分区的组织方式和传统关系数据库不同。桶在指定列进行 Hash 计算时,会根据哈希值切分数据,使每个桶对应一个文件。
这四种数据模型详细的使用我们将在之后的博客中学习。
Hive元数据存储
由于 Hive 的元数据可能要面临不断地更新、修改和读取操作,所以它显然不适合使用 Hadoop 文件系统进行存储。目前 Hive 把元数据存储在 RDBMS 中,比如存储在 MySQL, Derby 中。
这点我们在上面介绍的 Hive 的体系结构图中,也可以看出。
Hive的metastore组件是Hive元数据集中存放地。Metastore组件包括两个部分:metastore服务和后台数据的存储。
后台数据存储的介质就是关系数据库,例如Hive默认的嵌入式磁盘数据库derby,还有mysql数据库。
Metastore服务是建立在后台数据存储介质之上,并且可以和Hive服务进行交互的服务组件,默认情况下,metastore服务和Hive服务是安装在一起的,运行在同一个进程当中。我也可以把metastore服务从Hive服务里剥离出来,metastore独立安装在一个集群里,Hive远程调用metastore服务,这样我们可以把元数据这一层放到防火墙之后,客户端访问Hive服务,就可以连接到元数据这一层,从而提供了更好的管理性和安全保障。
使用远程的metastore服务,可以让metastore服务和Hive服务运行在不同的进程里,这样也保证了Hive的稳定性,提升了Hive服务的效率。
Hive查询语言
Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。
HiveQL是一个类SQL的查询语言。它模仿SQL语法来创建表,读表到数据,并查询表。 HiveQL也允许用户嵌入他们自定义的map-reduce脚本。这些脚本能用任何支持基于行的流式接口的语言写-从标准输入读入并写到标准输出。这种灵活性也有一定的代价:即字符串的转换带来的性能损失。
尽管如此,我们看到用户似乎不介意于此,他们自己实现这些脚本。
另一个特性是多表插入。在此构造下,用户可以在相同的数据上通过一条HiveQL执行多query。Hive优化这些query,从而能共享输入数据的扫描,这样就增加了这些query的几个数量级的吞吐量。
Hive为什么不直接使用SQL进行查询,而是要自己定义一个HiveQL 我们知道sql是有标准的规范的,例如sql92标准、sql99标准。但是各个数据库厂商在实现自己的数据库产品时,可能并没有遵循同一套规范,而且每个数据库厂商基本上都会扩展SQL语法,例如Oracle和Mysql的分页查询语法就是不一样的,并且即使某个数据库厂商实现了某个规范,可能也不会完全的实现sql规范,例如mysql官方文档就介绍过,由于考虑性能的问题,并没实现sql规范中的所有标准。 这意味,如果直接使用sql的问题是:oracle的用户要使用oracle数据库的语法,而mysql用户要使用mysql的语法,sqlserver用户要用sqlserver的语法。 因此,直接使用SQL是不合适的,与其去支持不同的数据库产品的语法,不如定义一个自己的语法,因为数据库厂商太多了, 每一个都去支持基本上是不可能的。
Hive如何实现类SQL查询 Hive支持将类sql的查询,实际上是因为其有一套映射工具,在数据仓库的构建过程中,可以把关系型数据库中表,字段转换为HDFS中的文件(夹)以及文件中的列,这套工具称之为metastore。在查询时, 可以将HiveQL转换为mapreduce中的job。
操作Hive时一般是shell语言与HQL结合使用,例如: Hive操作的一个简单的例子 首先我们创建一个普通的文本文件,里面只有一行数据,该行也只存储一个字符串,命令如下:
echo ‘zhangzequan’ > /home/Hadoop/test.txt
然后我们建一张Hive的表:
Hive –e “create table test (value string);
接下来加载数据:
Load data local inpath ‘home/Hadoop/test.txt’ overwrite into table test
最后我们查询下表:
Hive –e ‘select * from test’;
Hive十分简单,很好入门,操作和sql很像。
更多用法我们将在之后的博客里给出。
Hive学习路线
后续的文章我们会学习 Hive的数据模型使用方式 Hive的安装与配置 Hive常用命令 Hive使用案例