Hive的原理与操作Hive简介Hive可以被认为是一种数据仓库,包括数据的存储以及查询Hive包括一个高层语言的执行引擎,类似于SQL的执行Hive建立在Hadoop的其它组成部分之上,包括Hive依赖于HDFS进行数据保存,依赖于MapReduce完成查询操作Hive最初的开发由Facebook推动,在Facebook内部每天会搜集大量的数据,并需要在这些数据上进行大量分析最初的分析是通过手工的python脚本形式进行数据分析的数量十分巨大,在2006年每天需要分析数十个10GB左右的数据,在2007年增长到大约TB的量级,现在数据分析的数量可能是这个数量的10倍使用Hadoop进行数据分析通过前面的课程知道,上述的分析任务可以通过Hadoop集群进行,即可以通过Hadoop集群将任务分布到数百甚至上千个节点中进行分析,通过并行执行锁定分析的时间如果原始数据使用数据库形式的话,则需要进行数据的转换,将数据存储到分布式文件系统HDFS中,然后通过MapReduce程序进行分析Hadoop通过MapReduce的并行化方式进行并行处理,能够充分利用数目庞大的分析机器但是,MapReduce是一个底层的编程接口,对于数据分析人员来说,这个编程接口并不是十分友好,还需要进行大量的编程以及调试工作在Hadoop上加入数据分析的功能显然,为了能够支持一个类似于SQL相关的数据查询语言,Hadoop还需要加入一些额外的模块才能够方便数据分析人员的使用,这些额外的模块包括:•数据查询语言本身的定义与构造,这是与终端用户进行交互的接口,最简单的可以通过命令行接口的方式展开用户与系统的交互•构造数据查询语言的执行引擎,即将上述的查询语言进行编译,并通过分布式的执行引擎完成查询,在Hive中,执行引擎会将查询语言翻译为多个MapReduce的任务序列,交给MapReduce程序去执行•数据查询语言本身需要定义一套数据组织的格式Hive的组成模块(1)Hive的模块非常类似于传统的数据库的模块,下面是Hive的必要组成模块以及对应的功能介绍HiveQL:这是Hive的数据查询语言,与SQL非常类似。Hive提供了这个数据查询语言与用户的接口,包括一个shell的接口,可以进行用户的交互,以及网络接口与JDBC接口。JDBC接口可以用于编程,与传统的数据库编程类似,使得程序可以直接使用Hive功能而无需更改Driver:执行的驱动,用以将各个组成部分形成一个有机的执行系统,包括会话的处理,查询获取以及执行驱动Hive的组成模块(2)Compiler:Hive需要一个编译器,将HiveQL语言编译成中间表示,包括对于HiveQL语言的分析,执行计划的生成以及优化等工作ExecutionEngine:执行引擎,在Driver的驱动下,具体完成执行操作,包括MapReduce执行,或者HDFS操作,或者元数据操作Metastore:用以存储元数据:存储操作的数据对象的格式信息,在HDFS中的存储位置的信息以及其他的用于数据转换的信息SerDe等Hive的系统结构Hive的数据模型每一个类似于数据库的系统都首先需要定义一个数据模型,然后才是在这个数据模型之上的各种操作Tables:Hive的数据模型由数据表组成•数据表中的列是有类型的(int,float,string,data,boolean)•也可以是复合的类型,如list:map(类似于JSON形式的数据)Partitions:数据表可以按照一定的规则进行划分Partition•例如,通过日期的方式将数据表进行划分Buckets:数据存储的桶元数据存储:Metastore在Hive中由一系列的数据表格组成一个名字空间,关于这个名字空间的描述信息会保存在Metastore的空间中元数据使用SQL的形式存储在传统的关系数据库中,因此可以使用任意一种关系数据库,例如Derby(apache的关系数据库实现),MySQL以及其他的多种关系数据库存储方法数据的物理分布情况Hive在HDFS中有固定的位置,通常被放置在HDFS的如下目录中/home/hive/warehouse每个数据表被存放在warehouse的子目录中•数据划分Partition,数据桶Buckets形成了数据表的子目录上述数据实际上是数据表文件的元数据,保存在HDFS的NameNode中,实际数据则存储在DataNode中,可能以任意一种形式存储,例如:•使用分隔符的文本文件,或者是SequenceFile•使用用户自定义的形式Hive系统的配置要想Hive使用HDFS进行数据仓库的存储,使用MapReduce进行HQL语言的执行,需要进行相应的配置。首先,需要创建Hive的配置文件hive-site.xml(注意,Hive安装包中包含一个配置文件模板-hive-default.xml.template)。•fs.default.name用以告知Hive对应的HDFS文件系统的名字节点在什么位置•mapred.job.tracker用以告知Hive对应的MapReduce处理系统的任务管理器在什么位置通过上面两点的配置,就可以让Hive系统与对应的HDFS以及MapReduce进行交互,完成数据的存取以及查询的操作启动Hive的命令行界面shell完成Hive系统的合适配置之后,打开任意一个命令行界面,执行下面的命令就可以启动hive的界面$cd/hive/install/directory进入hive的安装目录,如果通过IDH安装,并配置好环境变量,则不需要这一步hivehive等待用户输入查询命令创建数据表的命令hiveshowtables;显示所有的数据表hivecreatetableshakespeare(freqint,wordstring)rowformatdelimitedfieldsterminatedby‘\t’storedastextfile;创建一个表,这个表包括两列,分别是整数类型以及字符串类型,使用文本文件表达,数据域之间的分隔符为\thivedescribeshakespeare;显示所创建的数据表的描述,即创建时候对于数据表的定义装入数据数据装入到Hive中hiveloaddatainpath“shakespeare_freq”intotableshakespeare;数据查询select语句hiveselect*fromshakespearelimit10;hiveselect*fromshakespearewherefreq100sortbyfreqasclimit10;查询语句,获取频率最高的单词hiveselectfreq,count(1)asf2fromshakespearegroupbyfreqsortbyf2desclimit10;hiveexplainselectfreq,count(1)asf2fromshakespearegroupbyfreqsortbyf2desclimit10;Hive深入了解Hive可以通过不同的形式提供服务cli:Hive的命令行接口,这是默认的服务hiveserver:让Hive以Thrift服务器的形式运行,接受Thrift,JDBC,ODBC连接的客户端的通信,默认端口为HIVE_PORT=10000hwi:Hive的Web接口jar:这个接口与hadoopjar等价,在运行jar包的时候同时将类路径包含了Hadoop以及Hive的类路径metastore:在通常情况下,metastore和Hive服务运行在同一个进程,使用这个服务,也可以让metastore作为单独的进程运行,环境变量METASTORE_PORT可以指定服务器监听端口号HiveWebInterface(HWI)编辑配置文件,conf/hive-site.xmlHWI启动hwi服务:%exportANT_LIB=/path/to/ant/lib%hive--servicehwi通过浏览器连接hwi服务HWI界面Localhost:9999/hwiHive客户端通过将Hive运行为服务器hive–servicehiveserver可以启动一个服务,而后可以通过不同的客户端连接到这个服务去访问Hive提供的功能Hive中的元数据存储metastoremetastore包括两个部分:服务和后台的数据存储•Embeddedmetastore:默认使用内嵌的Derby数据库实例,每次只能打开一个Hive会话•Localmetastore:可以使用运行在一个进程中的metastore进程来访问独立的数据库,可通过JDBC进行设置具体的数据库访问•Remotemetastore:一个或者多个metastore服务器和Hive服务运行在不同的进程内metastore的配置情况HiveJDBC编程HiveJDBCHive支持了标准的数据库查询接口JDBC在JDBC中需要指定驱动字符串以及连接字符串驱动器字符串为“org.apache.hadoop.hive.jdbc.HiveDriver”,即在Hive的软件包中已经加入了对应的JDBC的驱动程序连接字符串则是标志了对应Hive服务器,例如jdbc:hive://master:10000/default之后,可以直接使用传统的JDBC编程技术去访问Hive所提供的功能HiveJDBC程序举例Hive的分区和桶Hive的分区和桶Hive把表组织成分区partition的形式分区实际上是使用分区列partitioncolumn的值对表进行粗略划分的方式,使用分区可以加速数据分片slice的查询速度•例如,在进行日志分析的时候可以依据日志的日期以及日志发生的地面建立不同的分区表或者分区可以进一步被划分为桶,能够为数据提供额外的结构,以获得更高效率的查询速度•例如在进行用户点击分析的时候,可以依据用户的ID号来进行桶的划分分区方法举例以日志信息为例,假设每条日志包含一个时间戳,可以根据日期对其进行区分,同一天的记录会被存放在同一个分区中另外,除了使用日期进行分区之外,还可以根据国家进行子分区(subpartition)CREATETABLElogs(timestampBIGINT,lineSTRING)PARTITIONEDBY(dateSTRING,countrySTRING)这样的话数据空间首先是进行日期分区,然后进行按照国家进行分区Hive中的桶在Hive中可以把数据按照桶的方式存放在不同文件中需要注意的是桶与分区是两个独立的概念,任何一个概念都不包含对方分区包含的域,即前面的date以及country实际上并不会在数据记录中出现,而作为桶的域则需要在数据记录中出现通过桶的方式能够获得更高的查询处理效率,依据桶带来的额外的结构通过桶也可以提高取样的效率桶的划分通过使用CLUSTERBY子句可以将数据记录划分到桶中,例如以下的对用户的划分CREATETABLEbucketed_users(idINT,nameSTRING)CLUSTEREDBY(id)INTO4BUCKETS;对于map端连接的情况而言,两个表以相同的方式划分桶,处理其中一个表的mapper知道另外一个表的匹配的行的具体的桶,就可以无需访问其它的桶将数据插入到分桶的表中将hive.enforce.bucketing属性设置为true下面的语句将数据从不分桶的表插入到分桶的表INSERTOVERWRITETABLEbucketed_usersSELECT*fromusers;桶在物理上实际就是文件系统中的表目录中的一个文件。文件名不是很重要,桶n无非是这个目录中按照字典顺序排序的第n个文件,就对应于MapReduce的输出文件分区例如:•hivedfs–ls/user/hive/warehouse/bucketed_users;•Attempt_201211221523_0023_4_000000_0•Attempt_201211221523_0023_4_00