Hive 入门

2019-09-26  本文已影响0人  djm猿

1 Hive 基本概念

1.1 什么是 Hive?

Hive:由 Facebook 开源用于解决海量结构化日志的数据统计。

Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类 SQL 查询功能。

image

1.2 Hive 的优缺点

优点:

缺点:

1.3 Hive架构原理

image

1、用户接口:Client

2、元数据:Metastore

3、Hadoop

4、驱动器

image

Hive 通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的 Driver,结合元数据(MetaStore),将这些指令翻译成 MapReduce,提交到 Hadoop 中执行,最后,将执行返回的结果输出到用户交互接口。

1.4 Hive VS 数据库

2 Hive 安装

2.1 Hive 安装部署

1、解压 apache-hive-1.2.1-bin.tar.gz 到 /opt/module/ 目录下面

2、修改 apache-hive-1.2.1-bin.tar.gz 的名称为 hive

3、修改 /opt/module/hive/conf 目录下的 hive-env.sh.template 名称为 hive-env.sh

4、配置 hive-env.sh

# 配置HADOOP_HOME路径
export HADOOP_HOME=/opt/module/hadoop-2.7.2
# 配置HIVE_CONF_DIR路径
export HIVE_CONF_DIR=/opt/module/hive/conf

5、启动 hdfs、yarn

6、在 HDFS 上创建 /tmp 和 /user/hive/warehouse 两个目录并修改他们的同组权限可写

[djm@hadoop102 hadoop-2.7.2]$ bin/hadoop fs -mkdir /tmp
[djm@hadoop102 hadoop-2.7.2]$ bin/hadoop fs -mkdir -p /user/hive/warehouse
[djm@hadoop102 hadoop-2.7.2]$ bin/hadoop fs -chmod g+w /tmp
[djm@hadoop102 hadoop-2.7.2]$ bin/hadoop fs -chmod g+w /user/hive/warehouse

7、启动 Hive

[djm@hadoop102 hive]$ bin/hive

2.2 将本地文件导入到 Hive

1、在 /opt/module/ 目录下创建 datas

2、在 datas 目录下创建 student.txt 并添加如下内容

1001    zhangshan
1002    lishi
1003    zhaoliu

3、创建 student 表, 并声明列分隔符

hive> create table student(id int, name string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

4、加载 /opt/module/datas/student.txt 文件到 student 数据表中

hive> load data local inpath '/opt/module/datas/student.txt' into table student;

5、再打开一个客户端窗口启动 hive,会产生java.sql.SQLException 异常:

6、其他字段解释

2.3 安装 MariaDB

1、查看是否现有的包

rpm -qa | grep mariadb

2、如果有,删之

rpm -e --nodeps 包名

3、安装 MariaDB

yum -y install mariadb mariadb-server

4、启动 MariaDB

systemctl start mariadb

5、进行 MariaDB 的相关简单配置

mysql_secure_installation

首先是设置密码,会提示先输入密码
Enter current password for root (enter for none):<–初次运行直接回车

设置密码
Set root password? [Y/n] <– 是否设置root用户密码,输入y并回车或直接回车
New password: <– 设置root用户的密码
Re-enter new password: <– 再输入一次你设置的密码

其他配置
Remove anonymous users? [Y/n] <– 是否删除匿名用户,回车
Disallow root login remotely? [Y/n] <–是否禁止root远程登录,回车
Remove test database and access to it? [Y/n] <– 是否删除test数据库,回车
Reload privilege tables now? [Y/n] <– 是否重新加载权限表,回车

2.4 Hive 元数据配置到 MySQL

1、驱动拷贝:拷贝 /opt/software 目录下的 mysql-connector-java-5.1.27-bin.jar 到 /opt/module/hive/lib/

2、配置 Metastore 到 MySQL:在 /opt/module/hive/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:mysql://hadoop102:3306/metastore?createDatabaseIfNotExist=true</value>
        <description>JDBC connect string for a JDBC metastore</description>
    </property>
    <property>
        <name>javax.jdo.option.ConnectionDriverName</name>
        <value>com.mysql.jdbc.Driver</value>
        <description>Driver class name for a JDBC metastore</description>
    </property>
    <property>
        <name>javax.jdo.option.ConnectionUserName</name>
        <value>root</value>
        <description>username to use against metastore database</description>
    </property>
    <property>
        <name>javax.jdo.option.ConnectionPassword</name>
        <value>000000</value>
        <description>password to use against metastore database</description>
    </property>
</configuration>

2.4 HiveJDBC 访问

1、启动 hiveserver2 服务

[djm@hadoop102 hive]$ bin/hiveserver2

2、启动 beeline

[djm@hadoop102 hive]$ bin/beeline
Beeline version 1.2.1 by Apache Hive
beeline>

3、连接 hiveserver2

beeline> !connect jdbc:hive2://hadoop102:10000(回车)
Connecting to jdbc:hive2://hadoop102:10000
Enter username for jdbc:hive2://hadoop102:10000: djm(回车)
Enter password for jdbc:hive2://hadoop102:10000: (直接回车)
Connected to: Apache Hive (version 1.2.1)
Driver: Hive JDBC (version 1.2.1)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://hadoop102:10000>

2.5 Hive 常见属性配置

2.5.1 Hive 数据仓库位置配置

Default 数据仓库的最原始位置是在 hdfs 上的:/user/hive/warehouse 路径下

在仓库目录下,没有对默认的数据库 default 创建文件夹,如果某张表属于 default 数据库,直接在数据仓库目录下创建一个文件夹

修改 default 数据仓库原始位置,在 hive-site.xml 配置,添加如下配置:

<property>
    <name>hive.metastore.warehouse.dir</name>
    <value>/user/hive/warehouse</value>
    <description>location of default database for the warehouse</description>
</property>

配置同组用户有执行权限

bin/hdfs dfs -chmod g+w /user/hive/warehouse

2.5.2 查询后信息显示配置

在 hive-site.xml 文件中添加如下配置信息,就可以实现显示当前数据库,以及查询表的头信息配置

<property>
    <name>hive.cli.print.header</name>
    <value>true</value>
</property>
<property>
    <name>hive.cli.print.current.db</name>
    <value>true</value>
</property>

2.5.3 Hive 运行日志信息配置

Hive 的 log 默认存放在 /tmp/djm/hive.log 目录下

修改 hive 的 log 存放日志到 /opt/module/hive/logs

2.5.4 参数配置方式

查看当前所有的配置信息

hive>set;

参数的配置三种方式

1、配置文件方式

默认配置文件:hive-default.xml

用户自定义配置文件:hive-site.xml

注意:用户自定义配置会覆盖默认配置,另外,Hive 也会读入 Hadoop 的配置,因为 Hive 是作为 Hadoop 的客户端启动的,Hive 的配置会覆盖 Hadoop 的配置,配置文件的设定对本机启动的所有 Hive 进程都有效

2、命令行参数方式

启动 Hive 时,可以在命令行添加 -hiveconf param=value 来设定参数

例如:

[djm@hadoop103 hive]$ bin/hive -hiveconf mapred.reduce.tasks=10;

注意:仅对本次 hive 启动有效

查看参数设置:

set mapred.reduce.tasks;

3、参数声明方式

可以在 HQL 中使用 SET 关键字设定参数

例如:

set mapred.reduce.tasks=100;

注意:仅对本次 hive 启动有效

上述三种设定方式的优先级依次递增,即配置文件<命令行参数<参数声明。注意某些系统级的参数,例如 log4j 相关的设定,必须用前两种方式设定,因为那些参数的读取在会话建立以前已经完成了

3 Hive 数据类型

3.1 基本数据类型

Hive数据类型 Java数据类型 长度 例子
TINYINT byte 1byte有符号整数 20
SMALINT short 2byte有符号整数 20
INT int 4byte有符号整数 20
BIGINT long 8byte有符号整数 20
BOOLEAN boolean 布尔类型,true或者false TRUE FALSE
FLOAT float 单精度浮点数 3.14159
DOUBLE double 双精度浮点数 3.14159
STRING string 字符系列,可以指定字符集,可以使用单引号或者双引号 'a'、"A"
TIMESTAMP 时间类型
BINARY 字节数组

对于 Hive 的 String 类型相当于数据库的 varchar 类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它可以存储 2GB 的字符数

3.2 集合数据类型

数据类型 描述 语法示例
STRUCT 和c语言中的struct类似,都可以通过“点”符号访问元素内容。例如,如果某个列的数据类型是STRUCT{first STRING, last STRING},那么第1个元素可以通过字段.first来引用。 struct() 例如struct<street:string, city:string>
MAP MAP是一组键-值对元组集合,使用数组表示法可以访问数据。例如,如果某个列的数据类型是MAP,其中键->值对是’first’->’John’和’last’->’Doe’,那么可以通过字段名[‘last’]获取最后一个元素 map() 例如map<string, int>
ARRAY 数组是一组具有相同类型和名称的变量的集合。这些变量称为数组的元素,每个数组元素都有一个编号,编号从零开始。例如,数组值为[‘John’, ‘Doe’],那么第2个元素可以通过数组名[1]进行引用。 Array() 例如array<string>

3.3 类型转化

Hive 的原子数据类型是可以进行隐式转换的,类似于 Java 的类型转换,例如某表达式使用 INT 类型,TINYINT 会自动转换为 INT 类型,但是 Hive 不会进行反向转化,例如,某表达式使用 TINYINT 类型,INT 不会自动转换为 TINYINT 类型,它会返回错误,除非使用 CAST 操作

转换规则:

4 DDL

4.1 创建数据库

格式:

CREATE DATABASE [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];

4.2 查询数据库

显示所有数据库

show databases;

过滤显示查询的数据库

show databases like 'db_hive*';

查看数据库信息

desc database db_hive;

查看数据库详情

desc database extended db_hive;

切换数据库

use db_hive;

4.3 修改数据库

格式:

ALTER DATABASE database_name 
SET DBPROPERTIES (property_name=property_value, ...);

4.4 删除数据库

格式:

DROP database_name
[IF NOT EXISTS] 
[CASCADE];

4.5 创建表

格式:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name 
[(col_name data_type [COMMENT col_comment], ...)] 
[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] 
[ROW FORMAT row_format] 
[STORED AS file_format] 
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
[AS select_statement]

字段解释说明:

4.5.1 管理表

默认创建的表都是所谓的管理表,有时也被称为内部表,因为这种表,Hive会控制着数据的生命周期,Hive 默认情况下会将这些表的数据存储在由配置项 hive.metastore.warehouse.dir 所定义的目录的子目录下,当我们删除一个管理表时,Hive 也会删除这个表中数据,管理表不适合和其他工具共享数据。

4.5.2 外部表

因为表是外部表,所以 Hive 并非认为其完全拥有这份数据。删除该表并不会删除掉这份数据,不过描述表的元数据信息会被删除掉

4.5.3 管理表与外部表的互相转换

查询表的类型

desc formatted student;

修改内部表 student 为外部表

alter table student set tblproperties('EXTERNAL'='TRUE');

查询表的类型

desc formatted student;

修改外部表 student 为内部表

alter table student set tblproperties('EXTERNAL'='FALSE');

查询表的类型

desc formatted student;

4.6 分区表

创建分区表

hive (default)> create table dept_partition(
  deptno int, dname string, loc string
) partitioned by (month string) row format delimited fields terminated by '\t';

加载分区数据到分区表中

hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201709');
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201708');
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201707’);

查询分区内数据

# 单分区查询
select * from dept_partition where month='201709';
# 多分区查询
select * from dept_partition where month='201709'
  union select * from dept_partition where month='201708' 
  union select * from dept_partition where month='201707';

增加分区

# 增加单分区
alter table dept_partition add partition(month='201706');
# 增加多分区
alter table dept_partition add partition(month='201706') partition(month='201705');

删除分区

# 删除单分区
alter table dept_partition drop partition(month='201706');
# 删除多分区
alter table dept_partition drop partition(month='201706') partition(month='201705');

查看分区表有多少分区

hive> show partitions dept_partition;

查看分区表结构

desc formatted dept_partition;

创建二级分区并导入

# 创建二级分区
create table dept_partition2(
  deptno int, dname string, loc string
) partitioned by (month string, day string) row format delimited fields terminated by '\t';
# 加载数据
load data local inpath '/opt/module/datas/dept.txt' 
into table default.dept_partition2 partition(month='201709', day='13');
# 查询分区数据
select * from dept_partition2 where month='201709' and day='13';

把数据直接上传到分区目录上,怎么让分区表和数据产生关联?

1、执行分区修复命令

msck repair table dept_partition2;

2、上传数据后添加分区

alter table dept_partition2 add partition(month='201709', day='11');

3、创建文件夹后 load 数据到分区

load data local inpath '/opt/module/datas/dept.txt' 
into table dept_partition2 partition(month='201709',day='10');

4.7 修改表

重命名表

格式:

ALTER TABLE table_name RENAME TO new_table_name

增加/修改/替换列信息

格式:

# 更新列
ALTER TABLE table_name CHANGE [COLUMN] col_old_name
col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
# 增加和替换列
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...) 

ADD 是代表新增一字段,字段位置在所有列后面(partition 列前),REPLACE 则是表示替换表中所有字段

4.8 删除表

格式:

DROP TABLE table_name;

5 DML

5.1 数据导入

5.1.1 Load 方式

格式:

load data [local] inpath '/opt/module/datas/student.txt' [overwrite] into table student [partition (partcol1=val1,…)];

5.1.2 Insert 方式

insert overwrite table student1 partition(month = '201708') 
select id, name from student where month = '201709';

5.1.3 As Select 方式

create table if not exists student2 as select id, name from student;

5.1.4 Import 方式

import table student3 partition(month='201709') from '/user/hive/warehouse/export/student';

5.1.5 创建表时通过 Location 指定加载数据路径

create external table if not exists student4(
  id int, name string 
) row format delimited fields terminated by '\t' location '/student;

5.2 数据导出

5.2.1 Insert 导出

将查询结果导出到本地

insert overwrite local directory '/opt/module/datas/export/student' 
select * from student;

将查询结果格式化到本地

insert overwrite local directory '/opt/module/datas/export/student' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' 
select * from student;

将查询结果导出到 HDFS

insert overwrite directory '/user/atguigu/student2' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' 
select * from student;

5.2.2 Hive Shell 命令导出

bin/hive -e 'select * from default.student;' > /opt/module/datas/export/student.txt;

5.2.3 Export 导出到 HDFS

export table default.student to '/user/hive/warehouse/export/student';

5.3 清除表数据

truncate table student;

6 查询

6.1 基本查询

全表查询

select * from emp;

特定列查询

select empno, ename from emp;

列别名

select empno as id, ename as name from emp;

limit

select * from emp limit 5;

6.2 Where

# 查询出薪水等于5000的所有员工
select * from emp where sal = 5000;
# 查询出薪水在500到1000的员工
select * from emp where sal between 500 and 1000;
# 查询comm为空的所有员工信息
select * from emp where comm is null;
# 查询工资是1500或5000的员工信息
select * from emp where sal in (1500, 5000);
# 查找以2开头薪水的员工信息
select * from emp where sal like '2%';
# 查找第二个数值为2的薪水的员工信息
select * from emp where sal like '_2%';
# 查找薪水中含有2的员工信息
select * from emp where sal rlike '[2]';
# 查询薪水大于1000,部门是30
select * from emp where sal > 1000 and deptno = 30;
# 查询薪水大于1000,或者部门是30
select * from emp where sal > 1000 or deptno = 30;
# 查询除了20部门和30部门以外的员工信息
select * from emp where deptno not in (20, 30);

6.3 分组

GROUP BY 语句通常会和聚合函数一起使用,按照一个或者多个列队结果进行分组,然后对每个组执行聚合操作

# 计算emp表每个部门的平均工资
select deptno, avg(sal) from emp group by deptno;
# 计算emp每个部门中每个岗位的最高薪水

Having 只用于 GROUP BY 分组统计语句

# 求每个部门的平均薪水大于2000的部门
select deptno, avg(sal) as avg_sal from emp group by deptno having avg_sal > 2000;

6.4 Join

等值连接

内连接

左外连接

右外连接

满外连接

多表连接

6.5 排序

Order By

Sort By

Distribute By

Cluster By

6.6 分桶及抽样

分区提供一个隔离数据和优化查询的便利方式,不过,并非所有的数据集都可形成合理的分区,对于一张表或者分区,Hive 可以进一步组织成桶,也就是更为细粒度的数据范围划分

分桶是将数据集分解成更容易管理的若干部分的另一个技术

分区针对的是数据的存储路径;分桶针对的是数据文件

设置 hive.enforce.bucketing 属性,使得 Hive 能识别桶

set hive.enforce.bucketing = true;

创建分桶表

create table stu_buck (
  id int, name string
) clustered by(id) into 4 buckets row format delimited fields terminated by '\t';

查看表结构

desc formatted stu_buck;

导入数据到分桶表中

insert into table stu_buck select id, name from stu;

分桶规则:

Hive 的分桶采用对分桶字段的值进行哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中

分桶抽样查询

7 函数

7.1 空字段赋值

函数说明:

NVL(col, str):给值为 NULL 的数据赋值

# 如果员工的comm为NULL,则用-1代替
select comm, nvl(comm, -1) from emp;

7.2 CASE WHEN

准备数据:

name dept_id sex
悟空 A
大海 A
宋宋 B
凤姐 A
婷姐 B
婷婷 B

创建表并导入数据:

create table emp_sex(
  name string, dept_id string, sex string
) row format delimited fields terminated by "\t";
load data local inpath '/opt/module/datas/emp_sex.txt' into table emp_sex;

求各部门男女各有多少人

select 
  dept_id, 
  sum(case sex when '男' then 1 else 0 end) male, 
  sum(case sex when '女' then 1 else 0 end) female 
from emp_sex group by dept_id;

7.3 行转列

相关函数说明:

CONCAT(string A/col, string B/col…):返回输入字符串连接后的结果

CONCAT_WS(separator, str1, str2,...):将每个字符串用指定的字符分开

COLLECT_SET(col):将某字段的值进行去重汇总,产生 array 类型字段

准备数据:

name constellation blood_type
孙悟空 白羊座 A
大海 射手座 A
宋宋 白羊座 B
猪八戒 白羊座 A
凤姐 射手座 A

创建表并导入数据:

create table person_info(
  name string, 
  constellation string, 
  blood_type string
) row format delimited fields terminated by "\t";
load data local inpath "/opt/module/datas/constellation.txt" into table person_info;

把星座和血型一样的人归类到一起

select 
    t.base, concat_ws('|', collect_set(t.name)) name 
from 
    (select name, concat(constellation, ",", blood_type) base from person_info) t 
group by 
    t.base;

7.4 列转行

函数说明:

EXPLODE(col):将 array 或者 map 结构拆分成多行

LATERAL VIEW

用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias

解释:用于和 split, explode 等UDTF一起使用,它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合

准备数据:

movie category
《疑犯追踪》 悬疑,动作,科幻,剧情
《Lie to me》 悬疑,警匪,动作,心理,剧情
《战狼2》 战争,动作,灾难

创建表并导入数据:

create table movie_info(
    movie string, 
    category array<string>
) row format delimited fields terminated by "\t" collection items terminated by ",";
load data local inpath "/opt/module/datas/movie.txt" into table movie_info;

将电影分类中的数组数据展开

select
    movie,
    item
from
    movie_info lateral view explode(category) t as item;

7.5 开窗

相关函数说明:

OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化

CURRENT ROW:当前行

n PRECEDING:往前 n 行数据

n FOLLOWING:往后 n 行数据

UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING 表示到后面的终点

LAG(col,n,default_val):往前第 n 行数据

LEAD(col,n, default_val):往后第 n 行数据

NTILE(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从 1 开始,对于每一行,NTILE 返回此行所属的组的编号

创建表并导入数据

create table business(
  name string, 
  orderdate string,
  cost int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
load data local inpath "/opt/module/datas/business.txt" into table business;

按需求查询数据

# 查询在2017年4月份购买过的顾客及总人数
select name, count(*) over() from business where substring(orderdate, 1, 7) = '2017-04';
# 查询顾客的购买明细及月购买总额
select name, orderdate, sum(cost) over(partition by month(orderdate)) from business;
# 上述的场景, 将每个顾客的cost按照日期进行累加
select
    name,
    orderdate,
    cost,
    sum(cost) over(partition by name
order by
    orderdate rows between unbounded preceding and current row)
from
    business;
# 查询每个顾客上次的购买时间
select
    name,
    orderdate,
    cost,
    lag(orderdate, 1) over(partition by name)
from
    business;
# 查询前20%时间的订单信息
select
    *
from
    (
    select
        name,
        orderdate,
        ntile(5) over(
        order by orderdate) sorted
    from
        business) t
where
    sorted = 1;

7.6 Rank

函数说明:

RANK() 排序相同时会重复,总数不会变

DENSE_RANK() 排序相同时会重复,总数会减少

ROW_NUMBER() 会根据顺序计算

数据准备:

name subject score
孙悟空 语文 87
孙悟空 数学 95
孙悟空 英语 68
大海 语文 94
大海 数学 56
大海 英语 84
宋宋 语文 64
宋宋 数学 86
宋宋 英语 84
婷婷 语文 65
婷婷 数学 85
婷婷 英语 78

创建表并导入数据:

create table score(
  name string,
  subject string, 
  score int
) row format delimited fields terminated by "\t";
load data local inpath '/opt/module/datas/score.txt' into table score;

计算每门学科成绩排名

select
    name,
    subject,
    score,
    rank() over (partition by subject
order by
    desc)
from
    score;

计算没门学科前三名

select
    *
from
    (
    select
        *,
        rank() over (partition by subject
    order by
        score desc) as rk
    from
        score) t
where
    t.rk <= 3;

7.7 自定义函数

根据用户自定义函数类别分为以下三种:

步骤:

1、导入依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
    <dependency>
        <groupId>org.apache.hive</groupId>
        <artifactId>hive-exec</artifactId>
        <version>1.2.1</version>
    </dependency>
</dependencies>

2、创建一个类

package com.djm.hive;
import org.apache.hadoop.hive.ql.exec.UDF;

public class Lower extends UDF {

    public String evaluate (final String s) {
        
        if (s == null) {
            return null;
        }
        
        return s.toLowerCase();
    }
}

3、打成 jar 包上传到服务器 /opt/module/jars/ 目录

4、将 jar 包添加到 hive 的 classpath

add jar /opt/module/datas/udf.jar;

5、创建临时函数与 Class 关联

create temporary function mylower as "com.djm.hive.Lower";

6、使用自定义函数

select ename, mylower(ename) lowername from emp;

8 压缩和存储

8.1 开启 Map 输出阶段压缩

开启 map 输出阶段压缩可以减少 job 中 map 和 Reduce task 间数据传输量

# 开启hive中间传输数据压缩功能
set hive.exec.compress.intermediate=true;
# 开启mapreduce中map输出压缩功能
set mapreduce.map.output.compress=true;
# 设置mapreduce中map输出数据的压缩方式
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

8.2 开启 Reduce 输出阶段压缩

当 Hive 将输出写入到表中时,输出内容同样可以进行压缩

# 开启hive最终输出数据压缩功能
set hive.exec.compress.output=true;
# 开启mapreduce最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;
# 设置mapreduce最终数据输出压缩方式
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
# 设置mapreduce最终数据输出压缩为块压缩
set mapreduce.output.fileoutputformat.compress.type=BLOCK;

8.3 文件存储格式

8.3.1 列式存储和行式存储

image

Hive 支持的存储数据的格式主要有:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET

行存储的特点:

查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。

列存储的特点:

因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

8.3.2 TextFile 格式

默认格式,数据不做压缩,磁盘开销大,数据解析开销大,可结合 Gzip、Bzip2 使用,但使用 Gzip 这种方式,hive 不会对数据进行切分,从而无法对数据进行并行操作

8.3.3 Orc 格式

image

Orc (Optimized Row Columnar)是Hive 0.11版里引入的新的存储格式

如图所示可以看到每个 Orc 文件由 1 个或多个 Stripe 组成,每个 Stripe 一般为 HDFS 的块大小,每一个 Stripe 包含多条记录,这些记录按照列进行独立存储,对应到 Parquet 中的 row group的概念,每个 Stripe 里有三部分组成,分别是 Index Data,Row Data,Stripe Footer:

每个文件有一个 File Footer,这里面存的是每个 Stripe 的行数,每个 Column 的数据类型信息等;每个文件的尾部是一个PostScript,这里面记录了整个文件的压缩类型以及FileFooter的长度信息等,读取文件时,会 seek 到文件尾部读PostScript,从里面解析到 File Footer 长度,再读 FileFooter,从里面解析到各个 Stripe 信息,再读各个 Stripe,即从后往前读

8.3.4 Parquet 格式

image

如图所示一个文件中可以存储多个行组,文件的首位都是该文件的 Magic Code,用于校验它是否是一个 Parquet 文件,Footer length 记录了文件元数据的大小,通过该值和文件长度可以计算出元数据的偏移量,文件的元数据中包括每一个行组的元数据信息和该文件存储数据的 Schema 信息,除了文件中每一个行组的元数据,每一页的开始都会存储该页的元数据,在Parquet 中,有三种类型的页:数据页、字典页和索引页,数据页用于存储当前行组中该列的值,字典页存储该列值的编码字典,每一个列块中最多包含一个字典页,索引页用来存储当前行组下该列的索引,目前 Parquet 中还不支持索引页。

Parquet 文件是以二进制方式存储的,所以是不可以直接读取的,文件中包括该文件的数据和元数据,因此 Parquet 格式文件是自解析的。

通常情况下,在存储 ParquetBlockMapperBlock 每一个行组由一个任务处理,增大任务执行并行度

8.4 存储和压缩结合

查看是否支持 Snappy

hadoop checknative

将编译好的支持 Snappy 压缩的 Hadoop 解压

tar -zxvf hadoop-2.7.2.tar.gz

拷贝 /opt/software/hadoop-2.7.2/lib/native 到 /opt/module/hadoop-2.7.2/lib/native

cp ../native/* /opt/module/hadoop-2.7.2/lib/native/

集群分发

xsync /opt/module/hadoop-2.7.2/lib/native/

再次查看是否支持 Snapy

上一篇下一篇

猜你喜欢

热点阅读