Hive数据仓库工具

Hive

Hive基本概念

Hive简介

  • 什么是Hive

    • 将SQL转换为MapReduce的任务的工具,甚至更近一步可以说hive就是一个MapReduce客户端
    • 本质是将SQL转换为MapReduce的任务进行运算,底层由HDFS来提供数据存储
  • 为什么要使用Hive

    • 直接使用hadoop

      • 1)人员学习成本太高
      • 2)项目要求周期太短
      • 3)MapReduce实现复杂查询逻辑开发难度太大
    • 使用Hive

      • 1)操作接口采用类SQL语法,提供快速开发能力
      • 2)免去了写MapReduce,减少开发人员学历成本
      • 3)功能扩展很方便
  • Hive特点

    • 可扩展性

      • Hive可以自由的扩展集群的规模,一般情况下不需要重启服务
    • 延伸性

      • Hive支持自定义函数,用户可以根据自己的需要来实现自己的函数
    • 容错

      • 即使节点出现错误,SQL仍然可以完成执行
  • Hive优缺点

    • 优点

        1. 操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)。
        1. 避免了去写MapReduce,减少开发人员的学习成本。
        1. Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。
        1. Hive优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高。
        1. Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。
        1. 集群可自由拓展并且具有良好的容错性,节点出现问题SQL仍可完成执行。
    • 缺点

        1. Hive的HQL表达能力有限
        • (1)迭代式算法无法表达
        • (2)数据挖掘方面不擅长
        1. Hive的效率比较低
        • (1)Hive自动生成的MapReduce作业,通常情况下不够智能化
        • (2)Hive调优比较困难,粒度较粗
  • Hive应用场景

    • 日志分析:大部分互联网公司使用hive进行日志分析,包括百度、淘宝等。

      • 统计网站一个时间段内的pv、uv
      • 多维度数据分析
    • 海量结构化数据离线分析

Hive架构

  • 架构图

  • 架构细节

    • Client

      • 连接的方式

        • CLI(hive shell)
        • JDBC/ODBC(java访问hive)
        • WEBUI(浏览器访问hive)
    • Metastore

      • 元数据
      • 一般需要借助于其他的数据载体(数据库)
      • 主要用于存放数据库的建表语句等信息
      • 推荐使用Mysql数据库存放数据
      • 连接数据库需要提供:uri username password driver
    • Driver

      • 元数据存储在数据库中,默认存在自带的derby数据库
      • (1) 解析器(SQL Parser):将SQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如ANTLR;对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
      • (2) 编译器(Physical Plan):将AST编译生成逻辑执行计划。
      • (3) 优化器(Query Optimizer):对逻辑执行计划进行优化。
      • (4) 执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于Hive来说,就是MR/Spark。
    • 数据处理

      • Hive的数据存储在HDFS中,计算由MapReduce完成

Hive三种交互方式

  • 第一种

    • shell交互Hive,用命令hive启动一个hive的shell命令行,在命令行中输入sql或者命令来和Hive交互
    • 服务端启动metastore服务:nohup hive --service metastore > /dev/null 2>&1 &
    • 进入命令:hive
    • 退出命令行:quit;
  • 第二种

    • Hive启动为一个服务器,对外提供服务,其他机器可以通过客户端通过协议连接到服务器,这是生产环境用法最多的

    • 服务端启动hiveserver2服务:

      • nohup hive --service metastore > /dev/null 2>&1 &
      • nohup hiveserver2 > /dev/null 2>&1 &
    • 进入命令

      • 1)先执行beeline,在执行! connect jdbc:hive2://node01:10000
      • 2)或者直接执行 beeline -u jdbc:hive2://node01:10000 -n root
  • 第三种

    • 使用 –e 参数来直接执行hql的语句

      • bin/hive -e “show databases;”

Hive元数据

  • Hive元数据库中一些重要的表结构及用途,方便Impala、SparkSQL、Hive等组件访问元数据库的理解

Hive基本操作

Hive库的操作

  • 创建数据库

    • 默认存储路径是/hive/warehouse/*.db

      • create database shop;
    • 避免要创建的数据库已经存在错误,增加if not exists判断。(标准写法)

      • create database if not exists shop;
  • 创建数据库和位置

    • create database if not exists school location ‘/school.db’;
  • 修改数据库

    • 使用ALTER DATABASE命令为某个数据库的DBPROPERTIES设置键-值对属性值

      • alter database school set dbproperties(‘createtime’=‘20201213’);
  • 数据库详细信息

    • 显示数据库(show)

      • show databases;
    • 可以通过like进行过滤

      • show databases like ‘s*’;
    • 查看详情(desc)

      • desc database school;
    • 切换数据库(use)

      • use school;
  • 删除数据库

    • 最简写法

      • drop database school;
    • 如果删除的数据库不存在,最好使用if exists判断数据库是否存在

      • drop database if exists school;
    • 如果数据库不为空,使用cascade命令进行强制删除

      • drop database if exists school cascade;

Hive数据类型

  • 基础数据类型

    • 类似Java
  • 复杂数据类型

    • Hive有三种复杂数据类型ARRAY、MAP 和 STRUCT。ARRAY和MAP与Java中的Array和Map类似,而STRUCT与C语言中的Struct类似,它封装了一个命名字段集合,复杂数据类型允许任意层次的嵌套。
    • ARRAY
    • MAP
    • STRUCT

Hive表操作

  • 创建表

  • 显示表

    • show tables;
    • show tables like ‘u’;
    • desc t_person;
    • desc formatted t_person;
  • 重命名

    • alter table old_table_name rename to new_table_name;
  • 修改列

    • 查询表结构

      • desc test_new;
    • 添加列

      • alter table test_new add columns (education string);
    • 更新列

      • alter table test_new change education educationnew string;
  • 删除表

    • drop table test_new;

      • 表和数据都被删除
    • truncate table test_new

      • 截断表,不开启事务,不可恢复(清空表)

Hive内外部表

  • 内部表

    • 创建表的时候会在库中默认创建一个同名的文件夹,
    • 当load数据的时候会将数据剪切到文件夹中
    • 当我们用SQL处理数据的时候默认处理表对应文件夹中的数据,
    • 当表被删除的时候数据也会被删除,
    • 如果多个业务共同处理相同数据,无法对数据进行共享,
    • 三个项目组对数据进行共享,如果-个项目组将数据删除,会有数据不安全的情况
  • 外部表

    • 外部表一般在创建的时候直接将文件夹路径指向要分析数据的路径
    • 当我们删除表与数据映射结构的时候,数据不会被销毁

Hive载入数据

  • 加载linux本地数据

    • 切记必须和hiveserver2在同一个节点才可以上传
    • load data local inpath ‘/root/user.txt’ into table t_user;
  • 加载HDFS数据

    • load data inpath ‘/yjx/user.txt’ into table t_user;
  • 加载并覆盖已有数据

    • load data inpath ‘/yjx/user.txt’ overwrite into table t_user;
  • 通过查询插入数据

    • 将查询结果插入一张表

      • insert overwrite table t_user1 select id,uname from t_user;
    • 将查询结果一次性存放到多张表

      • from t_user
        insert overwrite table t_user1 select id,uname
        insert overwrite table t_user2 select id,pwd;

Hive导出数据

  • 将表中的数据备份

    • 将查询结果存放到本地

      • insert overwrite local directory ‘/root/person_data’ select * from t_person;
    • 按照指定的方式将数据输出到本地

      //导出查询结果的数据
      insert overwrite local directory ‘/root/yjx/person’
      ROW FORMAT DELIMITED fields terminated by ‘,’
      collection items terminated by ‘-’
      map keys terminated by ‘:’
      lines terminated by ‘\n’
      select * from t_person;

    • 将查询结果输出到HDFS

      //导出查询结果的数据
      insert overwrite directory ‘/yjx/copy/user’
      ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’
      select * from t_user;

  • 直接使用HDFS命令保存表对应的文件夹

    • //使用HDFS命令拷贝文件到其他目录
    • hdfs dfs -cp /hive/warehouse/t_person/* /yjx/person
  • 将表结构和数据同时备份

    • 导出

      • //导出查询结果的数据
      • export table t_person to ‘/yjx/copy’;
    • 恢复

      • import from ‘/yjx/copy’;
      • 需要注意的是:时间不同步,会导致导入导出失败

Hive分区表

  • 静态动态分区的特点

    • 静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。
    • 详细来说,静态分区的列是在编译时期通过用户传递来决定的;动态分区只有在SQL执行时才能决定
  • 静态分区

    • 单分区表

      CREATE TABLE IF NOT EXISTS t_student (
      sno int,
      sname string
      ) partitioned by(grade int)
      row format delimited fields terminated by ‘,’;

      –载入数据
      load data inpath ‘/yjx/student.txt’ into table t_student partition(grade=1);

      • 分区的字段不要和表的字段相同。相同会报错error10035
    • 多分区表

      CREATE TABLE IF NOT EXISTS t_teacher (
      tno int,
      tname string
      ) partitioned by(grade int,clazz int)
      row format delimited fields terminated by ‘,’;

      –载入数据
      load data inpath ‘/yjx/teacher11.txt’ into table t_teacher
      partition(grade=1,class=1);

      • –注意:前后两个分区的关系为父子关系,也就是grade文件夹下面有多个clazz子文件夹。
    • 分区表查询

      • select * from t_student where grade = 1 ;
    • 查看分区

      • show partitions t_student;
    • 添加分区

      • alter table t_student add partition (day=‘99990102’);
      • alter table t_student add partition (day=‘99990103’) location ‘99990103’;
    • 删除分区

      • alter table salgrade2 drop partition (day=‘99990102’);
  • 动态分区

    • 开启动态分区首先要在hive会话中设置如下的参数

      • set hive.exec.dynamic.partition=true;
      • set hive.exec.dynamic.partition.mode=nonstrict;
    • 如果静态分区的话,我们插入数据必须指定分区的值。

    • 如果想要插入多个班级的数据,我要写很多SQL并且执行24次很麻烦。

    • 而且静态分区有可能会产生数据错误问题

    • –创建分区表
      CREATE TABLE IF NOT EXISTS t_student_d (
      sno int,
      sname string
      ) partitioned by (grade int,clazz int)
      row format delimited fields terminated by ‘,’;
      –创建外部表
      CREATE EXTERNAL TABLE IF NOT EXISTS t_student_e (
      sno int,
      sname string,
      grade int,
      clazz int
      )
      row format delimited fields terminated by ‘,’
      location “/yjx/student”;

    • 如果使用动态分区,动态分区会根据select的结果自动判断数据应该load到哪儿分区去。

      insert overwrite table t_student_d partition (grade,clazz) select * from
      t_student_e ;

分桶表

  • 特点

    • 分桶是将数据集分解为更容易管理的若干部分的另-种技术。
    • 分桶就是将数据按照字段进行划分,可以将数据按照字段划分到多个文件当中去。
    • 计算数据列的hashcode,然后对桶的数据进行取余
    • 桶的个数尽可能多的是拥有因数12,方便数据取样计算
  • 原理

    • Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中
  • 优势

    • 方便抽样
    • 提高join查询效率
  • 实战

    • 开启分桶功能

      • set hive.enforce.bucketing=true;
    • 设置Reduce个数我们需要确保reduce 的数量与表中的bucket 数量一致

      • set mapreduce.job.reduce=3;
    • – 创建表
      CREATE TABLE t_citizen_bucket(
      idcard int,
      pname string,
      province int
      )clustered by(idcard) sorted by (pname desc) into 16 buckets
      row format delimited fields terminated by ‘,’
      lines terminated by ‘\n’;
      create EXTERNAL table t_citizen(
       idcard int,
       pname string,
       province int
      )row format delimited fields terminated by ‘,’
      lines terminated by ‘\n’
      location ‘/yjx/citizen’;
      – 数据导入
      for (int i = 1000; i < 10000; i++) {
      System.out.println(i + “,” + “admin” + (new Random().nextInt(89999) +

        • “,” + i % 34);
          }
          – 将外部表的数据导入到分桶表
          insert overwrite table t_citizen_bucket select * from t_citizen ;
  • 数据抽样算法

    • 数据块抽样

      • 该方式允许Hive随机抽取N行数据,数据总量的百分比(n百分比)或N字节的数据。

        • SELECT * FROM <Table_Name> TABLESAMPLE(N PERCENT|ByteLengthLiteral|N ROWS) s;
    • 桶表抽样

      • TABLESAMPLE(BUCKET x OUT OF y)

        • x表示从哪个bucket开始抽取。
        • y必须是table总bucket数的倍数或者因子
        • 例如,table总共分了64份,当y=32时,抽取(64/32=)2个bucket的数据,当y=128时,抽(64/128=)1/2个bucket的数据取
        • select * from t_citizen_bucket tablesample(bucket 1 out of 16 on idcard);
        • select * from t_citizen_bucket tablesample(bucket 2 out of 4 on idcard);
    • 随机抽样

      • 使用RAND()函数和LIMIT关键字来获取样例数据,使用DISTRIBUTE和SORT关键字来保证数据是随机分散到mapper和reducer的

        • SELECT * FROM <Table_Name> DISTRIBUTE BY RAND() SORT BY RAND() LIMIT ;
        • select * from t_citizen_bucket DISTRIBUTE BY RAND() SORT BY RAND() LIMIT 10;

Hive查询语法

Hive独特的排序

  • 全局排序

    • order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间

    • 多个列排序

      • order by cs,grade;
  • 局部排序

    • sort by 不是全局排序,其在数据进入reducer前完成排序。

    • 如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by 只保证每个reducer的输出有序,不保证全局有序。

    • 步骤

      • 设置reduce个数

        • set mapreduce.job.reduce=3;
      • 查看reduce个数

        • set mapreduce.job.reduce;
      • 排序

        • select * from t_student_d sort by sname;
      • 将查询结果导入到文件中

        • insert overwrite local directory ‘/root/student’ select * from t_student_d
          sort by clazz asc, grade desc;
  • 分区排序

    • 概述

      • distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列。
      • 类似MR中partition,进行分区,结合sort by使用。(注意:distribute by 要在sort by之前)
      • 对于distrbute by 进行测试,一定要多分配reduce进行处理,否则无法看到distribute by的效果
    • 步骤

      • 设置reduce个数

        • set mapreduce.job.reduce=7;
      • 排序

        • insert overwrite local directory ‘/data/student’ select * from t_student_d
          distribute by sname;
  • 分区并排序

    • cluster by(字段)除了具有Distribute by的功能外,还会对该字段进行排序
    • cluster by = distribute by + sort by 只能默认升序,不能使用倒序
    • select * from t_student_d sort cluster by sname;
    • select * from t_student_d distribute by sname sort by sname;

Hive内置函数

  • 内置函数

    • 查看系统自带函数

      • show functions;
    • 显示自带的函数的用法

      • desc function upper;
    • 详细显示自带的函数的用法

      • desc function extended upper;
  • 内置函数的分类

    • 关系操作符

    • 算数操作符

    • 逻辑操作符

    • 复杂类型构造函数

    • 复杂类型操作符

    • 数学操作符

    • 集合操作符

    • 类型转换函数

      • 日期函数
    • 日期函数

    • 条件函数

    • 字符串函数

  • 独树一帜的UDTF

    • explode 可以将一组数组的数据变成一列表

      • select explode(split(types,"-")) from t_movie1;
    • lateral view 表生成函数,可以将explode的数据生成一个列表

      • select id,name,type from t_movie1,lateral view explode(split(types,"-"))typetable as type;
    • collect_set()和collect_list()都是对列转成行,区别就是list里面可重复而set里面是去重的

    • concat_ws(’:’,collect_set(type))  ‘:’ 表示你合并后用什么分隔,collect_set(stage)表示要合并表中的那一列数据

    • collect_set(stage)表示要合并表中的那一列数据

    • select id,concat_ws(’:’,collect_set(type)) as types from t_movie2 group byid;

Hive窗口函数

  • 概述

    • 普通的聚合函数每组(Group by)只返回一个值,而开窗函数则可为窗口中的每行都返回一个值。
    • 简单理解,就是对查询的结果多出一列,这一列可以是聚合值,也可以是排序值。
    • 开窗函数一般就是说的是over()函数,其窗口是由一个 OVER 子句 定义的多行记录
    • 开窗函数一般分为两类,聚合开窗函数和排序开窗函数
  • 聚合开窗函数

    • 可将普通列与聚合列放在一起使用

    • rows必须跟在Order by 子句之后,对排序的结果进行限制,使用固定的行数来限制分区中的数据行数量

      • OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
      • CURRENT ROW:当前行
      • n PRECEDING:往前n行数据
      • n FOLLOWING:往后n行数据
      • UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDEDFOLLOWING表示到后面的终点
    • LAG(col,n,default_val):往前第n行数据,col是列名,n是往上的行数,当第n行为null的时候取default_val

    • LEAD(col,n, default_val):往后第n行数据,col是列名,n是往下的行数,当第n行为null的时候取default_val

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

    • cume_dist(),计算某个窗口或分区中某个值的累积分布。假定升序排序,则使用以下公式确定累积分布

      • 小于等于当前值x的行数 / 窗口或partition分区内的总行数。其中,x 等于 order by 子句中指定的列的当前行中的值
  • 排序开窗函数

    • RANK() 排序相同时会重复,总数不会变
    • DENSE_RANK() 排序相同时会重复,总数会减少
    • ROW_NUMBER() 会根据顺序计算
    • percent_rank() 计算给定行的百分比排名。可以用来计算超过了百分之多少的人

自定义函数

  • UDF(User-Defined-Function) 单行函数,一进一出

    • size/sqrt
  • UDAF(User- Defined Aggregation Funcation) 聚集函数,多进一出。

    • count/max/min/sum/avg
  • UDTF(User-Defined Table-Generating Functions) 一进多出

    • lateral view explode()

Hive文件存储格式

文件存储方式

  • 行式存储格式,便于按照ID查询

    • 特点

      • 相关数据保存在一起,数据读取的时候以行为单位读取的
    • 优点:这种存储格式简单、方便写入数据 。

    • 缺点:不支持压缩、并且不支持列裁剪,数据分析开销较大

    • 文件格式:TextFile、SequenceFile

  • 列式存储格式,只是针对数据的某些字段进行查询

    • 特点

      • 将不同的列存放在不同的块中
    • 优点:支持列裁剪、减少数据查询范围,数据支持压缩,节省空间。

    • 缺点:写入数据相对困难,并且查询整行数据时,开销相对较大。

    • 文件格式:ORC、PARQUET、RCFILE

文件存储格式

  • TextFile

    • 行存储
    • Hive默认格式,数据不做压缩,磁盘开销大,数据解析开销大
  • SequenceFile

    • 行存储
    • Hadoop API 提供的一种二进制文件,它将数据以<key,value>的形式序列化到文件中
    • 内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化
  • RCFile

    • 一种专门面向列的数据格式
    • 它遵循“先按列划分,再垂直划分”的设计理念。
    • 当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。
  • ORC

    • 并不是一个单纯的列式存储格式,仍然是首先根据行组分割整个表,在每一个行组内进行按列存储

数据倾斜

定义

  • 单个节点任务所处理的数据量远大于同类型任务所处理的数据量,导致该节点成为整个作业的瓶颈

本质原因

  • 一是任务读取大文件,最常见的就是读取压缩的不可分割的大文件。
  • 二是任务需要处理大量相同键的数据
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值