【转】 hive简介,安装 配置常见问题和例子

原文来自:  http://blog.csdn.net/zhumin726/article/details/8027802

1 HIVE概述

Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,HIVE的设计,可以轻松实现数据汇总,ad-hoc查询和分析大量的数据。它提供了一种称为HIVE QL的查询语言,基于sql的语法,使用户熟悉HIVE QL的语法容易做ad-hoc查询,汇总和数据分析,同时,HIVE QL也使传统的map / reduce的程序员能够插入他们的自定义映射器和减速器做更复杂的分析,可能不支持通过内置的语言能力。

HIVE不能做的事情:Hadoop是一个批量处理系统,Hadoop的工作往往具有较高的延迟,并在作业提交和调度产生大量的间接成本。因此 - HIVE查询的延迟通常是非常高(分钟),即使涉及的数据集,是非常小的(比如一个几百兆字节)。HIVE的目的是提供可以接受对小数据集或测试查询的延迟(但不是最优的)交互式数据浏览,查询。HIVE是不适合联机事务处理和不提供实时查询和行级的更新。

2 HIVE安装

2.1安装

从源代码进行安装

$ svn co http://svn.apache.org/repos/asf/hive/trunkhive

  $ cd HIVE

  $ ant clean package

  $ cd build/dist

  $ ls

  README.txt

  bin/ (all the shell scripts)

  lib/ (required jar files)

  conf/ (configuration files)

  examples/ (sample input andquery files)

从稳定版本安装

下载HIVE-x.y.z:

解压缩

tar -xzvf HIVE-x.y.z.tar.gz

设置环境变量

cd HIVE-x.y.z
export HIVE_HOME={{pwd}}
export PATH=$HIVE_HOME/bin:$PATH

2.2 运行

在运行前,需要先这是环境变量HADOOP_HOME

并且在hadoop中建文件系统

$HADOOP_HOME/bin/hadoop fs -mkdir       /tmp
  $ $HADOOP_HOME/bin/hadoop fs -mkdir       /user/HIVE/warehouse
  $ $HADOOP_HOME/bin/hadoop fs -chmod g+w   /tmp
  $ $HADOOP_HOME/bin/hadoop fs -chmod g+w   /user/HIVE/warehouse

HIVE的运行方式有以下几种

Cli 命令行模式HIVE_HOME/bin/HIVE  

Hwi web接口HIVE_HOME/bin/HIVE –service hwi

配置HIVE-site

<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>

<property>
<name>hive.hwi.war.file</name>
<value>lib/hive-hwi-0.9.0.war </value>
<description>Thisis the WAR file with the jsp content for Hive Web Interface</description>
</property>

可以通过http://ip:9999/hwi访问,界面进行操作

Hiveserver bin/hive –service hiveserver 可以使用Trift,JDBC,ODBC进行访问,默认端口10000,也可以通过环境变量设置HIVE_PORT

Jar  Java调用

假如需要把HIVE的元数据存储在其他数据库中可以通过配置HIVE-site.xml来定义如下:

<property>

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

 <value>jdbc:MySQL://10.10.21.52:3306/hive?characterEncoding=UTF-8</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>root</value>  

    </property>

注:一定要拷贝数据库驱动到HIVE/lib下

2.3常见问题

问题 : FAILED:Error in metadata: javax.jdo.JDODataStoreException: Error(s) were found whileauto-creating/validating the datastore for classes. The errors are printed inthe log, and are attached to this exception.
NestedThrowables:
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Specified key was toolong; max key length is 1000 bytes
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask

或者是
FAILED: Error in metadata: MetaException(message:Got exception:org.apache.thrift.transport.TTransportException null)
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Specified key was too long; max key length is 767 bytes
FAILED: Execution Error, return code 1 fromorg.apache.hadoop.hive.ql.exec.DDLTask

解决方法:alterdatabase hivedb character set latin1;

问题:Exceptionin thread "main" java.lang.NoClassDefFoundError: jline/ArgumentCompletor$ArgumentDelimiter       
at java.lang.Class.forName0(Native Method)       
at java.lang.Class.forName(Class.java:247)       
at org.apache.hadoop.util.RunJar.main(RunJar.java:149)
Caused by: java.lang.ClassNotFoundException: jline.ArgumentCompletor$ArgumentDelimiter       
at java.NET.URLClassLoader$1.run(URLClassLoader.java:202)       
at java.security.AccessController.doPrivileged(Native Method)      
at java.Net.URLClassLoader.findClass(URLClassLoader.java:190)      
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)       
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

解决方法:jline版本不一致,把HADOOP_HOME/lib和HIVE_HOME/lib下的jline-**.jar版本一致就可以了,复制其中一个高版本覆盖另一个。

3 HIVE表结构

3.1数据类型

类型相关联的表中的列。支持下列基本类型:

整数

TINYINT - 1字节的整数

SMALLINT - 2个字节的整数

INT - 4字节整数

BIGINT - 8个字节的整数

布尔类型

BOOLEAN - TRUE /​​FALSE

浮点数

FLOAT - 单精度

双 -双精度

String类型

STRING - 在指定的字符集的字符序列

类型进行转换例如TYNTINT可以转换成INT,单不能反转,除非使用CAST,数字可以转换成字符串,字符转换成数字需要: CAST(‘1’ AS INT)

复杂类型:

  Array数组

 Map图

 Struct结构

例如:

CREATE TABLE complex(

         Col1ARRAY<INT>,

         Col2MAP<STRING,INT>,

COL3 STRCUT<a:STRING,b:INT,c:DOUBLE>

)

Select col1[0],col2[‘a’],col3.b from complex;

3.2数据单元

按粒度的顺序: 

数据库:单独的表和其他数据单元命名冲突的命名空间。支持create database **和use **缺省数据库名是default。

:均质单位的数据有相同的模式。一个表的一个例子可能是PAGE_VIEWS表,每行可包括以下各列(架构):

时间戳 -这是INT类型,对应到UNIX时间戳,当网页被浏览的。

用户ID -这是标识该用户浏览页面的BIGINT类型。

page_url -是STRING类型捕获页面的位置。

referer_url -这是的的STRING,捕捉用户从那里到达当前页面的页面位置。

IP -这是字符串类型,抓住了IP地址的页面请求。

分区:每个表只能有一个或多个分区键决定如何将数据存储。分区-除了存储单元-使用户能够有效地识别出满足一定条件的行。

 :在每个分区中的数据可依次分为桶的表中的某些列的哈希函数值的基础上 例如通过用户ID来划分捅,我们可以在所有用户集合的随机样本上快速计算基于用户的查询。

3.3存储格式

Hive从2个维度对表进行管理,行格式和文件格式。航格式指行和一行中的字段如何存储,按照HIVE的术语,行格式的定义由SerDe(serializer-Deserializer序列化反序列化工具)定义

如果创建表时没有使用ROW FORMAT或者STORED AS字句,那么HIVE默认使用文本格式,一行存储一个数据行。

Row format derde ‘SerDe名’ with SERDEPROPERTIES (key1=value,key2=value2)STORED AS

SEQUENCEFILE/RCFILE/ TEXTFILE…

例如ngixn日志使用:CREATE TABLE log (host STRING,identity STRING,user STRING,time STRING,request STRING,status STRING,size STRING,referer STRING,agent STRING) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' WITH SERDEPROPERTIES ("input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) (-|\[[^\]]*\]) ([^ "]*|"[^"]*") (-|[0-9]*) (-|[0-9]*)(?: ([^ "]*|".*") ([^ "]*|".*"))?","output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s")STORED AS TEXTFILE; 

 

 

 

4 HIVE QL

4.1DDL

显示数据库:showdatabases;

建数据库createdatabase db1;

切换数据库:usedb1;

显示所有表showtables;

显示一部分表名匹配的表 :SHOW TABLES '.*s';

建表:

CREATE TABLE invites (foo INT, bar STRING)[ PARTITIONED BY (ds STRING)];

 

查看表结构

DESCRIBE  表名

修改表列名

Alter table PERSON age to age1

增加表列

Alter table PERSON  add columns (ageINT);

删除表DROPTABLE表名;

4.2DML

导入数据:

LOAD DATA  INPATH  ‘文件地址'  OVERWRITE INTO TABLE表名;

 

4.3SQL

SELECTS and FILTERS

SELECT a.foo FROM invites a WHEREa.ds='2008-08-15';

ORDER BY

SELECT a.foo FROM invites a ORDER BY a.dsdesc/asc

INSERT OVERWRITETABLE表名

[PARTITION(..)]

select语句

GROUP BY

FROM invites a INSERT OVERWRITE TABLEevents SELECT a.bar, count(*) WHERE a.foo > 0 GROUP BY a.bar;

JOIN

FROM pokes t1 JOIN invites t2 ON (t1.bar =t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo;

 

多表插入:

From源表名

Insert OVERWRITE table表1名select字句1

Insert OVERWRITE table表2名select字句2

Insert OVERWRITE table表3名select字句3

子查询:

Select * from (select * from … where. …) twhere t.name=’zhangsan’

视图:

Create view 视图名称

As select语句

5用户定义函数

如果你写的HIVEQL无法满足要求,可以使用HIVE的内置函数来解决。也成为用户定义函数Hive有三种UDF普通UDF,UDAF用户定义聚集函数 UDTF用户定义表生成函数

编写用户定义函数UDF

必须继承UDF,实现evaluate()方法

package com.quickjob;

 

import org.apache.commons.lang.StringUtils;

import org.apache.hadoop.hive.ql.exec.UDF;

import org.apache.hadoop.io.Text;

 

 

public classStrip extendsUDF {

    private Textresult=new Text();

    public Text evaluate(Textstr){

        if(str==null)

            return null;

        result.set(StringUtils.strip(str.toString()));

        returnresult;

    }

}

打包以后拖到hive_home目录下Hive命令行下加入

ADD JAR/home/hadoop/hive-0.9.0-bin/hadoop-utill-0.0.1-SNAPSHOT.jar

为JAVA类增加别名

CreateTEMPORARY FUNCTION strip AS ‘com.quickjob. Strip’

使用

selectstrip('asdsa') from pokes

 

编写UDAF需要继承 UADF,并且实现5个方法

init(),iterate,terminatePartial,merge,terminate

 

打包以后拖到hive_home目录下Hive命令行下加入

ADD JAR/home/hadoop/hive-0.9.0-bin/hadoop-utill-0.0.1-SNAPSHOT.jar;

CreateTEMPORARY FUNCTION maxnum AS ‘com.quickjob.TestUDAF’;

Select maxnum(foo)from pokes;

 

 

6JDBC链接

例子:

后台服务 ./hive --service hwi

客户端:

Class.forName("org.apache.hadoop.hive.jdbc.HiveDriver");

        Connection  con = DriverManager.getConnection("jdbc:hive://10.10.21.53:10000/default","","");

        StringquerySQL="select * from getlog t where  t.URL like '%.apk' or t.URL1 like '%.apk'or  t.URL2 like '%.apk' ;";

        Statementstmt = con.createStatement();

        ResultSetres = stmt.executeQuery(querySQL);

        while (res.next()) {

             System.out.println("Result: key:"+res.getString(1) +"??–>??value:"+res.getString(2));

        }

        return 0

原文地址:https://www.cnblogs.com/wangsongbai/p/9122828.html