1. Hive 概述
Hive 是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。
1.1 Hive 架构
Hive 的结构可以分为以下几部分:
- 用户接口:包括 CLI, Client, WUI;
- 元数据存储。通常是存储在关系数据库如 mysql, derby 中;
- 解释器、编译器、优化器、执行器;
- Hadoop:用 HDFS 进行存储,利用 MapReduce 进行计算。
- 用户接口主要有三个:CLI,Client 和 WebGUI。其中最常用的是 CLI,Cli 启动的时候,会同时启动一个 Hive 副本。Client 是 Hive 的客户端,用户连接至 Hive Server。在启动 Client 模式的时候,需要指出 Hive Server 所在节点,并且在该节点启动 HiveServer。 WUI 是通过浏览器访问 Hive。
- Hive 将元数据存储在数据库中,如 mysql、derby。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。
- 解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行。
- Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成(包含 * 的查询,比如 select * from tbl 不会生成 MapRedcue 任务)。
1.2 Hive 和 Hadoop 关系
Hive 构建在 Hadoop 之上,
- HQL 中对查询语句的解释、优化、生成查询计划是由 Hive 完成的;
- 所有的数据都是存储在 Hadoop 中;
- 查询计划被转化为 MapReduce 任务,在 Hadoop 中执行(有些查询没有 MR 任务,如:select * from table);
- Hadoop 和 Hive 都是用 UTF-8 编码的。
1.3 Hive 和普通关系数据库的异同
- 查询语言。专门针对 Hive 的特性设计了类 SQL 的查询语言 HQL;
- 数据存储位置。Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储在 HDFS 中的;
- 数据格式。用户定义数据格式需要指定三个属性:列分隔符(通常为空格、”\t”、”\x001″)、行分隔符(”\n”)以及读取文件数据的方法(Hive 中默认有三个文件格式 TextFile,SequenceFile 以及 RCFile),加载时无需从用户数据格式到Hive 定义的数据格式的转换,只是将数据复制到相应的HDFS目录下;
- 数据更新。Hive 是针对数据仓库应用设计的,所以不支持对数据的改写和添加;
- 索引。由于 MapReduce 的引入, Hive 可以并行访问数据,因此即使没有索引,对于大数据量的访问,Hive 仍然可以体现出优势;
- 执行。Hive 中大多数查询的执行是通过 Hadoop 提供的 MapReduce 来实现的(类似select * from tbl 的查询或查询单个字段不需要 MapReduce);
- 执行延迟。由于没有索引,需要扫描整个表,因此延迟较高,另外一个导致 Hive 执行延迟高的因素是 MapReduce 框架;
- 可扩展性。由于 Hive 是建立在 Hadoop 之上的,因此 Hive 的可扩展性是和 Hadoop的可扩展性是一致的;
- 数据规模;
- 数据处理。数据仓库是用来做查询分析的OLAP数据库。
1.4 Hive 元数据库
Hive 将元数据存储在 RDBMS 中,一般常用的有 MYSQL 和 DERBY(内嵌式)。
2. Hive 的部署
2.1 Hive的安装与配置
安装Hive
首先,Hive是依赖于hadoop系统的,因此在运行Hive之前需要保证已经搭建好hadoop集群环境。
在一个节点上安装关系型数据mysql:
rpm -qa | grep mysql #查看是否安装过mysql yum –y remove ***mysql*** #若安装过,卸载 yum -y install mysql-server mysql-devel #安装 service mysqld start #启动mysql mysqladmin -u root password 123456 #创建root管理员 mysql -u root -p 123456 #登录mysql update mysql.user set Host='%' where user="root"; #开放其它主机连接权限 flush privileges; #更新权限 service mysqld restart #重启mysql
- Apache官网下载安装包hive-1.2.2、源码包;
tar -zvxf apache-hive-1.2.1-bin.tar.gz
配置Hive配置环境变量
vim ~/.bash_profile export HIVE_HOME=/usr/apache-hive-1.2.2-bin PATH=$PATH:$HIVE_HOME/bin
替换和添加相关jar包
–修改HADOOP_HOME/share/hadoop/yarn/lib目录下的jline-*.jar 将其替换成HIVE_HOME/lib下的jline-2.12.jar:
rm HADOOP_HOME/share/hadoop/yarn/lib/jline.*.jar cp HIVE_HOME/lib/jline.*.jar HADOOP_HOME/share/hadoop/yarn/lib/
–将hive连接mysql的jar包(mysql-connector-java-5.1.32-bin.jar)拷贝到hive解压目录的lib目录下:
修改配置文件
见下一小节三种安装模式,任选一种。
启动hive
2.2 Hive的三种安装模式
2.2.1 内嵌Derby单用户模式
这种安装模式的元数据是内嵌在Derby数据库中的,只能允许一个会话连接,数据会存放到HDFS上。这种方式是最简单的存储方式,只需要配置HIVE_HOME/conf/hive-site.xml:
vim HIVE_HOME/conf/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>
2.2.2 本地用户模式(重要,多用于本地开发测试)
这种安装方式和嵌入式的区别在于,不再使用内嵌的Derby作为元数据的存储介质,而是使用其他数据库比如MySQL来存储元数据且是一个多用户的模式,运行多个用户client连接到一个数据库中。这种方式一般作为公司内部同时使用Hive。配置HIVE_HOME/conf/hive-site.xml:
vim HIVE_HOME/conf/hive-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive_rlocal/warehouse</value>
</property>
<property>
<name>hive.metastore.local</name>
<value>true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://node01/hive01?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>
在node01(安装Hive和mysql的节点)启动hive:
[root@node01 ~]# hive
19/01/14 18:45:09 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist
Logging initialized using configuration in jar:file:/usr/apache-hive-1.2.1-bin/lib/hive-common-1.2.1.jar!/hive-log4j.properties
hive>
2.2.3 远程模式(重要)
Remote 一体
这种存储方式需要在远端服务器运行一个mysql 服务器,并且需要在 Hive 服务器启动 meta服务。在异于node01(安装mysql)的节点node02中配置HIVE_HOME/conf/hive-site.xml:
vim HIVE_HOME/conf/hive-site.xml
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>hive.metastore.warehouse.dir</name> <value>/user/hive_romote01/warehouse</value> </property> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://node01:3306/hive02?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> <property> <name>hive.metastore.local</name> <value>false</value> </property> </configuration>
在node02(安装Hive的节点)启动hive:
[root@node02 ~]# hive 19/01/14 18:45:09 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist Logging initialized using configuration in jar:file:/usr/apache-hive-1.2.1-bin/lib/hive-common-1.2.1.jar!/hive-log4j.properties hive>
Remote 分开(公司企业经常用)
将 hive-site.xml 配置文件拆为如下两部分在两个节点配置:
1)服务端配置文件,在异于node01(安装mysql)的节点node02中配置HIVE_HOME/conf/hive-site.xml:
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>hive.metastore.warehouse.dir</name> <value>/user/hive_romote01/warehouse</value> </property> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://node02:3306/hive03?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)客户端配置文件,在异于node01(安装mysql)和node02(安装hive服务的)的节点node03中配置HIVE_HOME/conf/hive-site.xml:
<?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> <!--hive服务端--> <value>thrift://node02:9083</value> </property> </configuration>
在node02(安装Hive服务端的节点)启动hive:
[root@node02 ~]# hive --service metastore Starting Hive Metastore Server
在node03(安装Hive客户端的节点)启动hive:
[root@node03 ~]# hive 19/01/14 19:01:18 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist Logging initialized using configuration in jar:file:/usr/apache-hive-1.2.1-bin/lib/hive-common-1.2.1.jar!/hive-log4j.properties hive>
3. HQL 详解
3.1 DDL语句
具体参见:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL;
Hive的数据定义语言 (LanguageManual DDL)重点是 hive 的建表语句和分区。
3.1.1 创建/删除/修改/使用数据库
- 查看数据库列表:
hive> show databases;
OK
default #默认数据仓库
Time taken: 1.04 seconds, Fetched: 2 row(s)
hive>
- 创建数据库:
语法:CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name [COMMENT database_comment];
- 删除数据库
语法:DROP (DATABASE|SCHEMA) [IF EXISTS] database_name;
- 修改数据库(了解)
语法:ALTER (DATABASE|SCHEMA) database_name SET DBPROPERTIES (property_name=property_value, ...);
ALTER (DATABASE|SCHEMA) database_name SET OWNER [USER|ROLE] user_or_role;
- 使用数据库
USE database_name;
Use default;
3.1.2 创建/删除/表(*)
- 创建表(重要!)
数据类型:
data_type
: primitive_type 原始数据类型
| array_type 数组
| map_type map
| struct_type
| union_type -- (Note: Available in Hive 0.7.0 and later)
primitive_type
: TINYINT
| SMALLINT
| INT
| BIGINT
| BOOLEAN
| FLOAT
| DOUBLE
| DOUBLE PRECISION
| STRING 基本可以搞定一切
| BINARY
| TIMESTAMP
| DECIMAL
| DECIMAL(precision, scale)
| DATE
| VARCHAR
| CHAR
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, ... >
建表实例:
create table abc(
id int,
name string,
age int,
likes array<string>,
address map<string,string>
)
row format delimited fields terminated by ',' # 字段之间的分隔符
COLLECTION ITEMS TERMINATED by '-' # 一个字段各个item的分隔符
map keys terminated by ':' # map键值之间的分隔符
lines terminated by '\n'; # 行分隔符
外部关键字EXTERNAL允许您创建一个表,并提供一个位置,以便hive不使用这个表的默认位置。这方便如果你已经生成的数据。当删除一个外部表,表中的数据不是从文件系统中删除。外部表指向任何HDFS的存储位置,而不是存储在配置属性指定的文件夹hive.metastore.warehouse.dir中。
- 删除表
语法:DROP TABLE [IF EXISTS] table_name [PURGE];
3.1.3 修改表,更新,删除数据(这些很少用)
重命名表:
语法:ALTER TABLE table_name RENAME TO new_table_name;
更新数据:
语法:UPDATE tablename SET column = value [, column = value ...] [WHERE expression]
删除数据:
语法:DELETE FROM tablename [WHERE expression]
3.2 DML语句
具体参见:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML;
Hive数据操作语言([LanguageManual DML](javascript:changelink(‘https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML’,'EN2ZH_CN’)😉),重点是数据加载和查询插入语法。
3.2.1 四种插入/导入数据(重要)
Hive不能很好的支持用insert语句一条一条的进行插入操作,不支持update操作。数据是以load的方式加载到建立好的表中。数据一旦导入就不可以修改。
- 第一种:
从HDFS上导数据
语法:LOAD DATA INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
从本地服务器上导数据
语法:LOAD DATA LOCAL INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
- 第二种
创建person2表,然后从表person1…中导入数据:
语法:INSERT OVERWRITE TABLE person2 [PARTITION (partcol1=val1, partcol2=val2 ...)]
SELECT id,name,age From person1;
- 第三种
语法:FROM person1 t1
INSERT OVERWRITE TABLE person2 [PARTITION (partcol1=val1, partcol2=val2 ...)]
SELECT t1.id, t1.name, t1.age
from放前面好处就是后面可以插入多条语句,如:
FROM person1 t1
INSERT OVERWRITE TABLE person2
SELECT t1.id,t1.name,t1.age,t1.likes,t1.address where…
INSERT OVERWRITE TABLE person3
SELECT t1.id,t1.name,t1.age,t1.likes,t1.address where…;
- 第四种( 不建议)
INSERT INTO TABLE person1
VALUES(1,'zhangsa',18),(2,'zhangsa',22)
3.2.2 查询数据并保存
- 保存数据到本地:
insert overwrite local directory '/opt/datas/person1'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
select * from person ;
查看数据:
hive> !cat /opt/datas/person1/000000_0;
1,zhangsan,18,gamegirlbook,stu_addrbeijingwork_addrshanghai
2,lishi,16,shopboybook,stu_addrhunanwork_addrshanghai
3,wang2mazi,20,fangniueat,stu_addrshanghaiwork_addrtianjing
hive>
- 保存数据到HDFS上:
nsert overwrite directory '/user/hive_remote02/hive/person'
select * from person ;
- 在shell中将数据重定向到文件中:
[root@node03 ~]# hive -e "select * from mydb.person;" > /opt/datas/person2.txt
19/01/14 19:57:35 WARN conf.HiveConf: HiveConf of name hive.metastore.local does not exist
Logging initialized using configuration in jar:file:/usr/apache-hive-1.2.1-bin/lib/hive-common-1.2.1.jar!/hive-log4j.properties
OK
Time taken: 4.235 seconds, Fetched: 3 row(s)
[root@node03 ~]#
3.2.3 备份数据或还原数据
- 备份数据:
EXPORT TABLE person TO '/user/hadoop/hive/datas/export/person_bak' ;
- 删除再还原数据:
先删除表
drop table person;
show tables from mydb;
再还原数据:
IMPORT TABLE person_new FROM '/user/hadoop/hive/datas/export/person_bak' ;
3.2.4 Hive的其它函数
Hive的group by\join(left join right join等)\having\sort by \order by等操作和MySQL没有什么大的区别。
3.3 Hive SerDe
Hive SerDe - Serializer and Deserializer SerDe 用于做序列化和反序列化。构建在数据存储和执行引擎之间,对两者实现解耦。
Hive通过ROW
FORMAT DELIMITED以及SERDE进行内容的读写:
row_format(语法)
: DELIMITED
[FIELDS TERMINATED BY char [ESCAPED BY char]]
[COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char]
[LINES TERMINATED BY char]
: SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]
如 /root/hivedata.txt 存在如下数据:
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-nav.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /asf-logo.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:35 +0800] "GET /bg-middle.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
Hive正则匹配创建表:
CREATE TABLE logtbl (
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;
反序列化加载数据:
hive> load data local inpath '/root/hivedata.txt' overwrite into table logtbl;
Loading data to table mydb.logtbl
Table mydb.logtbl stats: [numFiles=1, numRows=0, totalSize=551, rawDataSize=0]
OK
Time taken: 5.362 seconds
hive> select * from logtbl;
OK
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-nav.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:35 +0800 GET /asf-logo.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:35 +0800 GET /bg-middle.png HTTP/1.1 304 -
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET / HTTP/1.1 200 11217
192.168.57.4 - - 29/Feb/2016:18:14:36 +0800 GET / HTTP/1.1 200 11217
Time taken: 0.189 seconds, Fetched: 7 row(s)
hive>
4. Beeline 和 Hiveserver2
hiveserver2直接启动(hive服务器所在节点):
[root@node02 ~]# hiveserver2
OK
OK
启动 beeline(hive客户端所在节点):
[root@node03 ~]# beeline
Beeline version 1.2.1 by Apache Hive
beeline> !connect jdbc:hive2://node02:10000 root 123456
Connecting to jdbc:hive2://node02:10000
Connected to: Apache Hive (version 1.2.1)
Driver: Hive JDBC (version 1.2.1)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://node02:10000> show databases;
+----------------+--+
| database_name |
+----------------+--+
| default |
| mydb |
+----------------+--+
2 rows selected (1.426 seconds)
1: jdbc:hive2://node02:10000>
5. Hive分区
5.1 Hive的分区partition(重要)
假如现在我们公司一天产生3亿的数据量,那么为了方便管理和查询,此时可以建立分区(可按日期 部门等具体业务分区),区分类别的管理。需要注意:
- 必须在表定义时创建partition;
- 分区分为:单分区和多分区;
- 分区分为:静态分区和动态分区。
5.1.1 创建分区
- 单分区建表语句:
create
table day_table(id int, content string) partitioned by (dt string) row format
delimited fields terminated by ',';
单分区表,按天分区,在表结构中存在id,content,dt三列,以dt为文件夹区分;
- 双分区建表语句:
create table day_hour_table (id int, content string) partitioned by (dt string, hour string) row format delimited fields terminated by ',';
双分区表,按天和小时分区,在表结构中新增加了dt和hour两列;先以dt为文件夹,再以hour子文件夹区分。
注意:在创建 删除多分区等操作时一定要注意分区的先后顺序,他们是父子节点的关系。分区字段不要和表字段相同。
5.1.2 添加分区表的分区
表已创建,在此基础上添加分区:
ALTER TABLE table_name
ADD partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...
5.1.3 删除分区
语法:ALTER TABLE table_name DROP partition_spec, partition_spec,...
注意:用户可以用ALTER TABLE DROP PARTITION 来删除分区,分区的元数据和数据将被一并删除。
5.1.4 数据加载进分区表中
语法:LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1,partcol2=val2 ...)]
例如:
LOAD DATA INPATH '/user/pv.txt' INTO TABLE day_hour_table PARTITION(dt='2008-08-08', hour='08');
5.1.5 查看分区语句
hive> show partitions table_name;
5.1.6 重命名分区
语法:ALTER TABLE table_name PARTITION partition_spec RENAME TO PARTITION partition_spec;
5.1.7 动态分区(重要)
在本地文件/root/hivedata.txt中写入以下4行数据:
aaa,US,CA aaa,US,CB bbb,CA,BB bbb,CA,BC
建立非分区表并加载数据
hive> CREATE TABLE t1 (name STRING, cty STRING, st STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ','; hive> LOAD DATA LOCAL INPATH '/root/hivedata.txt' INTO TABLE t1; SELECT * FROM t1;
建立外部分区表并动态加载数据 (注意删除外部表的相关事项)
hive> CREATE EXTERNAL TABLE t2 (name STRING) PARTITIONED BY (country STRING, state STRING);
动态分区的参数
set hive.exec.dynamic.partition;#是否开启动态分区功能,默认false关闭 set hive.exec.dynamic.partition.mode;#动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。 set hive.exec.max.dynamic.partitions.pernode;#默认值:100,在每个执行MR的节点上,最大可以创建多少个动态分区。 set hive.exec.max.dynamic.partitions;#默认值:1000,在所有执行MR的节点上,最大一共可以创建多少个动态分区。 set hive.exec.max.created.files;#默认值:100000整个MR Job中,最大可以创建多少个HDFS文件。 set hive.error.on.empty.partition;#默认值:false当有空分区生成时,是否抛出异常。一般不需要设置。
设置动态分区参数
set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; set hive.exec.max.dynamic.partitions.pernode=1000;
加载数据
INSERT INTO TABLE t2 PARTITION (country, state) SELECT name, cty, st FROM t1;
6. 函数自定义
自定义函数包括三种 UDF、UDAF、UDTF:
- UDF:一进一出
- UDAF:聚集函数,多进一出。如:Count/max/min
- UDTF:一进多出,如 lateralview explore()
使用方式 :在HIVE会话中add自定义函数的jar 文件,然后创建 function 继而使用函数,后续总结。
7. 分桶
7.1 分桶表及应用场景
分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储(类似MapReduce中的默认partition对于Key值得分区)。对于hive中每一个表、分区都可以进一步进行分桶。由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中。
适用场景:数据抽样( sampling )、map-join。
7.2 开启支持分桶
hive> set hive.enforce.bucketing=true;
注意:一次作业产生的桶(文件数量)和reduce task个数一致。
7.3 往分桶表中加载数据
语法:insert into table bucket_table select columns from tbl;
7.4 抽样查询
语法:select * from bucket_table tablesample(bucket 1 out of 4 on columns);
TABLESAMPLE语法:
TABLESAMPLE(BUCKET x OUT OF y)
x:表示从哪个bucket开始抽取数据
y:必须为该表总bucket数的倍数或因子