hive知识大全

 

     

Hive 的产生 

Hive 产生的原因:方便非java 编程者(熟悉 SQL 语言)对 hdfs 的数据做 mapreduce操作。

Hive 是数据仓库

数据库:用户与数据库交互,提交 SQL 语句后,马上见到执行结果;存放业务数据;数据库提出范式的概念是为了解决数据冗余和耦合的问题;数据库给业务数据提供存储支撑。

数据仓库:不与用户交互;存放历史数据;反范式设计,专门引入冗余数据,保证数据完整。数据仓库面向分析,里面存放的数据用来做分析和挖掘。

Hive 将 SQL 转化为 MapReduce 可以识别的操作,承担解释器、编译器、优化器等角色

Hive 运行时,元数据(表的结构、属性)存储在关系型数据库里面。因为元数据信息需要高效的读取。

 

用户接口主要有三个:Client(命令行),JDBC/ODBC 和 WEBGUI。其中最常用的是 Client,Client 启动的时候,会同时启动一个Hive 副本。Client 是 Hive 的客户端,用户连接至 Hive Server。在启动 Client 模式的时候,需要指出 Hive Server 所在节点,并且在该节点启动 Hive Server。 WEB GUI 是通过浏览器访问 Hive。

        Hive将元数据存储在数据库中,如 mysql、derby。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。

解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及

查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce调用执行。编译器将一个 Hive QL 转换操作符,操作符是 Hive 的最小的处理单元每个操作符代表 HDFS 的一个操作或者一道 MapReduce 作业。

Operator 是 hive 定义的一个处理过程,是一个树形结构:

protected List<Operator<?  extends Serializable>> childOperators;  protected List<Operator<?  extends Serializable>> parentOperators;  protectedboolean done; // 初始化值为false

Hive 的数据存储在 HDFS中,大部分的查询、计算由 MapReduce 完成(包含*的查询,比如 select * from tbl 不会生成 MapRedcue任务)。

 

Hive 语法解析

ANTLR词法语法分析工具解析 HQL

 

Hive 的三种模式

Local 模式

此模式连接到一个In-memory 的数据库 Derby,一般用于 UnitTest

 

单用户模式通过网络连接到一个数据库中,是最经常使用到的模式。

 多用户模式

远程服务器模式。用于非 Java 客户端访问元数据库,在服务器端启动

MetaStoreServer,客户端利用 Thrift协议通过 MetaStoreServer 访问元数据库。

 

Linux 下安装 MySQL

1.     yum 安装mysql

[root@node01 ~]# yum install mysql-server

2.     启动 mysqld服务

[root@node01 ~]# service mysqld start

3. 修改 mysql修改权限

[root@node01 ~]# mysql mysql> show databases; mysql> use mysql; mysql> show tables; mysql> select host,user from user;

+------------------+------+

| host       | user |

+------------------+------+

| 127.0.0.1   | root |

| localhost   |    |

| localhost   | root |

| node01    |    |

| node01    | root |

+-----------------+-------+

mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION; mysql> select host,user from user;

+--------------+------+

| host      | user |

+--------------+------+

| %       | root | | 127.0.0.1 | root |

| localhost |     |

| localhost | root | | node01  |    |

| node01  | root |

+---------------+------+

mysql> delete from mysql.user where host != '%'; mysql> flush privileges;

4.重新登录 mysql

[root@node01 ~]# mysql -u root -p

Hive 安装

本地模式(derby)

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

<?xml version="1.0"?>  

<?xml-stylesheettype="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 'metast ore_db',see the next exception for details.  

NestedThrowables:  

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

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


单用户模式(mysql)

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

<?xml version="1.0"?>  

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

  

<configuration>  

<!-- hive_remote 是数据库名称,同时安装不同的模式,连接的数据库要不同-->

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

多用户模式

Remot 一体

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

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

<?xml version="1.0"?>  

<?xml-stylesheettype="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 的服务端和客户端都放在同一台服务器上了。服务端和客户端可以拆开。

Remot 分开

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

 

服务端配置文件

<?xml version="1.0"?>  

<?xml-stylesheettype="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>  

客户端配置文件

<?xml version="1.0"?>  

<?xml-stylesheettype="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>  

安装单用户模式具体步骤

1. 解压 hive 包

[root@node02 sxt]# tar xf apache-hive-1.2.1-bin.tar.gz

2.     配置环境变量

[root@node02 sxt]# vi + /etc/profile

export HIVE_PREFIX=/opt/sxt/apache-hive-1.2.1-bin export

PATH=$JAVA_HOME/bin:$PATH:$HADOOP_PREFIX/bin:$HADOOP_PREFIX/sbin:$ZOOKEEPER_ PREFIX/bin:$HIVE_PREFIX/bin

[root@node02 apache-hive-1.2.1-bin]# . /etc/profile

3.     修改配置文件

[root@node02 sxt]# cd apache-hive-1.2.1-bin/conf

[root@node02 conf]# cp hive-default.xml.templatehive-site.xml

[root@node02 conf]# vi hive-site.xml

<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://node01/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>root</value>

</property>  

   

<property>

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

   <value>123456</value>

</property>

 

</configuration>

4.JDBC驱动包放到 Hive lib 目录下

5. 让 hadoop 的 jline 包和 hive 的 jline 包版本保持一致(高版本替换低版本)

[root@node02 conf]# cd /opt/sxt/apache-hive-1.2.1-bin/lib

[root@node02 conf]# cp jline-2.12.jar/opt/sxt/hadoop-2.6.5/share/hadoop/yarn/lib/

[root@node02 conf]# cd/opt/sxt/hadoop-2.6.5/share/hadoop/yarn/lib/

[root@node02 lib]# rm -f jline-0.9.94.jar

6. 启动 Hive

[root@node02 lib]# hive hive> 客户端启动的时候要注意:

[ERROR] Terminal initialization failed;falling back to unsupported java.lang.IncompatibleClassChangeError: Found classjline.Terminal, but interface was expected   atjline.TerminalFactory.create(TerminalFactory.java:101)

错误的原因: Hadoop jline 版本和 hive 的 jline 不一致

一些简单的操作

hive> create table table01 (id int, name string);hive> show tables; hive> desc table01; hive> insert into table01values(1,'Jed');

 

安装多用户模式具体步骤

角色划分

mysql

MetaStoreServer

Hive 客户端

node01

 

 

node03

 

 

node04

 

 

1. 将 hive 文件夹 copy到 node03、node04

[root@node02 sxt]# scp -r apache-hive-1.2.1-binnode03:`pwd`

[root@node02 sxt]# scp -r apache-hive-1.2.1-binnode04:`pwd`

2. 把 node02的环境变量配置文件 copy 到 node03、node04

[root@node02 sxt]# scp /etc/profile node03:/etc/

[root@node02 sxt]# scp /etc/profile node03:/etc/

[root@node03 ~]# . /etc/profile

[root@node04 ~]# . /etc/profile

3.修改 node03(客户端)的hive 的配置文件

[root@node03 conf]# vi hive-site.xml

<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://node04:9083</value>

</property>

  

</configuration>

4.     修改node04(服务端)的配置文件

[root@node04 conf]# vi hive-site.xml

<configuration> 

  

<property>  

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

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

</property>  

   

<property>  

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

    <value>jdbc:mysql://node01: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>

5.     使node03 node04 jline 包和 hadoop 包保持版本一致

6. 启动 hive 服务端

[root@node04 lib]# hive --service metastore

7.启动客户端

[root@node03 lib]# hive

注意:mysql 驱动包放置在服务器端,jline 放置在客户端

Hive 的数据类型

primitive_type:

array_type map_typestruct_type

TINYINT、SMALLINT、INT、BIGINT、BOOLEAN、FLOAT、DOUBLE、STRING

DDL(DataDefinition Language)

Create Database

CREATE (DATABASE|SCHEMA) [IF NOT EXISTS]database_name

 [COMMENT database_comment]

 [LOCATION hdfs_path]

 [WITH DBPROPERTIES (property_name=property_value, ...)];

DropDatabase

DROP (DATABASE|SCHEMA) [IF EXISTS]database_name [RESTRICT|CASCADE];

Alter Database

ALTER (DATABASE|SCHEMA) database_name SETDBPROPERTIES

(property_name=property_value,...);   -- (Note: SCHEMA added in Hive0.14.0)  

ALTER (DATABASE|SCHEMA) database_name SETOWNER [USER|ROLE] user_or_role;   --(Note: Hive 0.13.0 and later; SCHEMA added in Hive 0.14.0)

Use Database

USE database_name;

USE DEFAULT;

CreateTable

CREATE [TEMPORARY] [EXTERNAL] TABLE [IFNOT EXISTS] [db_name.]table_name    --(Note:

TEMPORARY available in Hive 0.14.0 andlater)

 [(col_name data_type [COMMENT col_comment], ...[constraint_specification])]

 [COMMENT table_comment]

 [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]

 [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC],...)] INTO num_buckets BUCKETS]

 [SKEWED BY (col_name, col_name, ...)                  -- (Note: Available in Hive0.10.0 and later)]

    ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)

    [STORED AS DIRECTORIES]

  [

  [ROW FORMAT row_format] 

   [STOREDAS file_format]

    | STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES(...)]  -- (Note:

Available in Hive 0.6.0 and later)

  ]

 [LOCATION hdfs_path]

 [TBLPROPERTIES (property_name=property_value, ...)]   -- (Note: Available in Hive 0.6.0 and later)

 [AS select_statement];   -- (Note:Available in Hive 0.5.0 and later; not supported for external tables)

 

CREATE [TEMPORARY] [EXTERNAL] TABLE [IFNOT EXISTS] [db_name.]table_name

 LIKE existing_table_or_view_name

 [LOCATION hdfs_path];

 data_type   : primitive_type

  |array_type

  |map_type

  |struct_type

  |union_type  -- (Note: Available in Hive0.7.0 and later)

 primitive_type   : TINYINT

  |SMALLINT

  |INT

  |BIGINT

  |BOOLEAN

  |FLOAT

  |DOUBLE

  |DOUBLE PRECISION -- (Note: Available in Hive 2.2.0 and later)

  |STRING

  |BINARY      -- (Note: Available in Hive0.8.0 and later)

  |TIMESTAMP   -- (Note: Available in Hive0.8.0 and later)

  |DECIMAL     -- (Note: Available in Hive0.11.0 and later)

  |DECIMAL(precision, scale)  -- (Note:Available in Hive 0.13.0 and later)

  |DATE        -- (Note: Available in Hive0.12.0 and later)

  |VARCHAR     -- (Note: Available in Hive0.12.0 and later)

  |CHAR        -- (Note: Available in Hive0.13.0 and later)

 array_type

  :ARRAY < data_type >

 

map_type

  :MAP < primitive_type, data_type >

 struct_type

  :STRUCT < col_name : data_type [COMMENT col_comment], ...>

 union_type

   :UNIONTYPE < data_type, data_type, ... > -- (Note: Available in Hive 0.7.0 and later)

 

row_format

  :DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS

TERMINATED BY char]

       [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char(换行符,默认'\n')]

        [NULL DEFINED AS char]   -- (Note: Available in Hive 0.13 andlater)   | SERDE serde_name [WITHSERDEPROPERTIES (property_name=property_value, property_name=property_value,...)]

 file_format:

  :SEQUENCEFILE

  |TEXTFILE    -- (Default, depending on hive.default.fileformatconfiguration)

  |RCFILE      -- (Note: Available in Hive0.6.0 and later)

  |ORC         -- (Note: Available in Hive0.11.0 and later)

  |PARQUET     -- (Note: Available in Hive0.13.0 and later)

  |AVRO        -- (Note: Available in Hive0.14.0 and later)

  |INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname

 constraint_specification:

  :[, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE ]

[, CONSTRAINTconstraint_name FOREIGN KEY (col_name, ...) REFERENCES table_name(col_name,...) DISABLE NOVALIDATE

例子

人员表

id、name、hobbyies、address

1,Jed,book-lol-game,beijing:haidian-shanghai:pudong 2,Tom,book-lol-lanqiu,beijing:xisanqi-shanghai:lujiazui

内部表:数据存放在配置文件指定的目录下,删除内部表后,其中的数据也会删除

<property>  

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

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

</property>

create table person0 ( id int,

name string, hobbies ARRAY<string>, address MAP<string,string>

)

ROW FORMAT DELIMITED 

FIELDS TERMINATED BY ','  #字段之间用','分隔

COLLECTION ITEMS TERMINATED BY '-'  #数组元素之间用'-'分隔

MAP KEYS TERMINATED BY ':';  #Map 元素之间用':'分隔

外部表:数据存放在建表时自定义的路径下,删除外部表后,其中的数据没有被删除,只是删除了元数据

create EXTERNAL table person1 ( id int,

name string, likes ARRAY<string>, address MAP<string,string>

)

ROW FORMAT DELIMITED 

FIELDS TERMINATED BY ','  

COLLECTION ITEMSTERMINATED BY '-' 

MAP KEYSTERMINATED BY ':'

LOCATION'/user/root/person1';

create tableperson2 as select id, hobbies from person0; #MapReduce

create tableperson3 like person0;  #不是 MapReduce任务

Loading files into tables

LOAD DATA [LOCAL] INPATH 'filepath'[OVERWRITE] INTO TABLE tablename [PARTITION

(partcol1=val1, partcol2=val2 ...)]

load data localinpath '/tmp/data/person0_data' into table person0;

分区

分区:分区的字段不能是表中已有的字段

create table person4 ( id int,

name string, likes ARRAY<string>, address MAP<string,string>

)

PARTITIONED BY (sex string)

ROW FORMAT DELIMITED 

FIELDS TERMINATED BY ','  

COLLECTION ITEMS TERMINATED BY '-' 

MAP KEYS TERMINATED BY ':';

load data local inpath '/tmp/data/person0_data' into table person4 PARTITION (sex='1'); load data local inpath '/tmp/data/person0_data' into table person4 PARTITION (sex='2');

 

hive> select *from person4;

1          Jed ["book","lol"]{"beijing":"chaoyang"} 1

2          Tom["book","lol","sports"] {"beijing":"chaoyang","shanghai":"pudong"}1

3          Cat["book","lol","sports","music"]

         {"beijing":"chaoyang","shanghai":"pudong","shanxi":"taiyuan"}1

1          Jed["book","lol"] {"beijing":"chaoyang"} 2

2          Tom["book","lol","sports"] {"beijing":"chaoyang","shanghai":"pudong"}2

3        Cat ["book","lol","sports","music"]

 {"beijing":"chaoyang","shanghai":"pudong","shanxi":"taiyuan"} 2 hive> select * from person4 where sex="1";

1           Jed ["book","lol"] {"beijing":"chaoyang"} 1

2           Tom ["book","lol","sports"]    {"beijing":"chaoyang","shanghai":"pudong"} 1

3           Cat ["book","lol","sports","music"]

         {"beijing":"chaoyang","shanghai":"pudong","shanxi":"taiyuan"} 1

create table person6 ( id int,

name string, likes ARRAY<string>, address MAP<string,string>

)

PARTITIONED BY (sex string, age int)

ROW FORMAT DELIMITED 

FIELDS TERMINATED BY ','  

COLLECTION ITEMS TERMINATED BY '-' 

MAP KEYS TERMINATED BY ':';

hive> load data local inpath '/tmp/data/person6_data' into table person6 PARTITION

(sex='1',age=18); hive> load data local inpath '/tmp/data/person6_data' into table person6 PARTITION

(sex='2',age=18); hive> load data local inpath '/tmp/data/person6_data' into table person6 PARTITION (sex='3',age=20);

添加/删除分区,内部表删除分区后该分区下的数据也会被删除,外部表删除分区后该分区下的数据不会被删除

ALTER TABLE person4 add PARTITION (sex='3');

ALTER TABLE person6 drop PARTITION (sex='1',age=18);

ALTER TABLE person6 drop PARTITION (sex='2');#会删除 sex='2'和 age=18

ALTER TABLE person4 drop PARTITION (age=20); #会删除 sex='3'和 age=20

DML(DataManipulation Language)

load data inpath 'hdfs path' into tabletable_name 

这个操作实际是把 hdfs path 下的文件移动到了 hive 配置的存放的数据的目录下

load data local inpath 'hdfs path' intotable table_name

这个操作实际是把本地的文件上传到 hdfs 的临时目录下,然后把该文件移动到了 hive 配置的存放的数据的目录下多次load 相同的文件,数据会追加,而不是覆盖

hive> create table person7 like person0;

常用于分析某张表,把结果放入另一张表 from log insert into table result select …… hive> from person0

    > insert into table person7

> select id,name,hobbies,address;

使用 Beeline 连接 Hive

服务端启动 hiveserver2

[root@node04 ~]# hiveserver2

  

客户端进入 beeline 并连接

[root@node03 ~]# beeline

Beeline version 1.2.1 by Apache Hive beeline> !connect jdbc:hive2://node04:10000

Connecting to jdbc:hive2://node04:10000

Enter username for jdbc:hive2://node04:10000: root

Enter password for jdbc:hive2://node04:10000: ******

Connected to: Apache Hive (version 1.2.1)

Driver: Hive JDBC (version 1.2.1)

Transaction isolation: TRANSACTION_REPEATABLE_READ

0: jdbc:hive2://node04:10000>

退出连接

0: jdbc:hive2://node04:10000> !quit

另一种连接方法

[root@node03 ~]# beeline -u jdbc:hive2//node04:10000 -nroot

Hive JDBC

项目依赖包:hive 安装包 lib 根目录下所有包,hadoop项目依赖的包

package com.sxt.hive.jdbc;

 import java.sql.SQLException;

import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.sql.DriverManager;

public class HiveJDBC {      private static String driverName =

"org.apache.hive.jdbc.HiveDriver";

     public static void main(String[] args) throws SQLException {

         try {

              Class.forName(driverName);          } catch (ClassNotFoundException e) {               e.printStackTrace();

              System.exit(1);

         }

          

         Connection conn = DriverManager.getConnection(

            "jdbc:hive2://node04:10000/default", "root", "");

          

         Statement stmt = conn.createStatement();

          

         String sql = "select * from person7 limit 5";          ResultSet res = stmt.executeQuery(sql);          while (res.next()) {

              //输出第1列和name那一列

              System.out.println(res.getString(1) 

+ "-" 

+ res.getString("name"));

         }

     } }

Regex

数据:

192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-upper.png HTTP/1.1" 304 - 192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-button.png HTTP/1.1" 304 -

192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217

SQL:

CREATE TABLE log ( host STRING, identity STRING,

t_user STRING, time STRING, request STRING, referer STRING, agent STRING

)

ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'

WITH SERDEPROPERTIES (

"input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) \\[(.*)\\] \"(.*)\" (-|[0-9]*) (-|[0-9]*)"

)

STORED AS TEXTFILE;

load data local inpath "/tmp/data/log.txt" into table log;

hive> select * from log;

192.168.57.4 - - 29/Feb/2016:18:14:35 +0800 GET /bg-upper.png HTTP/1.1 304 - 192.168.57.4 - - 29/Feb/2016:18:14:35 +0800 GET /bg-button.png HTTP/1.1 304 -

192.168.57.4 -         -       29/Feb/2016:18:14:36 +0800 GET / HTTP/1.1        200 11217

ROW FORMAT 不会破坏原数据的结构

函数

内置运算符关系运算符

运算符

类型

说明

A = B

所有原始类型

如果 A 与 B 相等,返回 TRUE,否则返回 FALSE

A == B

失败,因为无效的语法。 SQL 使用“=”,不使用

“==”。

A <> B

所有原始类型

如果 A 不等于 B 返回 TRUE,否则返回 FALSE。如果 A 或 B 值为“NULL”,结果返回“NULL”。

A < B

所有原始类型

如果 A 小于 B 返回 TRUE,否则返回 FALSE。如果 A 或 B 值为“NULL”,结果返回“NULL”。

A <= B

所有原始类型

如果 A 小于等于 B 返回 TRUE,否则返回 FALSE。如果 A 或 B 值为“NULL”,结果返回“NULL”。

A > B

所有原始类型

如果 A 大于 B 返回 TRUE,否则返回 FALSE。如果 A 或 B 值为“NULL”,结果返回“NULL”。

A >= B

所有原始类型

如果 A 大于等于 B 返回 TRUE,否则返回 FALSE。如果 A 或 B 值为“NULL”,结果返回“NULL”。

A IS NULL

所有类型

如果 A 值为“NULL”,返回 TRUE,否则返回 FALSE

A IS NOT

NULL

所有类型

如果 A 值不为“NULL”,返回 TRUE,否则返回 FALSE

A LIKE B

字符串

如果 A 或 B 值为“NULL”,结果返回”NULL”。

字符串 A 与 B 通过 sql 进行匹配,如果相符返回 TRUE,不符返回 FALSE。

B 字符串中 的“_”代表任一字符,“%”则代表多个任意

字符。例如: ("foobar " like "foo ")返回 FALSE,("foobar " like "foo_ _ _ "或者"foobar " like "foo% ")则返回 TURE

A RLIKE B

字符串

如果 A 或 B 值为“NULL”,结果返回”NULL”。

字符串 A 与 B 通过 java 进行匹配,如果相符返回 TRUE,

不符返回 FALSE。例如:("foobar " rlike "foo ")返回 FALSE,

("foobar " rlike "^f.*r$ ")返回 TRUE。

A REGEXP

B

字符串

与 RLIKE 一样

算数运算符

运算符

类型

说明

A + B

所有数字类型

A 和 B 相加。结果的与操作数值有共同类型。例如每一个整数是一个浮点数,浮点数包含整数。所以,一个浮点数和一个整数相加结果也是一个浮点数。

A – B

所有数字类型

A 和 B 相减。结果的与操作数值有共同类型。

A * B

所有数字类型

A 和 B 相乘,结果的与操作数值有共同类型。需要说明的是,如果乘法造成溢出,将选择更高的类型。

A / B

所有数字类型

A 和 B 相除,结果是一个 double(双精度)类型的结果。

A % B

所有数字类型

A 除以 B 余数与操作数值有共同类型。

A & B

所有数字类型

运算符查看两个参数的二进制表示法的值,并执行按位

“与”操作。两个表达式的一位均为 1 时,则结果的该位为 1。否则,结果的该位为 0。

A|B

所有数字类型

运算符查看两个参数的二进制表示法的值,并执行按位

“或”操作。只要任一表达式的一位为 1,则结果的该位为 1。否则,结果的该位为 0。

A ^ B

所有数字类型

运算符查看两个参数的二进制表示法的值,并执行按位 “异或”操作。当且仅当只有一个表达式的某位上为 1 时,结果的该位才为 1。否则结果的该位为 0。

~A

所有数字类型

对一个表达式执行按位“非”(取反)。

逻辑运算符

运算符

类型

说明

A AND B

布尔值

A 和 B 同时正确时,返回 TRUE,否则 FALSE。如果 A 或 B 值为 NULL,返回 NULL。

A && B

布尔值

与“A AND B”相同

A OR B

布尔值

A 或 B 正确,或两者同时正确返返回 TRUE,否则 FALSE。如果

A 和 B 值同时为 NULL,返回 NULL。

A | B

布尔值

与“A OR B”相同

NOT A

布尔值

如果 A 为 NULL 或错误的时候返回 TURE,否则返回

FALSE。

! A

布尔值

与“NOT A”相同

复杂类型函数

函数

类型

说明

map

(key1, value1, key2, value2, …)

通过指定的键/值对,创建一个 map。

struct

(val1, val2, val3, …)

通过指定的字段值,创建一个结构。结构字段名称将 COL1,COL2,…

array

(val1, val2, val3, …)

通过指定的元素,创建一个数组。

对复杂类型函数操作

函数

类型

说明

A[n]

A 是一个数组,n 为 int 型

返回数组 A 的第 n 个元素,第一个元素的索引为 0。如果

A 数组为['foo','bar'],则 A[0]返回'foo'和 A[1]返回'bar'。

M[key]

M 是 Map<K, V>,关键 K 型

返回关键值对应的值,例如 mapM 为 \{'f' -> 'foo', 'b' ->

'bar', 'all' -> 'foobar'\},则 M['all'] 返回'foobar'。

S.x

S 为 struct

返回结构 x 字符串在结构 S 中的存储位置。如 foobar

\{int foo, int bar\} foobar.foo 的领域中存储的整数。

内置函数数学函数

返回类型

函数

说明

BIGINT

round(double a)

四舍五入

DOUBLE

round(double a, int d)

小数部分 d 位之后数字四舍五入,例如

round(21.263,2),返回 21.26

BIGINT

floor(double a)

对给定数据进行向下舍入最接近的整数。例如 floor(21.2),返回 21。

BIGINT

ceil(double a),  ceiling(double a)

将参数向上舍入为最接近的整数。例如 ceil(21.2),返回 23.

double

rand(), rand(int seed)

返回大于或等于 0 且小于 1 的平均分布随机数(依重新计算而变)

double

exp(double a)

返回 e 的 n 次方

double

ln(double a)

返回给定数值的自然对数

double

log10(double a)

返回给定数值的以 10 为底自然对数

double

log2(double a)

返回给定数值的以 2 为底自然对数

double

log(double base, double a)

返回给定底数及指数返回自然对数

double

pow(double a, double p) power(double a, double p)

返回某数的乘幂

double

sqrt(double a)

返回数值的平方根

string

bin(BIGINT a)

返回二进制格式

string

hex(BIGINT a)  hex(string a)

将整数或字符转换为十六进制格式

string

unhex(string a)

十六进制字符转换由数字表示的字符。

string

conv(BIGINT num, int from_base, int to_base)

将 指定数值,由原来的度量体系转换为指定

的试题体系。例如 CONV(‘a’,16,2),返回。参考:’1010′ http://dev.mysql.com/doc/refman/5.0/en/mat hematical-functions.html#function_conv

double

abs(double a)

取绝对值

int double

pmod(int a, int b)  pmod(double a, double b)

返回 a 除 b 的余数的绝对值

double

sin(double a)

返回给定角度的正弦值

double

asin(double a)

返回 x 的反正弦,即是 X。如果 X 是在-1 到 1 的正弦值,返回 NULL。

double

cos(double a)

返回余弦

double

acos(double a)

返回 X 的反余弦,即余弦是 X,,如果-1<= A

<= 1,否则返回 null.

int double

positive(int a)  positive(double a)

返回 A 的值,例如 positive(2),返回 2。

int double

negative(int a)  negative(double a)

返回 A 的相反数,例如 negative(2),返回-2。

收集函数

返回类型

函数

说明

int

size(Map<K.V>)

返回的 map 类型的元素的数量

int

size(Array<T>)

返回数组类型的元素数量

类型转换函数

返回类型

函数

说明

指定 “type”

cast(expr as <type>)

类型转换。例如将字符”1″转换为整数:cast(’1′ as bigint),如果转换失败返回 NULL。

日期函数

返回类型

函数

说明

string

from_unixtime(bigint unixtime[, string format])

UNIX_TIMESTAMP 参数表示返回一个值’YYYY- MM – DD HH: MM:SS’或 YYYYMMDDHHMMSS.uuuuuu 格式,这取决于是否

是在一个字符串或数字语境中使用的功能。该值表示在当前的时区。

bigint

unix_timestamp()

如果不带参数的调用,返回一个 Unix 时间戳(从’1970- 01 –

0100:00:00′到现在的 UTC 秒数)为无符号整数。

bigint

unix_timestamp(string date)

指定日期参数调用 UNIX_TIMESTAMP(),它返回参数值’1970- 01 – 0100:00:00′到指定日期的秒数。

bigint

unix_timestamp(string date, string pattern)

指定时间输入格式,返回到 1970 年秒数:

unix_timestamp(’2009-03-20′, ‘yyyy-MM-dd’) = 1237532400 

string

to_date(string timestamp)

返回时间中的年月日: to_date(“1970-01-01 00:00:00″) =

“1970-01-01″

string

to_dates(string date)

给定一个日期 date,返回一个天数(0 年以来的天数)

int

year(string date)

返回指定时间的年份,范围在 1000 到 9999,或为”零”日期的

0。

int

month(string date)

返回指定时间的月份,范围为 1 至 12 月,或 0 一个月的一部分,如’0000-00-00′或’2008-00-00′的日期。

int

day(string date) dayofmonth(date)

返回指定时间的日期

int

hour(string date)

返回指定时间的小时,范围为 0 到 23。

int

minute(string date)

返回指定时间的分钟,范围为 0 到 59。

int

second(string date)

返回指定时间的秒,范围为 0 到 59。

int

weekofyear(string date)

返回指定日期所在一年中的星期号,范围为 0 到 53。

int

datediff(string enddate, string startdate)

两个时间参数的日期之差。

int

date_add(string startdate, int days)

给定时间,在此基础上加上指定的时间段。

int

date_sub(string startdate, int days)

给定时间,在此基础上减去指定的时间段。

条件函数

返回类型

函数

说明

T

if(boolean testCondition,

T valueTrue, 

T valueFalseOrNull)

判断是否满足条件,如果满足返回一个值,如果不满足则返回另一个值。

T

COALESCE(T v1, T v2, …)

返回一组数据中,第一个不为 NULL 的值,如果均为 NULL,返回 NULL。

T

CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END

当 a=b 时,返回 c;当 a=d 时,返回 e,否则返回 f。

T

CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END

当值为 a 时返回 b,当值为 c 时返回 d。否则返回 e。

字符函数

返回类型

函数

说明

int

length(string A)

返回字符串的长度

string

reverse(string A)

返回倒序字符串

string

concat(string A, string B…)

连接多个字符串,合并为一个字符串,可以接受任意数量的输入字符串

string

concat_ws(string SEP, string A, string B…)

链接多个字符串,字符串之间以指定的分隔符分开。

string

substr(string A, int start) substring(string A, int start)

从文本字符串中指定的起始位置后的字符。

string

substr(string A, int start, int len) substring(string A, int start, int len)

从文本字符串中指定的位置指定长度的字符。

string

upper(string A) ucase(string A)

将文本字符串转换成字母全部大写形式

string

lower(string A) lcase(string A)

将文本字符串转换成字母全部小写形式

string

trim(string A)

删除字符串两端的空格,字符之间的空格保留

string

ltrim(string A)

删除字符串左边的空格,其他的空格保留

string

rtrim(string A)

删除字符串右边的空格,其他的空格保留

string

regexp_replace(string A, string

B, string C)

字符串 A 中的 B 字符被 C 字符替代

string

regexp_extract(string subject, string pattern, int index)

通过下标返回正则表达式指定的部分。

regexp_extract(‘foothebar’, ‘foo(.*?)(bar)’,

2) returns ‘bar.’

string

parse_url(string urlString, string partToExtract [, string keyToExtract])

返回 URL 指定的部分。

parse_url(‘http://facebook.com/path1/p.ph p?k1=v1&k2=v2#Ref1′, ‘HOST’) 返回:’facebook.com’

string

get_json_object(string json_string, string path)

select a.timestamp, get_json_object(a.appevents, ‘$.eventid’), get_json_object(a.appenvets, ‘$.eventname’) from log a;

string

space(int n)

返回指定数量的空格

string

repeat(string str, int n)

重复 N 次字符串

int

ascii(string str)

返回字符串中首字符的数字值

string

lpad(string str, int len, string pad)

返回指定长度的字符串,给定字符串长度

小于指定长度时,由指定字符从左侧填补。

string

rpad(string str, int len, string pad)

返回指定长度的字符串,给定字符串长度

小于指定长度时,由指定字符从右侧填补。

array

split(string str, string pat)

将字符串转换为数组。

int

find_in_set(string str, string strList)

返回字符串 str 第一次在 strlist 出现的位

置。如果任一参数为 NULL,返回 NULL;如果第一个参数包含逗号,返回 0。

array<array

<string>>

sentences(string str, string lang, string locale)

将字符串中内容按语句分组,每个单词间以逗号分隔,最后返回数组。 例如

sentences(‘Hello there! How are you?’) 返

回:( (“Hello”, “there”), (“How”, “are”,

“you”) )

array<struct <string,dou ble>>

ngrams(array<array<string>>, int N, int K, int pf)

SELECT ngrams(sentences(lower(tweet)), 2,

100 [, 1000]) FROM twitter;

array<struct <string,dou ble>>

context_ngrams(array<array<str ing>>, array<string>, int K, int pf)

SELECT context_ngrams(sentences(lower(tweet)), array(null,null), 100, [, 1000]) FROM twitter;

内置的聚合函数(UDAF

返回类型

函数

说明

bigint

count(*) , count(expr), count(DISTINCT expr[, expr_., expr_.])

返回记录条数。

double

sum(col), sum(DISTINCT col)

求和

double

avg(col), avg(DISTINCT col)

求平均值

double

min(col)

返回指定列中最小值

double

max(col)

返回指定列中最大值

double

var_pop(col)

返回指定列的方差

double

var_samp(col)

返回指定列的样本方差

double

stddev_pop(col)

返回指定列的偏差

double

stddev_samp(col)

返回指定列的样本偏差

double

covar_pop(col1, col2)

两列数值协方差

double

covar_samp(col1, col2)

两列数值样本协方差

double

corr(col1, col2)

返回两列数值的相关系数

double

percentile(col, p)

返回数值区域的百分比数值点。0<=P<=1,否则返回 NULL,不支持浮点型数值。

array<double>

percentile(col, array(p~1,,\ [, p,,2,,]…))

返回数值区域的一组百分比值分别对应的数值点。0<=P<=1,否则返回 NULL,不支持浮点型数值。

double

percentile_approx(col

, p[, B])

Returns an approximate p^th^ percentile of a numeric column (including floating point types) in the group. The B parameter controls approximation accuracy at the cost of memory. Higher values yield better approximations, and the default is 10,000. When the number of distinct values in col is smaller than B, this gives an exact percentile value.

array<double>

percentile_approx(col

, array(p~1,, [, p,,2_]…) [, B])

Same as above, but accepts and returns an array of percentile values instead of a single one.

array<struct\{‘x

’,'y’\}>

histogram_numeric(c

ol, b)

Computes a histogram of a numeric column in the group using b non-uniformly spaced bins. The output is an array of size b of double-valued (x,y) coordinates that represent the bin centers and heights

array

collect_set(col)

返回无重复记录

内置表生成函数(UDTF

返回类型

函数

说明

数组

explode(array<TYPE>

a)

数组一条记录中有多个参数,将参数拆分,每个参数生成一列。

 

json_tuple

get_json_object 语句:select a.timestamp, get_json_object(a.appevents, ‘$.eventid’), get_json_object(a.appenvets, ‘$.eventname’) from log a; json_tuple 语句: select a.timestamp, b.* from log a lateral view json_tuple(a.appevent,

‘eventid’, ‘eventname’) b as f1, f2

自定义函数

自定义函数包括三种UDF、UDAF、UDTF

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

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

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

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

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

3)        步骤

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

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

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

d)       查询 HQL 语句:

   SELECT add_example(8, 9) FROM scores;

   SELECT add_example(scores.math, scores.art) FROM scores;

   SELECT add_example(6, 7, 8, 6.8) FROM scores;

e)        销毁临时函数:hive> DROP TEMPORARY FUNCTIONadd_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 需要实现init、iterate、terminatePartial、merge、terminate 这几个函数 init():类似于构造函数,用于 UDAF 的初始化 iterate():接收传入的参数,并进行内部的轮转,返回 boolean terminatePartial():无参数,其为 iterate函数轮转结束后,返回轮转数据,类似于 hadoop 的Combiner

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

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

3)               开发一个功能同:

Oracle 的 wm_concat()函数 Mysql的 group_concat()

Hive UDF 的数据类型

  案例-输出数据时部分内容显示为“*

package com.sxt.hive.udf;

import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; public class TestUDF extends UDF{

     //输出信息时部分内容用*代替

     public Text evaluate(final Text s) {          if (s == null) {               return null;

         }

         String str = s.toString().substring(0, 3) + "***";          return new Text(str);

     }

}

步骤:

1.         打成 jar 包

2.         上传到 Hive 客户端

3.         hive> add jar /root/TestUDF.jar;

Added [/root/TestUDF.jar] to class path

Added resources: [/root/TestUDF.jar]

4.         hive> CREATE TEMPORARY FUNCTION display AS 'com.sxt.hive.udf.TestUDF'; hive> select id,name,display(name) from person0;

OK

1           Jed Jed***

2           Tom Tom***

3           Cat Cat***

5. 销毁临时函数

hive> DROP TEMPORARY FUNCTION display;

案例

基站掉话率给定 50M 数据,部分数据如下:  字段说明:

record_time:通话时间imei:基站编号 cell:手机编号 drop_num:掉话的秒数

duration:通话持续总秒数要求:找出掉线率最高的前 10 基站

hive>create table cell_monitor( record_time string, imei string, cell string,

ph_num int, call_num int, drop_num int, duration int, drop_rate double, net_type string, erl string

)

ROW FORMAT DELIMITED FIELDS TERMINATED BY ','

STORED AS TEXTFILE;

hive>load data local inpath "/root/hivecase1_data" into table cell_monitor;

hive>select * from cell_monitor limit 5;

2011-07-13 00:00:00+08 356966      29448-37062 0       0      0      0            0.0 G

0

2011-07-13 00:00:00+08 352024      29448-51331 0       0      0      0            0.0 G

0

2011-07-13 00:00:00+08353736       29448-51331 0       0      0      0       0.0 G       0

2011-07-13 00:00:00+08 353736   29448-51333 0        0      0      0      0.0 G        0 2011-07-13 00:00:00+08 351545       29448-51333 0        0      0      0      0.0 G        0

建结果表

hive>create table cell_result( imei string, total_call_num int, total_drop_num int, d_rate double

ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'

STORED AS TEXTFILE;

hive>from cell_monitor cm  insert overwrite table cell_result   select cm.imei ,sum(cm.drop_num),sum(cm.duration),sum(cm.drop_num)/sum(cm.duration) d_rate  group by cm.imei  sort by d_rate desc;

hive>select * from cell_result limit 10;

639876      1       734     0.0013623978201634877

356436      1      1028         9.727626459143969E-4

351760      1      1232         8.116883116883117E-4

368883      1      1448         6.906077348066298E-4

358849      1      1469         6.807351940095302E-4

358231      1      1613         6.199628022318661E-4

863738    2      3343        5.982650314089142E-4 865011          1      1864        5.36480686695279E-4

862242      1      1913         5.227391531625719E-4

350301      2      3998         5.002501250625312E-4

WordCount

hive>create table wordcount (line string);

hive>load data local inpath "/root/wordcount_data" into table wordcount;

hive>select * from wordcount; C C++ Java MySQL Oracle

Spring SpringMVC Hibernate 

Struts2 SpringMVC Hibernate

Hadoop Hive MapReduce Spring SpringMVC

Java MySQL Oracle C C++ Java MySQL Oracle

Struts2 SpringMVC Hibernate

Hadoop Hive MapReduce

hive> select split(line,' ') from wordcount; ["C","C++","Java","MySQL","Oracle"]

["Spring","SpringMVC","Hibernate",""]

["Struts2","SpringMVC","Hibernate"]

["Hadoop","Hive","MapReduce","Spring","SpringMVC"]

["Java","MySQL","Oracle","C","C++","Java","MySQL","Oracle"]

["Struts2","SpringMVC","Hibernate"]

["Hadoop","Hive","MapReduce"]

hive> select explode(split(line,' ')) from wordcount;

OK

C

C++

Java

MySQL

Oracle

Spring

SpringMVC

Hibernate

Struts2

SpringMVC

Hibernate

Hadoop

Hive

MapReduce

Spring

SpringMVC

Java

MySQL

Oracle

C

C++

Java

MySQL

Oracle

Struts2

SpringMVC

Hibernate

Hadoop

Hive

MapReduce

hive> createtable count_result(word string,num int);

hive> from(select explode(split(line,' ')) as word from wordcount) w insert into tablecount_result select w.word,count(1) as num group by w.word;

hive> select *from count_result;

OK

C      2

C++ 2

Hadoop 2

Hibernate        3

Hive 2

Java 3

MapReduce     2

MySQL     3

Oracle      3

Spring      2

SpringMVC      4

Struts2    2

Hive 参数和变量

hive当中的参数、变量,都是以命名空间开头

命名空间

读写权限

含义

hiveconf

可读写

hive-site.xml 当中的各配置变量

例:hive --hiveconf hive.cli.print.header=true

system

可读写

系统变量,包含 JVM 运行参数等

例:system:user.name=root

env

只读

环境变量

例:env:JAVA_HOME

hivevar

可读写

例:hive -d val=key

通过${}方式进行引用,其中 system、env 下的变量必须以前缀开头

hive 参数设置方式

1.        修改配置文件 ${HIVE_HOME}/conf/hive-site.xml

2.        启动 hive cli 时,通过--hiveconf key=value 的方式进行设置(临时生效)

例:hive --hiveconf hive.cli.print.header=true

显示表头

[root@node03 ~]#hive --hiveconf hive.cli.print.header=true hive> select * from count_resultlimit 2;

count_result.wordcount_result.num

C      2

C++ 2

临时生效

[root@node03 ~]#hive -d val=test; hive> create table ${val} (id int,name string); hive>show tables; test

3.进入 cli 之后,通过使用set 命令设置(临时生效)

hive set 命令在 hiveCLI 控制台可以通过 set 对 hive 中的参数进行查询、设置。

set 设置:

set hive.cli.print.header=true;

set 查看某个配置的值:

set hive.cli.print.header

set 查看全部配置项:         sethive 参数初始化配置文件:当前用户家目录下的.hiverc 文件,如:  ~/.hiverc,如果没有,可直接创建该文件,将

需要设置的参数写到该文件中,hive 启动运行时,会加载改文件中的配置。

hive 历史操作命令集:

~/.hivehistory

hive> set hive.cli.print.header=true; hive> select * from count_result limit 3; count_result.word count_result.num

C      2

C++ 2

hive> set hive.cli.print.header; hive.cli.print.header=true

永久生效

[root@node03 ~]# vi .hiverc set hive.cli.print.header = true;

[root@node03 ~]# tail -5 .hivehistory  select * from cell_result; select * from cell_result limit 2; select * from count_result limit 2; quit;

Hive 动态分区

建表时指出分区字段,但不给值,导入数据时 hive 根据分区字段的值自动创建分区。

开启动态分区需要修改一些配置:是否开启动态分区,默认:false

set hive.exec.dynamic.partition=true;

动态分区模式,默认:strict:严格模式,至少有一个分区列是静态分区

sethive.exec.dynamic.partition.mode=nostrict;

相关参数:每一个执行 mr 节点上,允许创建的动态分区的最大数量(100)

sethive.exec.max.dynamic.partitions.pernode;

所有执行 mr 节点上,允许创建的所有动态分区的最大数量(1000)

set hive.exec.max.dynamic.partitions;

所有的 mr job 允许创建的文件的最大数量(100000)

set hive.exec.max.created.files;

hive> set hive.exec.dynamic.partition=true; hive> set hive.exec.dynamic.partition.mode=nostrict; hive> create table part0 ( id int,

name string

)

PARTITIONED BY (sex string)

ROW FORMAT DELIMITED 

FIELDS TERMINATED BY ',';

hive> desc part0;

col_name data_type       comment id                   int                                       name               string                                    sex                  string                                                

# Partition Information            

# col_name                     data_type            comment                 sex                  string  

导入两个分区的数据

hive> load data local inpath '/root/part0_data' into table part0 PARTITION (sex='1');  hive> load data local inpath '/root/part0_data' into table part0 PARTITION (sex='2');         

hive> select * from part0; part0.id part0.name     part0.sex

1           Jed 1

2           Tom 1

3           Cat 1

1       Jed 2

2           Tom 2

3           Cat 2

创建一个和 part0 表机构完全相同的表 part1

hive> create table part1 like part0;  

给 part1 导入数据,使用动态分区

hive> from part0 insert into table part1 partition (sex)  select *;

hive> select * from part1; part1.id part1.name     part1.sex

1           Jed 1

2           Tom 1

3           Cat 1

1           Jed 2

2           Tom 2

3           Cat 2

使用动态分区导入数据时,不使用 load,因为 load 必须指定分区的值,应该使用 from+select 方式。

Hive 分桶

分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储。对于 hive 中每一

个表、分区都可以进一步进行分桶。由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中。比分区更加细粒度。

适用场景:数据抽样( sampling )、map-join

开启分桶支持:

set hive.enforce.bucketing=true;

默认:false。设置为true 之后,mr 运行时会根据 bucket 的个数自动分配 reducetask

个数。(用户也可以通过 mapred.reduce.tasks 自己设置 reduce任务个数,但分桶时不推荐使用)注意:一次作业产生的桶(文件数量)和reduce task 个数一致。

hive> sethive.enforce.bucketing=true;

创建分桶表

hive> CREATETABLE bucket(id int, name string, age int)

CLUSTERED BY(age) INTO 4 BUCKETS 

ROW FORMATDELIMITED FIELDS TERMINATED BY ',';

查看表结构(比 desc table;更详细)

hive> descformatted bucket;

7

Hadoop 77

3

Dog 33

Hive Lateral View

LateralView 用于和 UDTF 函数(explode、split)结合来使用。首先通过UDTF 函数拆分成多行,再将多行结果组合成一个支持别名的虚拟表。主要解决在 select 使用 UTF 做查询过程中,查询只能包含单个 UDTF,不能包含其他字段、以及多个UDTF 的问题。

语法:

LATERAL VIEW udtf(expression) tableAliasAS columnAlias (',' columnAlias)

hive> select * from person0; person0.id        person0.name person0.hobbies     person0.address

1           Jed ["book","lol"] {"beijing":"chaoyang"}

2           Tom ["book","lol","sports"]    {"beijing":"chaoyang","shanghai":"pudong"}

3           Cat ["book","lol","sports","music"]

         {"beijing":"chaoyang","shanghai":"pudong","shanxi":"taiyuan"}

hive> select explode(hobbies) from person0; col

book

lol

book

lol

sports book

lol

sports music

hive> select explode(address) from person0; key value beijing     chaoyang beijing          chaoyang shanghai pudong beijing          chaoyang shanghai pudong shanxi          taiyuan

explode 只能支持查询一个字段

hive> select explode(address),id from person0;

FAILED: SemanticException 1:24 Only a single expression in the SELECT clause is supported with UDTF's. Error encountered near token 'i d'hive> select explode(address),explode(hobbies) from person0;

FAILED:SemanticException 1:24 Only a single expression in the SELECT clause issupported with UDTF's. Error encountered near token 'h obbies'

例子:统计表中有多少种 hobby 和 city

hive> selectcount(distinct(myCol1)) , count(distinct(myCol2)) from person0 

LATERAL VIEWexplode(hobbies) myTable1 AS myCol1 

LATERAL VIEWexplode(address) myTable2 AS myCol2, myCol3; 

_c0 _c1

4      3

Hive View 视图

和关系型数据库中的普通视图一样,hive 也支持视图

特点:

不支持物化视图、只能查询,不能做加载数据操作;视图的创建,只是保存一份元数据,查询视图时才执行对应的子查询;

view 定义中若包含了 ORDER BY/LIMIT 语句,当查询视图时也进行 ORDER BY/LIMIT 语

句操作,view 当中定义的优先级更高,view 支持迭代视图。

View 语法:创建视图

CREATE VIEW [IF NOT EXISTS][db_name.]view_name 

 [(column_name [COMMENT column_comment], ...) ]

 [COMMENT view_comment]

 [TBLPROPERTIES (property_name = property_value, ...)]

  ASSELECT ... ;

查询视图

select colums from view;

删除视图

DROP VIEW [IF EXISTS] [db_name.]view_name;

Hive 索引

目的:优化查询以及检索性能

创建索引:

create index t1_index on tableperson0(name) 

as'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'  with deferred rebuild in tablet1_index_table;

as:指定索引器;

in table:指定索引表,若不指定默认生成在 default_person0_t1_index_表中

create index t1_index on tableperson0(name)  as'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferredrebuild;

查询索引

show index on person0;

重建索引(建立索引之后必须重建索引才能生效)

ALTER INDEX t1_index ON person0 REBUILD;

删除索引

DROP INDEX IF EXISTS t1_index ON person0;

Hive> create index t1_index on table person0(name)  as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'  with deferred rebuild in table t1_index_table;

hive> show tables; person0 t1_index_table

hive> show index on person0; t1_index    person0      name     t1_index_table   compact    

hive> ALTER INDEX t1_index ON person0 REBUILD;  hive> select * from t1_index_table;

Cat hdfs://mycluster/user/hive/warehouse/person0/person0_data [87]

Jed hdfs://mycluster/user/hive/warehouse/person0/person0_data [0]

Tom hdfs://mycluster/user/hive/warehouse/person0/person0_data [32]           

Hive 运行方式

命令行方式 cli:控制台模式  metastore hive  hiveserver2 beeline

脚本运行方式(实际生产环境中用最多)

JDBC 方式:hiveserver2 web GUI 接口(hwi、hue 等)

命令行模式

与 HDFS 交互(比在 Linux中快,因为已经获得连接)

hive> dfs -ls/; Found 3 items drwxr-xr-x   - rootsupergroup          0 2017-07-11 19:58/psn6 drwxr-xr-x   - root supergroup          0 2017-07-11 15:31 /tmpdrwxr-xr-x   - root supergroup          0 2017-07-11 17:22 /user

与 Linux 交互(Linux命令以!开头)

hive> ! pwd;

/root

脚本方式运行

查询

[root@node03 ~]# hive -e "select * from wordcount limit 3";

17/07/12 17:35:43 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist

Logging initialized using configuration in jar:file:/opt/sxt/apache-hive-1.2.1-bin/lib/hivecommon-1.2.1.jar!/hive-log4j.properties

OK

C C++ Java MySQL Oracle

Spring SpringMVC Hibernate 

Struts2 SpringMVC Hibernate

Time taken: 1.831 seconds, Fetched: 3 row(s)

静默执行,只返回结果,不返回其他信息

[root@node03 ~]# hive -S -e "select * from wordcount limit 3";

17/07/12 17:39:18 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist

C C++ Java MySQL Oracle

Spring SpringMVC Hibernate 

Struts2 SpringMVC Hibernate

查询结果保存到文件中

[root@node03 ~]# hive -e "select * from wordcount limit 1" > result;

[root@node03 ~]# vi result

C C++ Java MySQL Oracle

执行指定文件中的 sql 语句(有几条执行几条,顺序执行)

[root@node03 ~]# vi sql select * from wordcount limit 1;

[root@node03 ~]# hive -f sql

C C++ Java MySQL Oracle

执行指定文件中的 sql 语句,执行完后进入 hive 客户端

[root@node03 ~]# hive -i sql hive>

在 hive 客户端中执行 Linux 中的文件

hive> source /root/sql; C C++ Java MySQL Oracle

web GUI 接口-hwi

搭建步骤

1. 把 apache-hive-*-src/hwi/web/下的所有文件打成 war 包

Microsoft Windows [版本 10.0.14393]

(c) 2016 Microsoft Corporation。保留所有权利。

 

C:\Users\Jed>e:

E:\>cd E:\package\hive-1.2.1-src\apache-hive-1.2.1-src\hwi\web

E:\package\hive-1.2.1-src\apache-hive-1.2.1-src\hwi\web>jar-cvf hive-hwi.war *

war 包在亚索的当前目录生成

2.        把 war 包上传到$HIVE_HOME/lib/下(服务端)

3.        把 JAVA_HOME/lib/下的 tool.jar 拷贝到$HIVE_HOME/lib/下

[root@node04 ~]# cp /usr/java/jdk1.7.0_67/lib/tools.jar/opt/sxt/apache-hive-1.2.1-bin/lib/

4.        修改 hive-site.xml,添加如下配置

<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.war</value>

</property>

5.        启动 hwi 服务

[root@node04 conf]# hive --service hwi

6.        访问浏览器

 

 创建查询:

 结果:

 

Hive 权限

三种授权模型:

1.        Storage Based Authorization inthe Metastore Server

基于存储的授权:可以对 Metastore 中的元数据进行保护,但是没有提供更加细粒度

的访问控制(例如:列级别、行级别)。

2.        SQL Standards BasedAuthorization in HiveServer2

基于 SQL 标准的 Hive授权:完全兼容 SQL 的授权模型,推荐使用该模式。除支持对于

用户的授权认证,还支持角色 role 的授权认证。role 可理解为是一组权限的集合,通过 role 为用户授权。一个用户可以具有一个或多个角色。默认包含两种种角色:public、 admin。

基于 SQL 标准的 Hive 授权模型的限制:

1)        启用当前认证方式之后,dfs, add, delete, compile, reset 等命令被禁用。

2)        通过 set 命令设置 hive configuration 的方式限制某些用户使用。(可通过修改配置文件 hive-site.xml 中 hive.security.authorization.sqlstd.confwhitelist 进行配置)

3)        添加、删除函数以及宏的操作,仅为具有 admin 的用户开放。

4)        用户自定义函数(开放支持永久的自定义函数),可通过具有 admin 角色的用户创建,其他用户都可以使用。

5)        Transform 功能被禁用。

3.   Default HiveAuthorization (Legacy Mode)

hive 默认授权:设计目的仅仅只是为了防止用户产生误操作,而不是防止恶意用户访

问未经授权的数据。

开启基于 SQL 标准的授权模型1) 在 hive 服务端添加如下配置

[root@node04 ~]#vi /opt/sxt/apache-hive-1.2.1-bin/conf/hive-site.xml

<property>

   <name>hive.security.authorization.enabled</name>

    <value>true</value>

</property>

<property>

   <name>hive.server2.enable.doAs</name>

    <value>false</value>

</property>

<!--设置 root用户为admin 角色-->

<property>

   <name>hive.users.in.admin.role</name>

    <value>root</value>

</property>

<property>

    <name>hive.security.authorization.manager</name>

    <value> org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory </value>

</property>

<property>

    <name>hive.security.authenticator.manager</name>

    <value>org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator</value> </property>

2)         服务端启动 hiveserver2

[root@node04 ~]# hiveserver2

3)         客户端通过 beeline 进行连接

root@node03 ~]# beeline -u jdbc:hive2://node04:10000 -n root

虽然在服务端配置文件中指定了 root 的角色是 admin,但在客户端还需要用 set 命令指定,否则无法创建角色

0: jdbc:hive2://node04:10000> create role role1;

Error: Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Current u ser : root is not allowed to add roles. User has to belong to ADMIN role and have it as current role, for this action. (state=08S01,code=1)

查看当前具有的角色

0: jdbc:hive2://node04:10000> show current roles;

设置角色

0: jdbc:hive2://node04:10000> set role admin;

0: jdbc:hive2://node04:10000> show current roles;

创建角色

0: jdbc:hive2://node04:10000> create role role1;

查看所有存在的角色

0: jdbc:hive2://node04:10000> show roles;

    priv_type [, priv_type ] ...

    ON table_or_view_name

FROM principal_specification [, principal_specification] ... ;

查看某个用户、角色的权限:

SHOW GRANT [principal_name] ON (ALL| ([TABLE] table_or_view_name);

 

查看属于某种角色的用户、角色列表

SHOW PRINCIPALS role_name;

删除角色

0: jdbc:hive2://node04:10000> drop role role1;

Hive 优化

hive 核心思想:把 Hive SQL 当做 Mapreduce程序去优化。以下 SQL 不会转为

Mapreduce 来执行: select 仅查询本表字段; where 仅对本表字段做条件过滤。

explain 命令可以显示执行计划:EXPLAIN [EXTENDED] query; EXTENDED 可以看到更详细的信息。

本地模式提高执行效率

本地模式:mapreduce 任务运行在一台节点上,该节点把需要的资源从其他机器copy 过来

集群模式:

mapreduce 任务在 hadoop集群中执行开启本地模式:

set hive.exec.mode.local.auto=true;

注意:

hive.exec.mode.local.auto.inputbytes.max 默认值为 128M,表示加载文件的最大值,若

大于该配置仍会以集群方式来运行

            查询的数据在数据量不大的表中,这种情况使用本地模式,数据量大时使用集群模式

并行计算

hive 执行 sql 默认是顺序执行,如下 sql 如果使用并行计算会大大提高效率,但是集群

压力也增大:

select wc.col1,bk.col2 from

(select count(*) as col1 from wordcount)wc,

(select count(*) as col2 from bucket) bk;

两条子查询可以使用并行计算

通过设置以下参数开启并行模式: sethive.exec.parallel=true;

注意:

hive.exec.parallel.thread.number

代表一次 SQL 计算中允许并行执行的job 个数的最大值严格模式

查询限制:

1)        对于分区表,必须添加 where 对于分区字段的条件过滤;

2)        order by 语句必须包含 limit输出限制; 3) 限制执行笛卡尔积的查询。

 

 

笛卡尔集中的记录不一定正确,为了避免笛卡尔集可以在 WHERE 中加入有效的连接条

件,实际运行环境下应该避免使用笛卡尔全集。

通过设置以下参数开启严格模式:

set hive.mapred.mode=strict;(默认为:nonstrict非严格模式)

Hive 排序

Order By

对于查询结果做全排序,只允许有一个 reduce 处理。当数据量较大时,应慎用。严格

模式下,必须结合 limit 来使用

Sort By

对于单个 reduce 的数据进行排序

Distribute By

分区排序,经常和 Sort By 结合使用

Cluster By

相当于 Sort By + Distribute By,Cluster By 不能通过 asc、desc 的方式指定排序规则;

可通过 distribute by column sort by column asc|desc 的方式结合使用。

Hive join

Join 计算时,将小表(驱动表)放在 join 的左边

Map Join:在 Map 端完成 Join(避免数据倾斜)两种实现方式:

1)        SQL 方式,在 SQL语句中添加 MapJoin 标记(mapjoin hint)语法:

SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value 

FROM smallTable  JOIN  bigTable ON  smallTable.key  = bigTable.key;

2)        开启自动的 MapJoin 通过修改以下配置启用自动的 mapjoin: sethive.auto.convert.join = true;

该参数为 true 时,Hive 自动对左边的表统计量,如果是小表就加入内存,即对小表使用 Map join

相关配置参数:

hive.mapjoin.smalltable.filesize;  

大表小表判断的阈值,如果表的大小小于该值则会被加载到内存中运行 hive.ignore.mapjoin.hint;

默认值:true;是否忽略mapjoin hint 即 mapjoin 标记

hive.auto.convert.join.noconditionaltask;

默认值:true;将普通的 join 转化为普通的 mapjoin时,是否将多个 mapjoin 转化为一个 mapjoin

hive.auto.convert.join.noconditionaltask.size;

最多可以把几个mapjoin 转化为一个 mapjoin

Map-Side 聚合

通过设置以下参数开启在 Map 端的聚合:set hive.map.aggr=true;

相关配置参数:

hive.groupby.mapaggr.checkinterval: 

map 端 groupby 执行聚合时处理的多少行数据(默认:100000)

hive.map.aggr.hash.min.reduction: 

进行聚合的最小比例,预先对 100000 条数据做聚合,若聚合之后的数据量/100000 的

值大于该配置 0.5,则不会聚合

hive.map.aggr.hash.percentmemory:  map 端聚合使用的内存的最大值

hive.map.aggr.hash.force.flush.memory.threshold: 

map 端做聚合操作时 hash表的最大可用内存,大于该值则会触发 flush,溢写到磁盘 hive.groupby.skewindata

是否对 GroupBy 产生的数据倾斜做优化,默认为 false

控制 Hive 中 Map 以及 Reduce的数量

Map 数量相关的参数:

mapred.max.split.size

一个 split 的最大值,即每个 map 处理文件的最大值 mapred.min.split.size.per.node

一个节点上 split 的最小值

mapred.min.split.size.per.rack

一个机架上 split 的最小值

Reduce 数量相关的参数:

mapred.reduce.tasks

强制指定 reduce 任务的数量

hive.exec.reducers.bytes.per.reducer每个 reduce 任务处理的数据量 hive.exec.reducers.max

每个任务最大的 reduce 数

JVM 重用

适用场景:

1)        小文件个数过多

2)        task 个数过多

频繁的申请资源,释放资源降低了执行效率

通过 set mapred.job.reuse.jvm.num.tasks=n; (n 为 task 插槽个数)来设置,道理与

“池”类似。

缺点:

设置开启之后,task 插槽会一直占用资源,不论是否有 task 运行,直到所有的task 即整个 job 全部执行完成时,才会释放所有的 task 插槽资源。

猜你喜欢

转载自blog.csdn.net/paulfrank_zhang/article/details/80983933