构建数据仓库Hive

    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插槽资源!

猜你喜欢

转载自blog.csdn.net/love__guo/article/details/83313553