数据分析引擎:Hive

什么是Hive

定义了一种类SQL语言HiveQL。可以看成是仍SQL到Map-Reduce的映射器

Hive 将元数据存储在数据库中(metastore),目前只支持 mysql、derby。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。

Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成(包含 * 的查询,比如 select * from table 不会生成 MapRedcue 任务)

1、Hive是一个翻译器,SQL ---> Hive引擎  ---> MR程序

2、Hive是构建在HDFS上的一个数据仓库(Data Warehouse)

  Hive       HDFS
  表         目录
  分区       目录
  数据       文件
  桶         文件

Hive的体系结构

安装和配置

1解压:jiaytar -zxvf apache-hive-2.3.0-bin.tar.gz -C ~/training/
2设置环境变量 
    HIVE_HOME=/root/training/apache-hive-2.3.0-bin
    export HIVE_HOME
    PATH=$HIVE_HOME/bin:$PATH
    export PATH
3核心配置文件: conf/hive-site.xml
    嵌入模式 不需要MySQL的支持,使用Hive的自带的数据库Derby 局限:只支持一个连接
			<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>file:///root/training/apache-hive-2.3.0-bin/warehouse</value>
			</property>
			</configuration>
            初始化Derby数据库:
			    which schematool   查找命令地址
				schematool -dbType derby -initSchema
			启动 : hive
    远程模式:需要MySQL
                <configuration>
				<property>
				   <name>javax.jdo.option.ConnectionURL</name>
				   <value>jdbc:mysql://localhost:3306/hive?useSSL=false</value>
				</property>
				<property>
				   <name>javax.jdo.option.ConnectionDriverName</name>
				   <value>com.mysql.jdbc.Driver</value>
				</property>
				<property>
					<name>javax.jdo.option.ConnectionUserName</name>
					<value>hiveowner</value>
				</property>
				<property>
					<name>javax.jdo.option.ConnectionPassword</name>
					<value>Welcome_1</value>
				</property>
				</configuration>
            将mysql的jar包放到lib目录下 一定要使用高版本的MySQL驱动(5.1.43以上的版本)
            初始化MySQL
                老版本:当第一次启动HIve的时候 自动进行初始化
                新版本:schematool -dbType mysql -initSchema

Hive的数据类型

  1. 基本数据类型
    1. tinyint/smallint/int/bigint:整数类型
    2. float/double:浮点数类型
    3. boolean:布尔类型
    4. string:字符串类型
  2. 复杂数据类型
    1. Array:数组类型,由一系列相同数据类型的元素组成
    2. Map:集合类型,包含key->value键值对,可以通过key来访问元素。
    3. Struct:结构类型,可以包含不同数据类型的元素。这些元素可以通过”点语法”的方式来得到所需要的元素
  3. 时间类型
    1. Date:从Hive0.12.0开始支持
    2. Timestamp:从Hive0.8.0开始支持

Hive的数据模型

Hive的数据存储

  1. 基于HDFS
  2. 没有专门的数据存储格式
  3. 存储结构主要包括:数据库、文件、表、视图
  4. 可以直接加载文本文件(.txt文件)
  5. 创建表时,指定Hive数据的列分隔符与行分隔符

注意:默认:列的分隔符是tab键(制表符),建表时需要指定分隔符

测试数据:员工表和部门表
    7654,MARTIN,SALESMAN,7698,1981/9/28,1250,1400,30

内部表

  1. 与数据库中的 Table 在概念上是类似
  2. 删除表时,元数据与数据都会被删除
  3. 所有的 Table 数据(不包括 External Table)都保存在这个目录中
  4. 每一个 Table 在 Hive 中都有一个相应的目录存储数据
create table emp
   (empno int,
	ename string,
	job string,
	mgr int,
	hiredate string,
	sal int,
	comm int,
	deptno int) row format delimited fields terminated by ',';
--按照条件查询结果存储到新表
create table if not exists emp_2 as select * from emp where ename ='tongla';
--查询结果导出到本地
insert overwrite local directory '/root/datas/yangmi.txt' select * from emp where ename ='tongla';

导入数据

load data inpath '/scott/emp.csv' into table emp;    --导入HDFS的数据
load data inpath '/scott/emp.csv' overwrite into table emp;    --导入HDFS的数据 并覆盖原数据
load data local inpath '/root/temp/*****' into table emp;    --导入本地Linux的数据

分区表: 可以提高查询的效率的----> 通过查看SQL的执行计划

  1. Partition 对应于数据库的 Partition 列的密集索引
  2. 在 Hive 中,表中的一个 Partition 对应于表下的一个目录,所有的 Partition 的数据都存储在对应的目录中
create table emp_part
(empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int)
partitioned by (deptno int) 
row format delimited fields terminated by ',';

--添加分区
alter table emp_part add partition(deptno ='1113');
--查询表结构
desc formatted emp_part;
--修改表名
alter table emp_part rename to new_table_name;
--添加列
alter table emp_part add columns(desc string);
--更新列
alter table emp_part change column desc desccc int;
--替换
alter table emp_part replace column(desccc int);

指明导入的数据的分区(通过子查询导入数据) ----> MapReduce程序

insert into table emp_part partition(deptno=10) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=10;
insert into table emp_part partition(deptno=20) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=20;
insert into table emp_part partition(deptno=30) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=30;

外部表

  1. 指向已经在 HDFS 中存在的数据,可以创建 Partition
  2. 它和内部表在元数据的组织上是相同的,而实际数据的存储则有较大的差异
  3. 外部表 只有一个过程,加载数据和创建表同时完成,并不会移动到数据仓库目录中,只是与外部数据建立一个链接。当删除一个外部表时,仅删除该链接
create external table students_ext 
(sid int,sname string,age int)
row format delimited fields terminated by ','
location '/students1'; 

桶表

  1. 桶表是对数据进行哈希取值,然后放到不同文件中存储。
  2. 需要设置环境变量:set hive.enforce.bucketing = true;
create table emp_bucket
(empno int,
ename string,
job string,
mgr int,
hiredate string,
sal int,
comm int,
deptno int)
clustered by (job) into 4 buckets 
row format delimited fields terminated by ',';	

通过子查询插入数据

insert into emp_bucket select * from emp1;

视图(View

  1. 视图是一种虚表,是一个逻辑概念;可以跨越多张表
  2. 视图建立在已有表的基础上, 视图赖以建立的这些表称为基表
  3. 视图可以简化复杂的查询
create view myview
	as	
	select dept.dname,emp1.ename
	from emp1,dept
	where emp1.deptno=dept.deptno;

使用sqoop导入关系型数据库中的数据

	将关系型数据的表结构复制到hive中
sqoop create-hive-table --connect jdbc:mysql://localhost:3306/test --table username --username root --password 123456 --hive-table test
其中 --table username为mysql中的数据库test中的表   --hive-table test 为hive中新建的表名称
	从关系数据库导入文件到hive中
sqoop import --connect jdbc:mysql://localhost:3306/test --username root --password mysql-password --table t1 --hive-import
	将hive中的表数据导入到mysql中
sqoop export --connect jdbc:mysql://localhost:3306/test --username root --password admin --table uv_info --export-dir /user/hive/warehouse/uv/dt=2011-08-03

Hive的查询

1、查询所有的员工信息
    select * from emp1;
2、查询员工信息:员工号 姓名 薪水
    select empno,ename,sal from emp1;
3、多表查询  部门名称  员工姓名
	select dept.dname,emp1.ename
	from emp1,dept
	where emp1.deptno=dept.deptno;	
4、子查询:
    hive只支持:from和where子句中的子查询
5、条件函数:  case .... when ....(Oracle中叫条件表达式)
              是标准的SQL语句
			  就是在SQL中实现一个if  else 逻辑
    举例:做报表,根据职位给员工涨工资
	      PRESIDENT  1000
		  MANAGER    800
		  其他       400
		  把涨前、涨后的薪水显示出来
			select empno,ename,job,sal,
			case job when 'PRESIDENT' then sal+1000
					 when 'MANAGER' then sal+800
					 else sal+400
			end 
			from emp1;

Hive的Java API:本质就是JDBC程序

  1. 首先启动Hive远程服务:hiveserver2 &
  2. 需要Hive lib目录下的jar

如出现错误  : User: root is not allowed to impersonate anonymous
修改hadoop 配置文件 etc/hadoop/core-site.xml,加入如下配置项

<property>
  <name>hadoop.proxyuser.root.hosts</name>
  <value>*</value>
</property>
<property>
  <name>hadoop.proxyuser.root.groups</name>
  <value>*</value>
</property>
*
 * 工具类:
 * 1、获取数据库Hive链接
 * 2、释放资源
 */
public class JDBCUtils {

	//Hive数据库的驱动
	private static String driver = "org.apache.hive.jdbc.HiveDriver";                                
	//Hive位置
	private static String url = "jdbc:hive2://192.168.157.111:10000/default";
	//注册驱动
	static{
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new ExceptionInInitializerError(e);
		}
	}
	//获取链接
	public static Connection getConnection(){
		try {
			return DriverManager.getConnection(url);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static void release(Connection conn,Statement st,ResultSet rs){
		if(rs != null){
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}finally{
				rs = null;
			}
		}
		if(st != null){
			try {
				st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}finally{
				st = null;
			}
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}finally{
				conn = null;
			}
		}
	}
}
public class TestMain {
	public static void main(String[] args) {
		String sql = "select * from mytest1";
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try{
			//获取链接
			conn = JDBCUtils.getConnection();
			//得到运行环境
			st = conn.createStatement();
			//运行SQL
			rs = st.executeQuery(sql);
			//处理
			while(rs.next()){
				//取员工姓名, 不能通过列名来取,通过序号
				int id = rs.getInt("tid");
				String name = rs.getString("tname");
				System.out.println(id+"\t"+name);
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			//释放资源
			JDBCUtils.release(conn, st, rs);
		}
	}
}

Hive的自定义函数

1Hive的自定义函数(UDF): User Defined Function
    可以直接应用于select语句,对查询结构做格式化处理后,再输出内容
2Hive自定义函数的实现细节
    自定义UDF需要继承org.apache.hadoop.hive.ql.UDF
    需要实现evaluate函数,evaluate函数支持重载
3Hive自定义函数的部署
    把程序打包放到目标机器上去
    进入hive客户端,添加jar包:
        hive> add jar /root/temp/udf.jar;
4创建临时函数:
    create temporary function myconcat as 'udf.MyConcatString';
    create temporary function checksal as 'udf.CheckSalaryGrade';
5Hive自定义函数的调用
    查询HQL语句:
        select myconcat(ename,job) from emp;
        select ename,sal, checksal (sal) from emp;
销毁临时函数:
    hive> DROP TEMPORARY FUNCTION checksalary;

Hive优化

压缩

开启Map阶段输出压缩
    开启输出压缩功能:set hive.exec.compress.intermediate=true;
    开启map输出压缩功能:set mapreduce.map.output.compress=true;
    设置压缩方式:
        set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

开启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;

存储:
    Hive存储格式:TextFile/SequenceFile/orc/Parquet
            orc:Index Data/row Data/stripe Footer
    压缩比:
            orc > parquet > textFile
    查询速度:
            orc > textFile
Group by优化:
    分组:mr程序,map阶段把相同key的数据分发给一个reduce,一个key的量很大。
    解决方案:
        在map端进行聚合(combiner) set hive.map.aggr=true;
        设置负载均衡  set hive.groupby.skewindata=true;
数据倾斜:
    合理避免数据倾斜
        合理设置map数 
        合并小文件 
        set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
        合理设置reduce数
    解决数据倾斜
        在map端进行聚合(combiner) set hive.map.aggr=true;
        设置负载均衡  set hive.groupby.skewindata=true;
        JVM重用 mapred-site.xml
                mapreduce.job.jvm.numtasks    10~20

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值