hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析
目录
架构
1.接口
CLI、Client、WUI。
CLI:最常用,CLI启动的时候,会同时启动一个Hive副本
Client:Hive的客户端,用户连接至Hive Server。启动Client模式时,需要指定Hive Server所在的节点,并启动Hive Server
WUI:通过浏览器访问Hive
2.数据库
Hive将元数据存储在数据库中,如mysql,derby等
Hive中元数据包括表的名字,表的列和分区及其属性,表的数据所在目录等
3解释器、编译器、优化器完成HQL查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在HDFS中,并在随后有MapReduce调用执行
Hive部署
1.安装Hive
1.安装Hive
1.将apache-hive-1.2.1-bin.tar.gz压缩文件传到客户端节点上,并解压
2.配置环境变量
# 编辑文件
vim /etc/profile
# 文件末尾添加
export HIVE_HOME=/data/hive
export PATH=$HIVE_HOME/bin:$HIVE_HOME/conf:$PATH
# 使修改生效
source /etc/profile
2.修改jar包
修改HADOOP_HOME\bin目录下的jline-*-jar变成HIVE_HOME\lib目录下的jar包
3.hive三种搭建方式
1. 本地模式(derby):derby与hive工具在同一个节点
缺点:不支持多个用户同时连接
2. 本地模式(mysql):mysql与hie工具在同一个节点
3. 基于MySQL的远程模式
2.本地模式(derby)
1.修改hive-site.xml
复制原有的hive-default.xml.template为hive-site.xml
hive-site.xml配置信息
<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>
2.启动hive
bin/hive
3.本地模式(Mysql)
1.在客户端节点上安装一个关系型数据库(mysql)
yum install mysql-server
2.修改MySQL权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123' WITH GRANT OPTION;
密码可自定义
3.刷新MySQL权限
flush privileges;
4.删除权限
删除多余会对权限造成影响的数据,刷新权限
#mysql数据库下的user表
select user,password from user;
删除多余会对权限造成影响的数据,刷新保留这一个用户
5.添加用户
#添加新用户
CREATE USER 'hive'@'%' IDENTIFIED BY '123';
#给新用户授权
grant all privileges on hive_meta.* to hive@"%" identified by '123';
#刷新权限
flush privileges;
密码可自定义
6.设置开机自启
chkconfig mysqld on
7.mysql驱动包
将mysql-connector-java-5.1.32-bin.jar放到HIVE_HOME\bin目录下
8.hvie-site.xml
<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_meta?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>123</value>
</property>
注意权限:前面给了hive用户对hive_meta数据库的操作权限,如果这个数据库不存在,hive用户是没有权限创建这个数据库的,需要提前创建好hive_meta数据库
注意账号密码一致
java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected at jline.TerminalFactory.create(TerminalFactory.java:101)
Hadoop jline版本和hive的jline不一致
4.基于MySQL的远程模式
1.划分
服务端 | 客户端 |
---|---|
client | node01(可多个:node02、node03等) |
2.服务端配置
hive-site.xml:与本地模式(MySQL)一样
3.客户端配置
hive-site.xml
<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://client:9083</value>
</property>
请注意客户端地址
4.启动hive
#1.client端启动metastore服务,存储元数据
hive --service metastore
#2.node01端直接使用hive命令
hive
直接使用hive命令,需要配置/etc/profile的环境变量,否则在bin目录下运行hive命令
可能出现的错误:
[ERROR] Terminal initialization failed; falling back to unsupported java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected at jline.TerminalFactory.create(TerminalFactory.java:101)
错误的原因: Hadoop jline版本和hive的jline不一致
Hive连接
1.thriftserver(hiveserver2)服务
可以通过修改hive-site.xml文件自己配置用户名、密码,需要自己编程
1.1.beeline
1.hive-site.xml
<property>
<name>hive.server2.authentication</name>
<value>CUSTOM</value>
</property>
<property>
<name>hive.jdbc_passwd.auth.zhangsan</name>
<value>123456789</value>
</property>
<property>
<name>hive.server2.custom.authentication.class</name>
<value>com.hoe.hive.authoriz.UserPasswdAuth</value>
</property>
账号密码可以自己修改,authentication.class是自己编程的Java代码
2.代码
package com.hoe.hive.authoriz;
import javax.security.sasl.AuthenticationException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hive.service.auth.PasswdAuthenticationProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserPasswdAuth implements PasswdAuthenticationProvider {
Logger logger = LoggerFactory.getLogger(UserPasswdAuth.class);
private static final String USER_PASSWD_AUTH_PREFIX = "hive.jdbc_passwd.auth.%s";
private Configuration conf = null;
@Override
public void Authenticate(String userName, String passwd) throws AuthenticationException {
logger.info("user: " + userName + " try login.");
String passwdConf = getConf().get(String.format(USER_PASSWD_AUTH_PREFIX, userName));
if (passwdConf == null) {
String message = "没有发现密码 " + userName;
logger.info(message);
throw new AuthenticationException(message);
}
if (!passwd.equals(passwdConf)) {
String message = "用户名密码不匹配 " + userName;
throw new AuthenticationException(message);
}
}
public Configuration getConf() {
if (conf == null) {
this.conf = new Configuration(new HiveConf());
}
return conf;
}
public void setConf(Configuration conf) {
this.conf = conf;
}
}
3.连接方式
#第一种
./beeline -u jdbc:hive2://node01:10000/test -n zhangsan -p123456789
#第二种
./beeline
!connect jdbc:hive2://node01:10000/test
#输入账号
#输入密码
1.2.JDBC
编写java代码
package com.hoe.hive.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ConnectHive {
public static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) {
try {
Class.forName(driverName);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String url = "jdbc:hive2://node01:10000";
String userName = "zhangsan";
String passwd = "123456789";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, userName, passwd);
Statement statement = conn.createStatement();
String sql = "select * from test.logtbl limit 10";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println(resultSet.getString(1) + "-" + resultSet.getString(2));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
注意修改ip、账号、密码
2.Web ui
1.源码包
apache-hive-1.2.1-src.tar.gz
2.将hwi war包放在HIVE_HOME\bin
将apache-hive-1.2.1-src/hwi/web/*所有文件达成war包
3.复制jdk/lib/tools.jar到HIVE_HOME/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服务(端口号9999)
hive --service hwi
6.通过浏览器来访问
http://client.9999/hwi/
Hive优化
核心思想:把Hive SQL当成MapReduce程序去优化
select仅查询本表字段、where仅对本表字段做条件过滤不会被转为MapReduce来执行
1.模式优化
开启本地模式
set hive.exec.mode.local.auto=true;
条件:
1.输入数据大小必须小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB)
2.map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4)
3.reducce数必须为0或者1
2.并行计算
set hive.exec.parallel=true;
hive.exec.parallel.thread.number是一次SQL计算中允许并行执行的job个数的最大值
3.严格模式
#默认是nonstrict,非严格模式
set hive.mapred.mode=strict;
查询限制:
1.对于分区表,必须添加where对于分区字段的条件过滤
2.order by语句必须包含limit输出限制
3.限制执行笛卡尔积的查询
4.Hive排序
Order By - 对于查询结果做全排序,只允许有一个reduce处理。当数据量较大时,应慎用。严格模式下,必须结合limit来使用
Sort By - 对于单个reduce的数据进行排序
Distribute By - 分区,经常和Sort By结合使用达到分区排序的效果
Cluster By - 相当于 Sort By + Distribute By。不能通过asc、desc的方式指定排序规则,可通过 distribute by column sort by column asc|desc 的方式
5.Hive Join
Join计算时,将小表(驱动表)放在join的左边
Map Join:在Map端完成Join
#第一种:SQL方式,在SQL语句中添加MapJoin表级
SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value
FROM smallTable JOIN bigTable ON smallTable.key = bigTable.key;
#第二种,开启自动的MapJoin
set hive.auto.convert.join = true;
6.Map-Site聚合
#设置Map端的聚合combiner
set hive.map.aggr=true;
7.Hive-JVM重用
适用场景:
1.小文件个数过多
2.task个数过多
set mapred.job.reuse.jvm.num.tasks=n;
#n为task插槽个数
缺点:设置开启之后,task插槽会一直占用资源,不论是否有task运行,直到所有的task即整个job全部执行完成时,才会释放所有的task插槽资源!