Hive全方面攻略

1 篇文章 0 订阅

概述

Apache Hive™数据仓库软件有助于使用SQL读取,编写和管理驻留在分布式存储中的大型数据集。可以将结构投影到已存储的数据中。提供了命令行工具和JDBC驱动程序以将用户连接到Hive。它是一个构建在Hadoop上的数据仓库框架。

简单点来说,hive是为了替代hadoop的mapreduce。

从数据计算的角度来说:

mapreduce分布式计算难度大,而hive是用sql语句来进行数据分析的,简化开发,减少学习成本(sql简单学习)。mysql不可以处理大数据量,而hive可以处理。hive可以替代mapreduce,但是一些复杂的mapreduce,hive还是不能替代。

Hive优缺点

优点:

  1. 操作接口采用了sql,可以简化开发,减少学习成本。
  2. 避免手写MapReduce程序。
  3. hive执行延迟高,适用场景大于用于实时性要求不高的场景,如处理历史数据。
  4. 处理大数据。
  5. 依赖hdfs文件系统作存储,所以它也属于分布式。
  6. 支持自定义函数。(把功能封装成函数,用sql执行)

缺点:

  1. hive的sql表达能力有限(简称HQL),即并不是所有大数据应用场景都可以使用,还需要结合mapreduce。
  2. hive效率低,因为sql需要解析成mqpreduce程序再执行,影响效率
  3. 调优难,因为粒度粗,不好优化。

Hive架构

Hive把SQL查询转换成一系列在Hadoop集群上运行的Job。Hive把存储在HDFS上的数据转换成表的结构,其中元数据(meta)则存储在metastore数据库中。

在这里插入图片描述

  1. client代表hive的一系列操作接口,如hive shell、jdbc/odbc、web ui。当这些接口发送一个查找数据的请求时,首先,会通过meta来查看数据属于哪个表。
  2. meta是hive表的元数据信息,默认以表形式存储在derby数据库中,表名为metastore,但是由于derby不支持多客户端连接,所以推荐使用mysql来替代。
  3. 从meta查看到需要的元数据后,首先会进入SQL Parser解析器,解析器的作用是把sql语句解析成相对应的MapReduce。
  4. 解析器之后是Physical编译器,程序需要编译过后才能执行。
  5. 程序编译完毕会进入Query优化器,Query优化器的作用是对hive进行优化,并不是所有的sql都需要运行一个mr计算,如select all语句查询表中所有内容的,就不需要计算。
  6. 最后进入Execution执行器,这里是真正执行MR程序的地方。

安装部署

  1. 下载安装包:
    http://hive.apache.org/downloads.html
  2. 上传安装包到服务器
  3. 解压
    tar -zxvf .tar
  4. 修改配置 conf/hive-env.sh.template重命名为hive-env.sh
    vi hive-env.sh
    #指定hadoo的目录
    HADOOP_HOME=/home/even/hd/hadoop-2.8.4
    #配置hive的配置文件
    export HIVE_CONF_DIR=/home/even/hd/hive/conf
  5. 启动hive前启动hadoop集群
    start-dfs.sh
    start-yarn.sh
    或者
    start-all.sh
  6. 在hdfs上创建文件夹
    hdfs dfs -mkdir /tmp
    hdfs dfs -mkdir -p /user/hive/warehouse/
  7. 启动hive
    bin/hive

Hive测试

  1. 查看数据库
    show databases;

  2. 使用数据库
    use default;

  3. 查看表
    show tables;

  4. 创建表
    create table user(id int, name string);

  5. 插入数据
    insert into user values(1,“even”);

  6. 查询
    select * from user;

  7. 删除表
    drop table user;

  8. 退出终端
    quit;

操作数据

  1. 准备数据
    vi user.txt
    1 even
    2 zhangsan
    3 lala
    4 elina
    5 haha
  2. 创建数据库
    create database hive_db;
  3. 使用数据库
    use hive_db;
  4. 创建hive表(row format delimited fields terminated by ‘\t’:表明数据文件的每一行是由制表符分隔的文本)
    create table usertable(id int,name string) row format delimited fields terminated by ‘\t’;
  5. 加载数据(加载本地文件数据到hive表中,会把文件复制生成的表的hdfs目录下,如果没有local,则是把hdfs对应目录的文件移动到表的hdfs目录下)
    load data local inpath ‘/home/even/hd/user.txt’ into table usertable;
    在这里插入图片描述

Hive配置

配置文件 conf/hive-site.xml

  1. 启动指定配置文件(配置HIVE_CONF_DIR环境变量是全局配置):
    hive --config 配置文件所有目录的绝对路径
  2. fs.defaultFS
    hdfs文件系统,默认本地hdfs文件系统
  3. yarn.resourcemanager.address
    yarn资源管理器
    例:hive -hiveconf fs.defaultFS=hdfs://localhost -hiveconf mapreduce.framework.name=yarn -hiveconf yarn.resourcemanager.address=localhost:8032
    (注意:如果要让多个hive用户共享一个hadoop集群,需要使hive所用的目录树对所有用户可写)
  4. hive shell中设置配置,例:设置表的定义使用“分桶”
    hive>SET hive.enforce.bucketing=true; #设置属性
    hive>SET hive.enforce.bucketing #查看属性
    hive>SET #列出所有非默认值
    hive>SET -v #列出所有属性值,包括默认值

配置信息优先级:
1,Hive SET命令
2, -hiveconf选项
3,hive-site.xml 和Hadoop站点文件(core-site.xml,hdfs-site.xml,mapreduce-site.xml,yarn-site.xml)
4,hive默认值和hadoop默认文件(core-site.xml,hdfs-site.xml,mapreduce-site.xml,yarn-site.xml)

Hadoop执行引擎

Hive的默认是以MapReduce作为执行引擎,另还支持Apache Tez(http://tez.apache.org/)和Spark引擎。Tez和Spark是通用有向无环图(DAG)引擎,相比MapReduce更加灵活且性能优越。

在使用MapReduce引擎时,中间job的输出会被materialize存储到hdfs上,而Tez和Spark则可以根据Hive规划器的请求,把中间结果写到本地的磁盘或者是内存k缓存,以提高性能,避免复制的开销。

可通过设置hive-site.xml的hive.execution.engine属性来选择引擎。

Hadoop日志

默认在本地文件系统的${java.io.tmpdir}/${user.name}/hive.log,一般情况下,${java.io.tmpdir}就是/tmp目录,可以通过hive.log.dir属性设置。

Hive服务

Hive命令提供了一系列的服务,其中,直接输入hive启动shell环境只是其中的一种,可以通过hive --service help来查看可用的服务列表。然后使用hive --service serviceName来启动服务:

  1. Cli
    hive命令行默认的服务,相当于直接输入hive
  2. hiveserver2
    让hive以提供Thrift服务的服务器形式运行,可以使用不同语言编写的客户端进行访问,如Thrift,JDBC和ODBC连接器的客户端都可以与hive服务器通信,可以通过hive.server2.thrift.port指定服务器监听的端口,类似mysql的3306
  3. jar
    和hadoop jar作用一样,让Java应用程序运行在hadoop集群中
  4. metastore
    默认情况下,metastore和hive服务运行在同一个线程,使用此服务,可以让metastore作为一个单独的进程执行。可通过设置METASTORE_PORT环境变量指定服务器监听的端口号(默认为9083)

Hive客户端

如果hive以服务器的形式运行,则可以通过应用程序来连接服务器。

  • Thrift客户端:hiveserver2是以提供thrift服务的服务器形式运行的,因此,任何运行Thrift的编程语言的客户端都可以与之交互。
  • JDBC驱动:Hive提供了JDBC的驱动,定义在org.apache.hadoop.hive.jdbc.HiveDriver类中,可以以jdbc:hive2://host:port/dbname形式配置JDBC URI,Java应用程序连接hive服务器,实际上驱动是使用java的Thrift绑定来调用Hive Thrift客户端实现的接口。
  • ODBC驱动:可允许支持ODBC协议的应用程序连接Hive服务器。

在这里插入图片描述

Metastore

metastore是Hive元数据存储的地方,主要包括两部分:服务和后台数据的存储。默认情况下,metastore服务和hive服务运行在同一个JVM中,以一个内嵌的以本地磁盘为存储的Derby数据库来实例,即内嵌metastore配置
每次只有一个Derby数据库可以访问磁盘中的数据库文件,所以,一个只能为一个metastore打开一个Hive会话,即不支持多会话连接。
如果需要支持多会话连接,需要一个独立的数据库,使用独立的数据库,metastore服务仍然和hive服务运行在同一个进程中,但是,连接的数据库却已是另一个进程运行的,而不是本进程内嵌的,此种配置为本地metastore配置

metastore的相关配置:

属性名称类型默认值描述
hive.metastore.warehouse.dirURI/user/hive/warehouse管理表就存储在这里
hive.metastore.uris逗号分隔的URI连接由URI列表指定的远程metastore服务器。以轮询方式连接。默认使用当前的metastore
javax.jdo.option.ConnectionURLURIjdbc:derby:;Name=metastored b;create=truemetastore数据库的JDBC URL
javax.jdo.option.ConnectionDriverName字符串org.apache.derby.jdbc.EmbeddedDriverJDBC驱动器的类名
javax.jdo.option.ConnectionUserName字符串APPJDBC用户名
javax.jdo.option.ConnectionPassword字符串mineJDBC密码

以上属性使用javax.jdo前缀,原因是因为metastore的实现针对持久化java对象使用了Java Data Object API,DataNucles实现。另还需要在指定驱动类后,需要把驱动类放入hive的lib目录。

远程metastore配置,即把一个或多个metastore服务器和hive服务运行在不同的进程内,远程metastore配置可以使数据库置于防火墙之后,客户端无需数据库凭据。

可通过设置hive.metastore.uris配置metastore服务器列表,metastore服务器URI的形式为thrift://host:port,此处端口号为上面提及到METASTORE_PORT值。

在这里插入图片描述

配置Hive默认Meta的数据库

CentOS7 安装Mysql

  1. 检查MySQL是否已安装
    yum list installed | grep mysql
  2. 卸载旧版本的Mysql
    yum -y remove 数据库名称
    在这里插入图片描述
  3. 安装Mysql依赖libaio。
    yum search libaio #检索相关信息
    yum install libaio #安装依赖包
  4. 下载MySQL Yum Repository,如果没有wget工具,就先用yum install wget安装
    wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
  5. 添加MySQL Yum Repository
    添加Yum Repository到系统repository列表中。
    yum localinstall mysql-community-release-el7-5.noarch.rpm
  6. 检查是否添加成功
    yum repolist all | grep mysql
    在这里插入图片描述
  7. yum repolist enabled | grep mysql
    在这里插入图片描述
  8. 通过yum安装MySQL,遇到提示按y
    yum install mysql-community-server
  9. 安装成功后查看:
    在这里插入图片描述
  10. 执行whereis mysql,发现mysql在/usr/bin
    在这里插入图片描述

启动关闭mysql

  1. 启动mysql
    systemctl start mysqld
  2. 查看mysql server状态
    systemctl status mysqld
  3. 关闭mysql
    systemctl stop mysqld

防火墙设置

firewall-cmd --permanent --zone=public --add-port=3306/tcp #开放默认端口3306

firewall-cmd --reload #重启

或systemctl stop firewall #直接关闭防火墙

MYSQL设置安全信息

mysql_secure_installation

要求输入root初始密码,默认为空,然后设置新密码。后面根据提示一直y。

mysql 授权命令:
grant all privileges on . to ‘root’@’%’ identified by ‘password’ with grant option;

flush privileges; //刷新权限

Hive配置Mysql

  1. 把mysql-connector-java-5.1.39.jar包拷贝到HIVE_HOME/lib目录下
  2. 配置Metastore到mysql,在hive_home/conf目录创建一个hive-site.xml
    根据官方文档配置参数,拷贝数据到hive-site.xml文件中,特别注意,value标签的内容两边不要有空格,mysql防火墙要关闭
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:mysql://hd-even-01: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>root</value>
        <description>password to use against metastore database
        </description>
    </property>
</configuration>

Hive数据类型

Java数据类型Hive数据类型描述类型
byteTINYINT1byte原子
shortSMALINT2byte原子
intINT4byte原子
longBIGINT8byte原子
floatFLOAT单精度浮点数
doubleDOUBLE双精度浮点数
stringSTRING字符
TIMESTAMP时间类型
BINARY字节数组
DateDATE日期
arrayARRAY一组有序字段,字段类型必须相同
mapMAP一组无序键-值对,键的类型必须是原子级的。同一个map的键和值类型必须相同
STRUCT一组命名的字段。字段类型可以不同
UNION值的数据类型可以是多个被定义的数据类型中的任意一个,该数据类型通过一个整数来标记

DDL数据定义语言

CREATE、ALTER、DROP等sql语句,用于创建或修改表结构,数据类型,表之间的关系和约束等初始化的工作。

  1. 创建数据库
=>查看数据库
show databases;
=>创建数据库
create database hive_db;
=>创建数据库标准写法
create database if not exist db_hive;
=>创建数据库指定所在hdfs路径
create database hive_db1 location '/hive_db';
  1. 修改数据库
=>查看数据库结构
desc database hive_db;
=>添加描述信息
alter database hive_db set dbproperties('datais'='even');
=>查看拓展属性
desc database extended hive_db;
  1. 查询数据库
=>显示数据库
show databases;
=>筛选查询的数据库
show database like 'hive*';
  1. 删除数据库
=>删除数据库
drop database hive_db;
=>删除数据库标准写法
drop database if exists hive_db;
  1. 创建表
=>创建表,行格式化且以fields为界限,以"\t"为分隔
>create table db_h(id int,name string)
>row format
>delimited fields
>terminated by "\t";

表类型

  1. 管理表(内部表)
    加载数据到管理表时,Hive把数据移到仓库目录
#不擅长做数据共享,因为在删除hive中管理表时,数据也会被删除
=>加载数据
load data local inpath 'home/even/hd/even.txt' into table emp;
=>查询并保存到一张新的表
create table if not exists emp2 as select * from emp where name='even';
=>查询表结构
desc formated emp;
Table Type:	MANAGED_TABLE
==>删除表,此操作会把管理表的数据包括元数据全删除了
drop table emp2
  1. 外部表
    使用external关键字,表示创建的表是外部表。此操作不会把数据移到自己的仓库目录。甚至在定义时,不会检查这一外部位置是否存在。删除外部表时,hive只会删除元数据。
#hive不认为这张表拥有这份数据,当删除该表时,数据不删除,擅长做数据共享
=>创建外部表
>create external table if not exists emptable(empno int,ename string,job string,mgr int,birthday string,sal double,comm double,deptno int)
>row format
>delimited fields
>terminated by '\t';
=>导入数据
load data local inpath '/home/even/hd/emp.txt' into table emptable;
=>查看表结构
desc formatted emptable
Table Type:	EXTERNAL_TABLE
=>删除表
drop table emptable;
再次创建相同的表,字段相同,将自动关联数据

1,针对管理表和外部表的用法,一般是把存放在hdfs的初始数据集用作外部表进行使用,然后用hive的变换功能把数据移到管理表。2,所有处理都由hive完成的,应该使用管理表,如果要用hive和其他工具共同处理同一个数据集,就用外部表。3,当同一个数据集需要关联不同的模式时,也需要使用外部表。

  1. 分区表
=>创建分区表
>create table dept_partitions(depno int,dept string,loc string)
>partitioned by(day string)
>row format
>delimited fields
>terminated by '\t';
=>加载数据
load data local inpath '/home/even/hd/dept.txt' into table dept_partitions;
注意:会报错,不能直接导入,需要指定分区
load data local inpath '/home/even/hd/dept.txt' into table dept_partitions partition(day='1112');
=>添加分区
alter table dept_partitions add partition(day='1113');
=>单分区查询
select * from dept_partitions where day='1112';
=>全查询
select * from dept_partitions;
=>查询表结构
desc formatted dept_partitions;
=>删除单个分区
alter table dept_partitions drop partition(day='1112');
  1. 分桶表
分区表分的是数据的存储路径
分桶针对数据文件
1. 创建分桶表
create table emp_buck(id int,name string)
clustered by(id) into 4 buckets
row format
delimited fields
terminated by '\t';
2. 设置属性
set hive.enforce.bucketing=true;
3. 导入数据
insert into table emp_buck select * from emp_b;
注意:分区分的是文件夹 分桶是分的文件
适用于抽样测试
  1. 修改表
=>修改表名
alter table emptable rename to new_emp_table;
=>添加列
alter table dept_partitions add columns(desc string);
=>更新列
alter table dept_partitions change columns desc descc int;
=>替换
alter table dept_partitions replace column(descc int);

Hive存储格式

Hive从两个维度来对表的存储进行管理,分别是行格式(ROW FORMAT)和文件格式(FILE FORMAT)。

ROW FORMAT:行格式指行和一行中的字段如何存储。行格式由SerDe定义,当执行INSERT或CTAS操作时,表的SerDe会把hive的数据行内部表示形式序列化成字节形式并写到输出文件中。如Select操作时,SerDe会把文件中字节形式的数据行反序列化为hive内部操作数据行。

FILE FORMAT:指一行(ROW)中字段容器的格式。最简单的格式是纯文件文件。

默认使用每行(line)存储一个数据行(row),可以通过hive.default.fileformat属性设置默认格式。默认行内分隔符使用Control-A(ASCII码为1),集合类元素默认分隔符为字符Control-B,用于分隔ARRAY或STRUCT或MAP的键-值对中的元素。默认的映射键(map key)分隔符为字符Control-C,用于分隔MAP的键和值。表中各行之间用换行符分隔。

DML数据操作语言

SELECT、UPDATE、INSERT、DELETE、LOAD语句,主要用来对数据库的数据进行操作。

 1. 向表中加载数据
load data local inpath '/home/even/hd/even.txt' into table even;
 2. 加载hdfs中数据
load data inpath '/even.txt' into table even;
提示:因为Hive数据是保存在hdfs中的,因此,此处的操作相当于剪切,把数据从hdfs的一个路径,复制到表对应的路径。
 3. 覆盖原有的数据
load data local inpath '/home/even/hd/even1.txt' overwrite into table even;
 4. 创建分区表
create table even_partitions(id int,name string) partitioned by (month string) row format delimited by fields terminated by '\t';
 5. 向分区表插入数据
insert into table even_partitions partition(month='201901') values(1,'hmb');
 6. 按照条件查询结果并存储到新表
create table if not exists even_partions1 as select * from even_partitions where name='hmb';
 7. 创建表时加载数据
>create table db_h(id int,name string)
>row format
>delimited by fields
>terminated by '\t'
>location '数据路径';
 8. 查询结果导出到本地
insert overwrite local directory '/home/even/hd/elina.txt' select * from even where name='hmb';
或
hive -e 'select * from even' > /home/even/hd/elina.txt
或
dfs -get /user/hive/warehouse/0000 /home/even/hd;

配置查询头信息

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

基本查询

=>全表查询
select * from empt;
=>查询指定列
select empt.empno,empt.empname from empt;
=>列别名
select ename name,empno no from empt;

算数运行符

算数运算符描述
+相加
-相减
*相乘
/相除
%取余
&按位取与
|按位取或
^异或
~按位取反

函数


 1. 求行数count
select count(*) from empt;
 2. 求最大值max
select max(empt.sal) sal_max from empt;
 3. 求最小值
select min(empt.sal) sal_min from empt;
 4. 求总和
select sum(empt.sal) sal_sum from empt;
 5. 求平均值
select avg(empt.sal) sal_avg from empt;
 6. 前两条
select * from empt limit 2;

=>where语句

 1. 工资大于1700的员工信息
 select * from empt where empt.sal > 1700;
 
 2. 工资小于1800的员工信息
select * from empt where empt.sal < 1800;
 3. 查询工资在1500到1800区间的员工信息
 select * from empt where empt.sal between 1500 and 1800;
 
 4. 查询有奖金的员工信息
 select * from empt where empt.comm is not null;
 
 5. 查询无奖金的员工信息
select * from empt where empt.comm is null;
 6. 查询工资是1700和1900的员工信息
select * from empt where empt.sal in (1700,1900);

=>Like
使用like运算选择类似的值,选择条件可以包含字母和数字

 1. 查找员工薪水第二位为6的员工信息
select * from empt where empt.sal like '_6%';
_代表一个字符
%代表0个或多个字符
 2. 查找员工薪水中包含7的员工信息
select * from empt where empt.sal like '%7%';
=》rlike
select * from empt where empt.sal rlike '[7]';

=>分组
1. Group By语句
计算empt表每个部门的平均工资
select avg(empt.sal) avg_sal,deptno from empt group by deptno;select
avg(empt.sal) avg_sal,deptno from empt group by deptno;
2. 计算empt每个部门中最高的薪水
select max(empt.sal) max_sal,deptno from empt group by deptno;
3. 求部门平均薪水大于1700的部门
select deptno,avg(sal) avg_sal from empt group by deptno having avg_sal>1
700;
注意:having只用于group by分组统计语句

=>Join操作
1. 等值join
根据员工表和部门表中部门编号相等,查询员工编号、员工名、部门名称
select e.empno,e.ename,d.dept from empt e join dept d on e.deptno=d.deptn
o;
2. 左外连接 left join
null
select e.empno,e.ename,d.dept from empt e left join dept d on e.deptno=d.
deptno;
3. 右外连接 right join
select e.empno,e.ename,d.dept from dept d right join empt e on e.deptno=
d.deptno;
4. 多表连接查询
查询员工名字、部门名称、员工地址
select e.ename,d.dept,l.loc_name from empt e join dept d on e.deptno=d.de
ptno join location l on d.loc = l.loc_no;
5. 笛卡尔积
为了避免笛卡尔积采用设置为严格模式
set hive.mapred.mode;
set hive.mapred.mode=strict;

=>排序
1. 全局排序 order by
查询员工信息按照工资升序排列
select * from empt order by sal asc;默认
select * from empt order by sal desc;降序
2. 查询员工号与员工薪水按照员工二倍工资排序
select empt.empno,empt.sal*2 two2sal from empt order by two2sal;
3. 分区排序
select * from empt distribute by deptno sort by empno desc;

自定义函数

自定义函数有三种UDF,普通UDF,用户定义聚集函数(user-defined aggregate function)UDAF及用户定义表生成函数(user-defined table-generating function)UDTF。

  • UDF作用于单个数据行,且产生一个数据行作为输出。
  • UDAF接受多个输入数据行,且产生一个输出数据行。像COUNT和MAX。
  • UDTF操作作用于单个数据行,且产生多个数据行(即一个表)作为输出
    其中UDTF用处较少。
  1. UDF(user-defined function),用户定义函数。必须使用Java语言编写。
    编写UDF需要满足两个条件:
    (1)必须是org.apache.hadoop.hive.ql.exec.UDF的子类
    (2)一个UDF必须至少实现evaluate()方法
    其中evalutate()方法可以有多个,Hive会检查UDF,看能否找到和函数调用相匹配的evaluate方法。
package com.even.hive;

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

/**
 * @author even
 * @date 2019年1月11日 下午8:29:00
 * @version 1.0
 */
public class Lower extends UDF{
	//大写转换为小写
	public String evaluate(final String s) {
		if(s == null) {
			return null;
		}
		return s.toString().toLowerCase();
	}
}
#把该类打包成jar文件,然后在metastore中注册这个函数并使用CREATE FUNCTION语句为它起名。
create function lower as 'com.even.hive.Lower' using jar '/home/even/hd/lower.jar';#如果是在集群中使用,需要把文件复制到hdfs中使用。
#使用函数,udf名大小写都可以
select lower(name) from dept;
#删除函数
drop function lower;
#创建一个只在会话期间可以使用的函数,创建一个.hiverc文件以包含定义这些udf的命令
add jar /jar;
create temporary function lower as 'com.even.hive.Lower';
#运行hive时自动添加udf库
hive --auxpath /jar路径
或
设置环境变量HIVE_AUX_JARS_PATH,附加路径可以是逗号分隔的jar文件路径,也可以是包含jar文件的目录。
  1. UDAF
    编写UDAF必须是org.apache.hadoop.hive.ql.exec.UDAF的子类,且内部包含至少一个静态内部类,该静态内部类实现了org.apache.hadoop.hive.ql.UDAFEvaluator。
    编写UDAF需要实现5个方法:
    (1)init()方法,负责初始化计算函数并重设它的内部状态,相当于构造函数
    (2)iterate()方法,每次对一个新值进行聚集计算时都会调用iterate()方法。
    (3)terminatePartial()方法,Hive需要部分聚集结果时会调用terminatePartial()方法,相当于Map的combine。
    (4)merge()方法,决定要合并一部分聚集值和另一部分聚集值时会调用。相当于Reduce的合并。
    (5)terminate()方法,最终聚集结果输出,相当于reduce的输出。
package com.even.hive;

import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.IntWritable;

/**
 * Project Name: Web_App
 * Des:求最大值
 * Created by Even on 2019/1/11
 */
public class Maximum extends UDAF {
    public static class MaximumIntUDAFEvaluator implements UDAFEvaluator {

        private IntWritable result;

        @Override
        public void init() {
            result = null;
        }

        public boolean iterate(IntWritable value) {
            if (value == null)
                return true;
            if (result == null) {
                result = new IntWritable(value.get());
            } else
                result.set(Math.max(result.get(), value.get()));
            return true;
        }

        public IntWritable terminatePartial() {
            return result;
        }

        private boolean merge(IntWritable value) {
            return iterate(value);
        }

        public IntWritable terminate() {
            return result;
        }

    }
}

在这里插入图片描述

Hive优化

压缩

  1. 开启Map阶段输出压缩
#开启输出压缩功能
set hive.exec.compress.intermediate=true;
#开启map输出压缩功能
set mapreduce.map.output.compress=true;
#设置压缩方式(压缩方式在前面《MapReduce数据压缩》文章时提及到)
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
  1. 开启reduce输出端压缩
#开启最终输出压缩功能
set hive.exec.compress.output=true;
#开启最终数据压缩功能
set mapreduce.output.fileoutputformat.compress=true;
#设置压缩方式
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
#设置块压缩
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
  1. 存储
#Hive存储格式:TextFile/SequenceFile/orc/Parquet
orc:Index Data/row Data/stripe Footer
压缩比:
orc>parput>textfile
查询速度:
orc>textfile
  1. Group by优化
    问题,对于一个mr程序,map阶段把相同key的数据分发给一个reduce,其中一个key的量很大。

解决方案:
在map端进行聚合(combiner)
set hive.map.aggr=true;
设置负载均衡:
set hive.groupby.skwindata=true;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值