Hive总结

来源:互联网 发布:移动数据开着不能上网 编辑:程序博客网 时间:2024/05/17 19:21


1、Hive概念

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

数据仓库

数据仓库(Data Warehouse, DW或者DWH),是为企业所有级别的决策制定过程,提供所有类型数据支持的战略集合。它是单个数据存储,出于分析性报告和决策支持目的而创建。 为需要业务智能的企业,提供指导业务流程改进、监视时间、成本、质量以及控制简而言之,数据仓库是用来做查询分析的数据库,基本不用来做插入,修改,删除。(这就是数据仓库和数据库的区别,数据库只用来查询就是数据仓库)

Hive架构原理

Hive执行流程

Ÿ   编译器将一个Hive QL转换操作符

Ÿ   操作符是Hive的最小处理单元

Ÿ   每个操作符代表HDFS的一个操作或者一个MR作业

Operator

Ÿ   Operator是Hive定义的一个处理过程

Ÿ   Operator定义有:

protectedList <Operator<? extendsSerializable >> childOperators;

protectedList <Operator<? extendsSerializable >> parentOperators;

protectedboolean done;  //初始化值为false

Ÿ   所有的操作构成了Operator图,Hive基于这些图关系来处理limt, group by, join等操作。

操作符如下:

    TableScanOperator:扫描hive表数据
    ReduceSinkOperator:创建将发送到Reducer端的<Key,Value>对
    JoinOperator:Join两份数据
    SelectOperator:选择输出列
    FileSinkOperator:建立结果数据,输出至文件
    FilterOperator:过滤输入数据
    GroupByOperator:GroupBy语句
    MapJoinOperator:/*+mapjoin(t) */
    LimitOperator:Limit语句
    UnionOperator:Union语句

 

Hive工作流程

Ÿ   1.Execute Query:Hive界面如命令行或Web UI将查询发送到Driver(任何数据库驱动程序如JDBC、ODBC,等等)来执行。

Ÿ   2.Get Plan: Driver根据查询编译器解析query语句,验证query语句的语法,查询计划或者查询条件。

Ÿ   3.Get Metadata:编译器将元数据请求发送给Metastore(任何数据库)。

Ÿ   4.Send Metadata:Metastore将元数据作为响应发送给编译器。

Ÿ   5.Send Plan:编译器检查要求和重新发送Driver的计划。到这里,查询的解析和编译完成。

Ÿ   6.Execute Plan: Driver将执行计划发送到执行引擎。

Ÿ   7.Execute Job: Hadoop内部执行的是MapReduce工作过程,任务执行引擎发送一个任务到资源管理节点(ResourceManager),资源管理器分配该任务到任务节点,由任务节点上开始执行MapReduce任务。

Ÿ   7.1Metadata Ops:在执行引擎发送任务的同时,对Hive的元数据进行相应操作。

Ÿ   8.Fetch Result:执行引擎接收数据节点(data node)的结果。

Ÿ   9.Send Results: 执行引擎发送这些合成值到Driver。

Ÿ   10.Send Results:Driver将结果发送到Hive接口。

 

2、Hive三种方式区别和搭建

Hive中metastore(元数据存储)的三种方式:

a)内嵌Derby方式

b)Local方式

c)Remote方式

内嵌derby

这种方式是最简单的存储方式,只需要在hive-site.xml做如下配置便可

<?xml version="1.0"?>  

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>  

  

<configuration>  

  

<property>  

  <name>javax.jdo.option.ConnectionURL</name>  

  <value>jdbc:derby:;databaseName=metastore_db;create=true</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionDriverName</name>  

  <value>org.apache.derby.jdbc.EmbeddedDriver</value>  

</property>  

   

<property>  

  <name>hive.metastore.local</name>  

  <value>true</value>  

</property>  

   

<property>  

  <name>hive.metastore.warehouse.dir</name>  

  <value>/user/hive/warehouse</value>  

</property>  

   

  

</configuration>  


注:使用derby存储方式时,运行Hive会在当前目录生成一个derby文件和一个metastore_db目录。这种存储方式的弊端是在同一个目录下同时只能有一个Hive客户端能使用数据库,否则会提示如下错误:

[html] view plaincopyprint?

hive> show tables;  

FAILED: Error in metadata: javax.jdo.JDOFatalDataStoreException: Failed to start database 'metastore_db', see the next exception for details.  

NestedThrowables:  

java.sql.SQLException: Failed to start database 'metastore_db', see the next exception for details.  

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask  

hive> show tables;

FAILED: Error inmetadata: javax.jdo.JDOFatalDataStoreException: Failed to start database'metastore_db', see the next exception for details.

NestedThrowables:

java.sql.SQLException:Failed to start database 'metastore_db', see the next exception for details.

FAILED: Execution Error,return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask

本地MySQL

这种存储方式需要在本地运行一个MySQL服务器,并作如下配置(下面两种使用MySQL的方式,需要将MySQL的jar包拷贝到$HIVE_HOME/lib目录下)。

<?xml version="1.0"?>  

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>  

  

<configuration>  

<property>  

  <name>hive.metastore.warehouse.dir</name>  

  <value>/user/hive_remote/warehouse</value>  

</property>  

   

<property>  

  <name>hive.metastore.local</name>  

  <value>true</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionURL</name>  

  <value>jdbc:mysql://localhost/hive_remote?createDatabaseIfNotExist=true</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionDriverName</name>  

  <value>com.mysql.jdbc.Driver</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionUserName</name>  

  <value>hive</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionPassword</name>  

  <value>password</value>  

</property>  

</configuration>  

 

远端MySQL

(1)remote一体

这种存储方式需要在远端服务器运行一个MySQL服务器,并且需要在Hive服务器启动meta服务。

这里用MySQL的测试服务器,ip位192.168.1.214,新建hive_remote数据库,字符集位latine1

<?xml version="1.0"?>  

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>  

   

<configuration>  

  

<property>  

  <name>hive.metastore.warehouse.dir</name>  

  <value>/user/hive/warehouse</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionURL</name>  

  <value>jdbc:mysql://192.168.57.6:3306/hive?createDatabaseIfNotExist=true</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionDriverName</name>  

  <value>com.mysql.jdbc.Driver</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionUserName</name>  

  <value>hive</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionPassword</name>  

  <value>password</value>  

</property>  

  

<property>  

  <name>hive.metastore.local</name>  

  <value>false</value>  

</property>  

  

<property>  

  <name>hive.metastore.uris</name>  

  <value>thrift://192.168.1.188:9083</value>  

</property>  

  

</configuration>  

 

注:这里把Hive的服务端和客户端都放在同一台服务器上了。服务端和客户端可以拆开。

(2)Remote分开

将hive-site.xml配置文件拆为如下两部分

1)、服务端配置文件

<?xml version="1.0"?>  

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>  

   

<configuration>  

  

<property>  

  <name>hive.metastore.warehouse.dir</name>  

  <value>/user/hive/warehouse</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionURL</name>  

  <value>jdbc:mysql://192.168.57.6:3306/hive?createDatabaseIfNotExist=true</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionDriverName</name>  

  <value>com.mysql.jdbc.Driver</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionUserName</name>  

  <value>root</value>  

</property>  

   

<property>  

  <name>javax.jdo.option.ConnectionPassword</name>  

  <value>123456</value>  

</property>  

</configuration>  

 

2)、客户端配置文件

<?xml version="1.0"?>  

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>  

   

<configuration>  

  

<property>  

  <name>hive.metastore.warehouse.dir</name>  

  <value>/user/hive/warehouse</value>  

</property>  

   

<property>  

  <name>hive.metastore.local</name>  

  <value>false</value>  

</property>  

  

<property>  

  <name>hive.metastore.uris</name>  

  <value>thrift://192.168.57.5:9083</value>  

</property>  

  

</configuration>  

 

启动Hive服务端程序

 hive --service metastore   

 

客户端直接使用Hive命令即可

root@my188:~$ hive   

Hive history file=/tmp/root/hive_job_log_root_201301301416_955801255.txt  

hive> show tables;  

OK  

test_hive  

Time taken: 0.736 seconds  

hive>  

 

3、Hive的数据类型和DDL

具体参见https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL

 

重点是hive 的建表语句和分区

4、Hive的数据加载和DML

具体参见https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML

 

重点是数据加载和查询插入语法

 

5、HiveServer2和Hive JDBC

企业用Hive的-e  -f  -i三个参数



6、Hive的UDF和UDAF UDTF

自定义函数包括三种UDFUDAFUDTF

UDF(User-Defined-Function)一进一出

UDAF(User- Defined Aggregation Funcation)聚集函数,多进一出。Count/max/min

UDTF(User-Defined Table-GeneratingFunctions)&#160;一进多出,如lateral view explore()

使用方式:在HIVE会话中add自定义函数的jar文件,然后创建function继而使用函数

UDF开发

1UDF函数可以直接应用于select语句,对查询结构做格式化处理后,再输出内容。

2、编写UDF函数的时候需要注意一下几点:

a)自定义UDF需要继承org.apache.hadoop.hive.ql.UDF

b)需要实现evaluate函数,evaluate函数支持重载。

3、步骤

a)把程序打包放到目标机器上去;

b)进入hive客户端,添加jar包:hive>add jar /run/jar/udf_test.jar;

c)创建临时函数:hive>CREATE TEMPORARY FUNCTION add_example AS'hive.udf.Add';

d)查询HQL语句:

    SELECTadd_example(8, 9) FROM scores;

    SELECTadd_example(scores.math, scores.art) FROM scores;

    SELECTadd_example(6, 7, 8, 6.8) FROM scores;

e)销毁临时函数:hive> DROP TEMPORARY FUNCTION add_example;

UDAF自定义集函数

多行进一行出,如sum()min(),用在group  by

1.必须继承

org.apache.hadoop.hive.ql.exec.UDAF(函数类继承)

org.apache.hadoop.hive.ql.exec.UDAFEvaluator(内部类Evaluator实现UDAFEvaluator接口)

2.Evaluator需要实现 inititerateterminatePartialmergeterminate这几个函数:

init():类似于构造函数,用于UDAF的初始化

iterate():接收传入的参数,并进行内部的轮转,返回boolean

terminatePartial():无参数,其为iterate函数轮转结束后,返回轮转数据,类似于hadoopCombiner

merge():接收terminatePartial的返回结果,进行数据merge操作,其返回类型为boolean

terminate():返回最终的聚集函数结果

 

开发一个功能同:

Oraclewm_concat()函数

Mysqlgroup_concat()

 

7、Hive嵌入Python

Python的输入输出都是\t为分隔符,否则会出错,python脚本输入print出规定格式的数据

用法为先addfile,使用语法为TRANSFORM (name, items)   USING'python test.py'  AS (name string, item1string,item2 string,item3 string),这里后面几个字段对应python的类型

 

create table test (namestring,items string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

LOAD DATA local INPATH'/opt/data/tt.txt' OVERWRITE INTO TABLE test ;

create table test2 (namestring,item1 string,item2 string,item3 string) ROW FORMAT DELIMITED FIELDSTERMINATED BY '\t';

 

INSERT OVERWRITE TABLEtest2 

SELECT 

  TRANSFORM (name, items) 

  USING 'python test.py' 

  AS (name string, item1 string,item2string,item3 string) 

FROM test;

 

 

 

#!/usr/bin/python 

import sys 

for line insys.stdin: 

     line = line.strip()   

     name,it = line.split('\t') 

     count = it.count(',')+1

     for i in range(0,3-count):

          it = it+',NULL'

     result = it.split(',')[0:3]

     print '%s\t%s'%(name,'\t'.join(result))

8、HWI环境搭建

HWI是Hive Web Interface的简称,是hive cli的一个web替换方案。

需要下载Hive的源码文件,然后将hwi/web目录下的文件用 jar cvf hive-hwi-0.13.1.war ./*

其实war包也是zip包,可以通过

cd hwi/web
zip hive-hwi-1.2.1.zip ./*     //打包成.zip文件。

将zip包后缀改成war

mv hive-hwi-1.2.1.zip hive-hwi-1.2.1.war
cp hive-hwi-1.2.1.war /opt/soft/apache-hive-1.2.1-bin/lib/

命令来打包成一个war包,然后放到Hive的lib目录下即可

配置conf/hive-site.xml

<property>

<name>hive.hwi.war.file</name>

<value>lib/hive-hwi-1.2.1.war</value>

</property>

 

<property>

<name>hive.hwi.listen.host</name>

<value>0.0.0.0</value>

</property>

 

<property>

<name>hive.hwi.listen.port</name>

<value>9999</value>

</property>

 

执行命令hive--service hwi

访问http://192.168.17.4:9999/hwi

可参照http://blog.csdn.net/wulantian/article/details/38271803

9、Hive的优化