第1章 Hive基础知识

主要内容

l Hadoop概述

l Hive概述

 

从早期的互联网主流大爆发开始,主要的搜索引擎公司和电子商务公司就一直在和不断增长的数据进行较量。最近,社交网站也遇到了同样的问题。如今,许多组织已经意识到他们所收集的数据是让他们了解他们的用户,提高业务在市场上的表现以及提高基础架构效率的一个宝贵的资源。

Hadoop生态系统就是为处理如此大数据集而产生的一个合乎成本效益的解决方案。Hadoop实现了一个特别的计算模型,也就是MapReduce,其可以将计算任务分割成多个处理单元,然后分散到一群家用的或服务器级别的硬件机器上,从而降低成本并提供成本可伸缩性。这个计算模型的下面是一个被称为Hadoop分布式文件系统(HDFS)的分布式文件系统。这个文件系统是“可插拔的”,而且现在已经出现了几个商用的和开源的替代方案。

不过,仍然存在一个挑战,那就是用户如何从一个现有的数据基础架构转移到Hadoop上,而这个基础架构是基于传统关系型数据库和结构化查询语句(SQL)。对于大量的SQL用户(包括专业数据库设计师和管理员,也包括那些使用SQL从数据仓库中抽取信息的临时用户)来说,这个问题又将乳鸽解决呢?

这就是Hive出现的原因。Hive提供了一个被称为Hive查询语言(简称HiveQL或HQL)的SQL方言,来查询存储在Hadoop集群中的数据。

SQL知识分布广泛的一个原因是:它是一个可以有效地、合理地且直观地组织和使用数据的模型。即使对于经验丰富的Java开发工程师来说,将这些常见的数据运算对应到底层的MapReduce Java API也是令人畏缩的。Hive可以帮助用户来做这些苦活,这样用户就可以集中精力关注于查询本身了。Hive可以将大多数的查询转换为MapReduce任务(job),进而在介绍一个令人熟悉的SQL抽象的同时,拓宽Hadoop的可扩展性。

Hive最适合于数据仓库应用程序,使用该应用程序进行相关的静态数据分析,不需要快速响应给出结果,而且数据本身不会频繁变化。

Hive不是一个完整的数据库。Hadoop以及HDFS的设计本身约束和局限性地限制了Hive所能胜任的工作。其中最大的限制就是Hive不支持记录级别的更新、插入或者删除操作。但是用户可以通过查询生成新表或者将查询结果导入到文件中。同时,因为Hadoop是一个面向批处理的系统,而MapReduce任务(job)的启动过程需要消耗较长的时间,所以Hive查询延时比较严重。传统数据库中在秒级别可以完成的查询,在Hive中,即使数据集相对较小,往往也需要执行更长的时间。

如果用户需要对大规模数据使用OLTP功能的话,那么应该选择使用一个NoSQL数据库,例如,

和Hadoop结合使用的HBase及Cassandra。如果用户使用的是Amazon弹性MapReduce计算系统(EMR)或者弹性计算云服务(EC2)的话,也可以使用DynamoDB。用户甚至可以和这些数据库(还包括其他一些数据库)结合来使用Hive,这个我们会在后面章节进行介绍。

因此,Hive是最适合数据仓库应用程序的,其可以维护海量数据,而且可以对数据进行挖掘,然后形成意见和报告等。

因为大多数的数据仓库应用程序是使用基于SQL的关系型数据库实现的,所以Hive降低了将这些应用程序移植到Hadoop上的障碍。用户如果懂得SQL,那么学习使用Hive将会很容易。如果没有Hive,那么这些用户就需要去重新学习新的语言和新的工具后才能进行生产。

同样的,相对于其他Hadoop语言和工具来说,Hive也使得开发者将基于SQL的应用程序移植到Hadoop变得更加容易。

不过,和大多数SQL方言一样,HiveQL并不符合ANSI SQL标准,其和Oracle,MySQL,SQL Server支持的常规SQL方言在很多方面存在差异(不过,HiveQL和MySQL提供的SQL方言最接近)。

因此,本书共有两个目的。其一,本书提供了一个针对所有用户的介绍。这个介绍会比较综合,并且会使用例子来进行讲解。使用的用户包括开发者、数据库管理员和架构师,以及其他(如商业分析师等)非技术类用户。其二,本书针对开发者和Hadoop管理员等需要深入了解Hive技术细节的用户提供了更详尽的讲述,以帮助这些用户学习如何优化Hive查询性能,如何通过用户自定义函数和自定义数据格式等,来个性化使用Hive。

因为Hive缺少好的文档,所以我们经历了不少的挫折才完成了这本书。特别是对于那些非开发者以及不习惯通过查看项目BUG记录和功能数据库、源代码等途径来获取其所需信息的用户,Hive并没有提供好的文档。Hive Wiki提供的信息价值很大,但是其中的解释有时太少了,而且常常没有进行及时的更新。我希望本书可以弥补这些不足,可以提供一个对于Hive的所有基本功能以及如何高效使用这些功能的综合性的指南[6]。

 

1.1 Hadoop概述

 

1.1.1 Hadoop体系架构

Hadoop是一个使用Java编写的Apache开放源代码框架,其核心是HDFS和MapReduce、Yarn三个组件,Hadoop允许使用简单的编程模型跨大型计算机的大型数据集进行分布式处理数据,其旨在从单一服务器扩展到数千台机器(可以从单一服务器提交任务,并在多台机器上分布式执行程序),每台机器都提供本地计算和存储的功能。根据上面的简单概述,总结了Hadoop的几个特点,

(1)Hadoop主要是在多节点的集群环境下使用,用户可采用简单的计算模型在计算机集群下对大规模的数据进行分布式处理。

(2)Hadoop是以数据存储为基础,以数据处理为主要目的,且其数据操作技术多样化。

(3)Hadoop最大限度兼容结构化数据格式。

(4)Hadoop集群本身可以获取每台服务器的状态,其框架可以检测并处理硬件失效问题,而不是依赖于硬件自身来维持高可用性。

(5)在Hadoop框架集群中,硬件失效被认为是一种常态,集群的高可用性服务是建立在整个集群之上的。

Hadoop是一个生态圈体系,包含很多组件,并且需要很多组件共同运作才可以正常工作,下面是对于Hadoop的整体架构的理解,如图1-1所示。

 

第1章 Hive基础知识

 

 

图1-1 Hadoop整体框架

图1-1中提到的组件都有自己的功能,具体介绍如下,

(1)分布式文件系统(Hadoop Distributed File System,HDFS):主要用于Hadoop生态圈的数据存储。

(2)并行计算模型(Map/Reduce):主要用于Hadoop job的计算应用。

(3)列式数据库(Hbase):主要用于对于实时数据的列式存储。

(4)数据仓库(Hive):主要用于数据分析,例如使用类SQL语句对于固定形式的数据进行数据提取以及数据过滤 。

(5)数据分析语言(Pig):类似于Hive,也是一个数据分析的语言,主要用于数据分析,但是市场上使用的占比较小。

(6)数据格式转化工具(Sqoop):主要用于在Hive与传统的数据库(如MYSQL)间进行数据传递。

(7)协同工作系统(Zookeeper):开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。

(8)数据序列化系统(AvroSerialization):是一个基于二进制数据传输高性能的中间件。在Hadoop的其他项目中例如HBase和Hive的客户端与服务端的数据传输也采用了这个工具。

 

1.1.2 HDFS架构

Hadoop的一个比较核心的组件是HDFS,HDFS是NameNode/DataNode主从架构,它公开文件系统的命名空间并允许用户在文件系统中存储数据。一个HDFS只有一个NameNode(这里的一个是只起作用的只有一个,在NameNode的HA状态下,也是只有一个NameNode起作用,其他的NameNode节点只是备份)。这个NameNode管理整个文件系统的命名空间。DataNode用来存储数据,还有一些DataNode用来管理连接到运行节点的存储。关于HDFS的架构如图1-2所示,

第1章 Hive基础知识

 

 

图1-2 HDFS架构

根据上面的架构图,可以总结出关于HDFS的几个特点,如下所示,

(1)HDFS 基于商用硬件环境,具有高容错性,被部署在廉价的硬件之上,同时向应用程序提供高的数据吞吐访问,适用于需要处理大规模海量数据集的应用。

(2)HDFS中只含有一个NameNode主服务节点,该节点管理文件系统中的命名空间和调度客户端对文件的访问,NameNode执行文件系统中命名空间的操作(打开、关闭、重命名文件和目录),NameNode需要执行数据块到DataNode映射的决策(数据存放在哪个DataNode下,需要在NameNode下作出相应的位置存储)。

(3)通常一个机器就是一个DataNode数据节点,DataNode管理本节点上数据的存储,同时负责响应来自客户端的文件读写要求,也负责执行来自NameNode的关于数据块创建、删除和冗余存储的指令。

(4)在HDFS内部,一个文件被分割为一个或多个数据块(block),并且这些数据块被存储在一批DataNode中。

(5)HDFS遵循部分POSIX协议要求,可以确保应用程序以流的方式访问系统数据。

其实HDFS目前也有一些不能够达到的要求,以下几点也是HDFS对于现实应用环境的假设及其目标,

(1)硬件失效:硬件失效是常态而不是特例。一个HDFS集群可能包含了成百上千的服务器(HDFS集群由很多DataNode组成,而一个DataNode部署在一个服务器上面,因此一个大的HDFS集群可能由成千上万个服务器组成),每个都会存储文件系统的部分数据。而大量的组件就会导致组件出错的概率非常高,而这也意味着HDFS的部分组件会经常不工作。因此,检查缺陷和快速自动地恢复就成了HDFS的核心架构目标。

(2)流式数据访问:运行在HDFS上的应用程序需要流式访问数据集的能力。HDFS被设计用来应对批量计算的场景,而不是用来和用户交互。重点是数据访问的高吞吐而不是低延迟。POSIX引入了大量的硬性需求来约束应用程序,而这些需求不是HDFS的目标需求。

(3)海量数据集:运行在HDFS上的应用程序拥有大规模的数据集。一个HDFS文件可能是GB级别或是TB级别的存储,因此HDFS被调优为存储大文件。它应该提供高聚合的数据宽带并且可以在单个集群内扩展到其他成百上千的节点。程序应该支持在单实例中存在千万级别的文件。

(4)追加写入及文件同步:HDFS程序需要一个一次写入多次读出的文件访问模型。一旦一个文件被创建、写入数据然后关闭,这个文件应该不再需要被改动。此假设简化了数据一致性的问题,并且支持了数据的高吞吐。一个Map/Reduce程序或者一个网络爬虫程序就非常符合这种模型。未来有计划支持对于文件的追加写入。

(5)“移动计算比移动数据的代价小”:一个程序如果在运行计算任务时能够更贴近其依赖的数据,那么计算会更高效。尤其是在数据集规模很大时该效应更加明显。因为这会最小化网络消耗而增加系统整体的吞吐能力。计算靠近数据要比数据靠近计算成本更低,HDFS提供给应用程序接口来做到移动程序使其离数据更近。

(6)跨异构硬件和软件平台的可移植性:HDFS被设计为可以很容易的从一个平台移植到另一个平台。这有利于推广HDFS,使其作为广泛首选的大数据集应用的平台。

 

1.1.3 MapReduce简介

Hadoop另一个比较核心的组件是MapReduce计算框架,MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行计算。它极大的方便编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。它的实现是由Map函数和Reduce函数组成。这种编程模型在很长时间以前就出现了,但当时并不热门。当Google将几篇关于MapReduce的文章发布出来之后,这个编程模型就变得异常火热。以下是关于MapReduce的一些介绍,

(1)MapReduce是最先由Google提出的分布式计算软件架构,是一种用于在大型商用硬件集群中(成千上万的节点)对海量数据(多个字节数据集)实施可靠的、高容错的并行计算的软件系统。

(2)MapReduce的基本原理:“Map”和“Reduce”是编程语言中的概念,都是处理数据集合的函数。整个的思想就是将一个复杂的问题,分成若干个简单的子问题进行解决。然后,对子问题的结果进行合并,得到原有问题的解。一个MapReduce任务会把一个输入数据集分割为独立的数据块,然后Map任务会以完全并行的方式处理这些数据块,再对这些数据块的输出分类,把分类结果作为Reduce任务的输入。关于MapReduce的处理过程如图1-3所示,

第1章 Hive基础知识

 

 

图1-3 MapReduce处理过程

上图是一次MapReduce任务的全过程。用户提交任务给JobTracker,JobTracker把对应用户程序中的Map操作和Reduce操作映射至TaskTracker节点中;输入模块负责把输入数据分成小数据块,并把它们传给Map节点;Map节点得到每一个Key/Value对,处理后产生一个或多个Key/Value对,然后写入文件;Reduce节点获取临时文件中的数据,对带有相同Key的数据进行迭代计算,把最终结果写入文件。

(3)Map在处理数据序列的过程中只处理当前的数据信息,不需要跟之前处理的状态信息交互。

(4)Reduce在处理过程中却依赖之前处理的结果,同时生成的结果也被后续的处理使用。节点得到所有子节点的处理结果,然后把所有结果组合并且返回到输出。

(5)MapReduce的特点是在用Map和Reduce方法来处理分布式计算问题时,尽可能地实现数据处理的本地化,降低由数据移动而产生的代价。每一个Map操作都是相对独立的,所有的Map都是并行运行的,虽然实践中会受到数据源和CPU个数的影响。同样地,用一个Reduce集合来执行Reduce操作,所有带有相同Key的Map输出会聚集到同一个Reduce。能够处理一般服务器所不能处理的大量数据。

初步了解MapReduce的概念以及介绍以后,其实MapReduce有两点最主要的作用及特点,如下所示,

(1)MapReduce通过工作状态的返回有效处理了单点失效的问题。

(2)MapReduce是隶属于大粒度的并行计算模式,并行节点间在Map阶段中和Reduce阶段中无法通信,也并非是一种万能的数据处理模型。

 

1.1.4 HBase简介

HBase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模集群。它是一个可以随机访问的存储和检索数据的平台,允许动态的灵活的数据模型。关于HBase的几点主要作用如下所示,

(1)HBase是开源、分布式、版本化、面向列的存储模型,并且可提供随机、实时的大数据读写访问。

(2)HBase的目标是在商用硬件上存储非常大的表(数十亿的行和数百万的列)。

(4)HBase是对Google公司BigTable系统的开源模仿,并且建立在Hadoop和HDFS之上,作用是来提供类BigTable的存储力。

HBase是一个类似于BigTable的分布式数据库,它是一个稀疏的长期存储、多维度、排序的映射表。这张表的索引是行关键字、列关键字和时间戳。HBase的数据都是字符串,不划分数据类型。关于HBase的数据模型,有以下几点概述,

(1)HBase按预先定义好的列族结构来存储数据,即每一条数据由一个Key及若干列属性值组成,每列的数据都有自己的版本信息。

(2)HBase有两种数据操作的方式。第一种方式是通过对有序Key值进行扫描查询,获取Value值;第二种方式是借助强大的Hadoop来进行MapReduce查询。

(4)HBase采用了强一致性的读写保证,数据会在多个不同的域中进行保存。列族可以包含无限多个数据版本,每个版本可以有自己的TTL。

(5)HBase通过行级锁来保证写操作的原子性,但是不支持多行写操作的事务性。

HBase以表的形式存储数据,其中列划分为若干个列族,每个列族可以有多个列,由于文字讲解比较抽象,可以使用图展示来方便理解,关于HBase表的逻辑视图,如表1-1所示。

表1-1 HBase表的逻辑视图

 

第1章 Hive基础知识

 

 

虽然从概念图来看每个表格是由很多行组成的,但是在物理存储上面,它是按照列来保存的,关于HBase表的物理视图,如表1-2所示。

表1-2 HBase表的物理视图

 

第1章 Hive基础知识

 

 

需要注意的是,在概念视图上面有些列是空白的,这样的列实际上并不会被存储,当请求这些空白的单元格时,会返回null值。如果在查询的时候不提供时间戳,那么会返回距离现在最近的那一个版本的数据,因为在存储的时候,数据会按照时间戳来排序。

在HBase中采用的稀疏存储和物理存储过程中都细化到一个单元。在逻辑视图中,任意不为空的一行的每一列都被称为一个单元。单元联同行键、时间戳、列族名、列名作为完整的一行存储到文件系统中,并且这个存储过程中会自动排序,先在各行键间以字母升序排列,再在同行键间以时间戳降序排列。

关于HBase的物理存储过程,如图1-4所示。

 

第1章 Hive基础知识

 

 

图1-4 HBase物理存储过程

根据上面的过程可以看出表创建的初始阶段只含有一个Region,随着表中数据量的不断增多,一个Region会分裂为两个Region,然后不断重复上述过程,并且Region会被存储到HDFS中不同的Datanode上。其中Region包含一个或多个Store(分为两个部分:第一个部分是Memstore,一个Store中只包含一个Memstore,并且Memstore存储在内存空间中,Storefile的数量也会增加,当文件个数增加到一定量时,系统会自动对Storefile文件进行合并),它的数量增长过程同表中的Region数量增长过程一致。

上面提到的Storefile文件的合并过程,主要完成以下几个工作:

(1)具有相同行键的行存放在一个文件中; 

(2)扔掉被标志为删除的行;

(3)扔掉时间戳过期的行,完成更新操作。随着合并操作的频繁执行Storefile会变得很大,达到一定文件大小时自动分裂文件,贴合HDFS中对一个块数据大小的定义。

在物理存储上一个列族对应一个文件夹,一个文件夹中可包含若干HFile文件。HFile是Storefile的底层文件格式,Storefile就是对HFile做了轻量级包装。

HBase的数据最终是以HFile的形式存储在HDFS中的,HBase中HFile有着自己的格式。一次memstore的flush会产生一个HFile,一次Compact会导致多个HFile合并成一个。本小节主要讲述一下HFile文件格式,并介绍在HBase中读取,写出HFile的过程。通过HBase提供的读/写HFile的reader和writer工厂类,使用者可以直接从HFile文件读取数据,从而绕过HBase提供的Scan、Get、Put等api。关于上面提到的HFile的文件结构,如表1-3所示,

表1-3 hfile文件结构

 

第1章 Hive基础知识

 

 

根据HFile文件结构的图示,总结了几个特点,

(1)HFile记录数据块中以键值对形式存放的用户数据,一条记录保存一个键值对或者说保存一个单元的数据。

(2)元数据块的主要作用是判断一个键值对是否在当前的HFile文件中。

(3)文件信息中保存了与该HFile相关的一些信息,其中有系统保留的一些固定的值,也有用户自定义的一些值。

(4)数据块索引保存的是每一个数据块在HFile文件中的位置、大小信息及每个块的第一个单元的键值。

(5)元数据索引的格式与数据块索引相同,元数据块索引保存的是每一个元数据在HFile文件中的位置、大小信息及每个元数据的键值。

(6)文件尾主要保存了该HFile的一些基本信息,其大小固定,可以根据它查找到fileinfo、block index的起始位置。

 

1.2 Hive概述

1.2.1 Hive简介

Hive诞生于Facebook的日志分析需求,面对海量的结构化数据,Hive以较低的成本完成了以往需要大规模数据库才能完成的任务,并且学习门槛相对较低,应用开发灵活而高效。Hive是一个基于Hadoop的开源数据仓库工具,用来存储和处理海量的结构化数据。它把海量数据存储于Hadoop文件系统,而不是数据库,但提供了一套类数据库的数据存储和处理机制,并采用HQL(类SQL)语言对这些数据进行自动化管理和处理。我们可以把Hive中海量结构化数据看成一个个的表,而实际上这些数据是分布式存储在HDFS中的。Hive经过对语句进行解析和转换,最终生成一系列基于Hadoop的MapReduce任务,通过执行这些任务完成数据处理,由于Hadoop本身在数据存储和计算方面有很好的可扩展性和高容错性,因此使用Hive构建的数据仓库也秉承了这些特性。

简单来说,Hive就是在Hadoop上架了一层SQL接口,可以将SQL翻译成MapReduce去Hadoop上执行,这样就使得数据开发和分析人员很方便地使用SQL来完成海量数据的统计和分析,而不必使用编程语言开发MapReduce 。

先来看一张经典的Hive架构图,如图1-5所示。Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver,结合元数据(MetaStore),将这些指令翻译成MapReduce,提交到Hadoop中执行,最后将执行返回的结果输出到用户交互接口。

第1章 Hive基础知识

 

 

图1-5 Hive架构图

在使用过程中,需要将Hive看成是一个数据库,Hive本身也具备了数据库的很多特性和功能。

关于Hive的特性,有以下几点说明,

(1)Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并为其提供完整的SQL查询功能,可以将SQL语句转换为MapReduce任务进行运行。其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。

(2)Hive是建立在Hadoop上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。Hive定义了简单的类SQL查询语言,称为HQL,它允许熟悉SQL的用户查询数据。同时,这个语言也允许熟悉MapReduce的开发者开发自定义的mapper和reducer来处理内建的mapper和reducer无法完成的复杂的分析工作。

要理解Hive,必须先理解Hadoop和MapReduce,如果有不熟悉的读者,可以通过上一节了解 。

使用Hive的命令行接口,很像操作关系数据库,但是Hive和关系数据库还是有很大不同的,下面就比较一下Hive与关系数据库的区别,如下所述,

(1)Hive和关系数据库存储文件的系统不同,Hive使用的是Hadoop的HDFS(Hadoop的分布式文件系统),关系数据库则是服务器本地的文件系统。

(2)Hive使用的计算模型是MapReduce,而关系数据库则是自己设计的计算模型。

(3)关系数据库都是为实时查询业务进行设计的,而Hive则是为海量数据做数据挖掘设计的,实时性很差。这导致Hive的应用场景和关系数据库有很大的不同。

(4)Hive很容易扩展自己的存储能力和计算能力,这是继承自Hadoop的特点,而关系数据库在这个方面要比Hive差很多。

Hive可以使用HQL(Hive SQL)很方便地完成对海量数据的统计汇总,即席查询和分析,除了很多内置的函数,还支持开发人员使用其他编程语言和脚本语言来自定义函数。但是,由于Hadoop本身是一个批处理、高延迟的计算框架,Hive使用Hadoop作为执行引擎,自然也就有了批处理、高延迟的特点。在数据量很小的时候,Hive执行也需要消耗较长时间来完成,这时候,就显示不出它相对Oracle、MySQL等传统数据库的优势。此外,Hive对事物的支持不够好,原因是HDFS本身就设计为一次写入、多次读取的分布式存储系统,因此,不能使用Hive来完成诸如delete、update等在线事务处理的需求。

因此,Hive擅长的是非实时的、离线的、对响应及时性要求不高的海量数据批量计算,即席查询,统计分析。

 

1.2.2 Hive的数据单元及类型

根据颗粒度的顺序,Hive数据被分成:

(1)Databases:数据库。概念等同于关系型数据库的Schema,在此不多解释。

(2)Tables:表。概念等同于关系型数据库的表,在此不多解释。

(3)Partitions:分区。概念类似于关系型数据库的表分区,没有那么多分区类型,只支持固定分区,将同一组数据存放至一个固定的分区中。

(4)Buckets(或 Clusters):分桶。同一个分区内的数据还可以细分,将相同的Key再划分至一个桶中,这个有点类似于HASH分区,只不过这里是HASH分桶,也有点类似子分区。

既然Hive是被当成数据库来使用,除了数据单元,Hive当然也得有一些列的数据类型。

(1)原始数据类型

l 整型

TINYINT:微整型,只占用1字节,只能存储0~255的整数。

SMALLINT:小整型,占用2字节,存储范围-32,768~32,767。

INT:整型,占用4字节,存储范围-2,147,483,648~2,147,483,647。

BIGINT:长整型,占用8字节,存储范围-2^63~2^63-1。

l 布尔型

BOOLEAN:TRUE/FALSE。

l 浮点型

FLOAT:单精度浮点数。

DOUBLE:双精度浮点数。

l 字符串型

STRING:不设定长度。

(2)复合数据类型

Structs:一组由任意数据类型组成的结构。比如,定义一个字段C的类型为STRUCT {a INT; b STRING},则可以使用a和C.b来获取其中的元素值。

Maps:和Java中的Map没什么区别,就是存储K-V对的。

Arrays:就是数组而已。

 

1.2.3 Hive组件

Hive的组件包括服务器组件和客户端组件两种形式,关于Hive服务端组件包括如下几种,

1)Driver组件:该组件包括Complier、Optimizer和Executor,它的作用是将我们写的HiveQL(类SQL)语句进行解析、编译优化,生成执行计划,然后调用底层的MapReduce计算框架。

2)Metastore组件:元数据服务组件,这个组件存储Hive的元数据,Hive的元数据存储在关系数据库里,Hive支持的关系数据库有Derby、MySQL。元数据对于Hive十分重要,因此Hive支持把Metastore服务独立出来,安装到远程的服务器集群里,从而解耦Hive服务和Metastore服务,保证Hive运行的健壮性。

3)Thrift服务:Thrift是Facebook开发的一个软件框架,它用来进行可扩展且跨语言的服务的开发,Hive集成了该服务,能让不同的编程语言调用Hive的接口。

了解到Hive的服务端组件之后,Hive的客户端组件也有如下几种,

1)CLI:Command Line Interface,命令行接口。

2)Thrift客户端:图1-5所示的架构图中提到的Thrift客户端,Hive架构的许多客户端接口是建立在该客户端之上的,包括JDBC和ODBC接口。

3)WEBGUI:Hive客户端提供了一种通过网页的方式访问Hive所提供的服务。这个接口对应Hive的hwi组件(hive web interface),使用前要启动hwi服务。

在上面提到的所有组件中,Hive中比较重要的组件还是Metastore了,因为Metastore组件存储Hive的元数据,因此下面将着重讲述Metastore组件,具体描述如下,

Hive的Metastore组件是Hive元数据集中存放地。Metastore组件包括两个部分:Metastore服务和后台数据的存储。后台数据存储的介质就是关系数据库,如Hive默认的嵌入式磁盘数据库Derby,还有MySQL数据库。Metastore服务是建立在后台数据存储介质之上,可以和Hive服务进行交互的服务组件。默认情况下,Metastore服务和Hive服务是安装在一起的,运行在同一个进程当中。也可以把Metastore服务从Hive服务里剥离出来,Metastore独立安装在一个集群里,Hive远程调用Metastore服务,这样就可以把元数据这一层放到防火墙之后。客户端访问Hive服务,就可以连接到元数据这一层,从而提供了更好的管理性和安全保障。使用远程的Metastore服务,可以让Metastore服务和Hive服务运行在不同的进程里,这样就保证了Hive的稳定性,提升了Hive的服务效率。

 

1.2.4 Hive vs 关系型数据库

在初步了解Hive概念以及介绍之后,可以简单的对Hive进行一些操作,方便我们更深入的了解到Hive这个工具的作用,下面是一个简单的demo,让我们来看看Hive是如何操作的。

首先创建一个普通的文本文件,里面只有一行数据,该行也只存储一个字符串,命令如下:

 

echo 'sharpxiajun' > /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很像,根据上面的例子,可能大家觉得跟SQL没有本质的区别,下面就让我们来看一下Hive与关系型数据库在哪些方面存在差异,主要有以下几点,

(1)关系数据库里,表的加载模式是在数据加载时强制确定的(表的加载模式是指数据库存储数据的文件格式),如果加载数据时发现加载的数据不符合模式,关系数据库会拒绝加载数据,这称为“写时模式”,写时模式会在数据加载时对数据模式进行检查校验的操作。Hive在加载数据时和关系数据库不同,Hive在加载数据时不会对数据进行检查,也不会更改被加载的数据文件,而检查数据格式的操作是在查询操作时执行的,这种模式称为“读时模式”。在实际应用中,写时模式在加载数据时会对列进行索引,对数据进行压缩,因此加载数据的速度很慢,但是当数据加载好后,去查询数据时,速度很快。当我们的数据是非结构化,存储模式也是未知时,关系数据库操作这种场景就麻烦多了,这时候Hive就会发挥它的优势。

(2)关系数据库一个重要的特点是可以对某一行或某些行的数据进行更新、删除操作, Hive不支持对某个具体行的操作,Hive对数据的操作只支持覆盖原数据和追加数据。Hive也不支持事务和索引,更新、事务和索引都是关系数据库的特征,这些Hive都不支持,也不打算支持,原因是Hive的设计是针对海量数据的处理,全数据的扫描是常态,针对某些具体数据进行操作的效率是很差的,对于更新操作,Hive是通过查询将原表的数据进行转化最后存储在新表里,这和传统数据库的更新操作有很大不同。

(3)Hive也可以为Hadoop在实时查询上做一份自己的贡献,那就是和HBase集成,HBase可以进行快速查询,但是HBase不支持类SQL的语句,那么此时Hive可以给HBase提供SQL语法解析的外壳,可以用类SQL语句操作HBase数据库。

 

练 习

1.1 Hadoop是什么?

1.2 Hive是什么?其主要的作用是什么?