扎实Hive基础

Hive的基本简介

1)Hive是什么?
Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为
一张数据库表,并提供类 SQL 查询功能。Hive 利用 HDFS 存储数据,利用 MapReduce 查询分析数据。
本质是将 SQL 转换为 MapReduce 程序,比直接用 MapReduce 开发效率更高。
2)Hive的源数据存储?
通常是存储在关系数据库如 mysql/derby 中。 Hive 将元数据存储在数据库中。 Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。
3)Hive与传统DB的区别?
传统数据库:OLTP-->面向事务(Transaction) 操作型处理 就是关系型数据库:mysql oracle sqlserver db2 主要是支持业务,面向业务。
Hive:OLAP-->面向分析(Analytical)分析型处理 就是数据仓库 面对的是历史数据(历史数据中的一部分就来自于数据库) 开展分析


image.png

2Hive数仓开发的基本流程。

1)从业务系统获取数据

Sqoop 导入数据库的数据:spoop可以在 Hive与传统的数据库间进行数据的传递,可以将一个关系型数据库中的数据导进到Hadoop的HDFS中,也可以将HDFS的数据导进到关系型数据库中。
Flume 采集文本数据:Flume可以将各类型的文件进行采集,存放入hdfs中。
Ftp 文件服务器:从文件服务器上下载分析所需的源数据(增量数据、全量数据)。如下图所示:


image.png

image.png
2)数据存储

数据仓库分层 ods层、dw层、da层:

源数据层 ODS :直接引用外围的数据 没有统一格式化的 不会直接应用使用 不利于分析

数据仓库层 DW :来自于ODS 要经过ETL的过程 格式统一 数据规整 干净清洁

数据应用层 DA :要去用DW层数据 真正的数据使用者。

数据集市:
数据集市也叫数据市场,数据集市就是满足特定的部门或者用户的需求,按照多维的方式进行存储,包括定义维度、需要计算的指标、维度的层次等,生成面向决策分析需求的数据立方体。

3)写sql开发需求
4)配置调度系统
5)导出数据&展示

Hive sql 知识点

1)DML&DDL

DML:数据操纵语言 ,负责对数据库对象运行数据访问工作的指令集DELETE FROM table_name;
DDL:数据定义语言,用语定义和管理数据库中的对象。
TRUNCATE TABLE table_name;

2)外表和内表

内部表:
create table student(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',';
未被external修饰、表数据由Hive自身管理、表数据存储的位置是默认的hive.metastore.warehouse.dir 、删表会直接删除元数据及存储数据、对表的修改会将修改直接同步给元数据的是内部表
外部表:
create external table student_ext(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',' location '/stu';
被external修饰的、表数据由HDFS管理、表数据的存储位置由自己指定、删表仅仅会删除元数据,HDFS上的文件并不会被删除的是外部表。

3)分区、分桶
分区(重点)
为了避免select查询时候的全表扫描问题 hive提出了分区表(partitioned by)概念 给文件归类 打上标识(标识不能为表中已有的字段)
静态分区:
单分区建表 create table par_tab (name string,nation string) partitioned by (sex string) row format delimited fields terminated by ',';

加载 load data local inpath '/home/hadoop/files/par_tab.txt' into table par_tab partition (sex='man');
在新建分区表的时候,系统会在hive数据仓库默认路径/user/hive/warehouse/下创建一个目录(表名),再创建目录的子目录sex=man(分区名),最后在分区名下存放实际的数据文件。

多分区建表create table par_tab_muilt (name string, nation string) partitioned by (sex string,dt string) row format delimited fields terminated by ',' ;

加载:load data local inpath '/home/hadoop/files/par_tab.txt' into table par_tab_muilt partition (sex='man',dt='2018-05-26');

新建表的时候定义的分区顺序,决定了文件目录顺序(谁是父目录谁是子目录),因为有了这个层级关系,当我们查询所有man的时候,man以下的所有日期下的数据都会被查出来。如果只查询日期分区,但父目录sex=man和sex=woman都有该日期的数据,那么Hive会对输入路径进行修剪,从而只扫描日期分区,性别分区不作过滤(即查询结果包含了所有性别)。
动态分区
静态分区在插入的时候必须首先要知道有什么分区类型,而且每个分区写一个load data,太烦人。使用动态分区可解决以上问题,其可以根据查询得到的数据动态分配到分区里。其实动态分区与静态分区区别就是不指定分区目录,由系统自己选择。
`开启动态分区功能set hive.exec.dynamic.partition=true;

加载数据 insert overwrite table par_dnm partition(sex='man',dt) select name, nation, dt from par_tab;

注:
1.动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区。
2.动态分区可以允许所有的分区列都是动态分区列,但是要首先设置一个参数
hive.exec.dynamic.partition.mode 。 set hive.exec.dynamic.partition.mode; hive.exec.dynamic.partition.mode=strict
它的默认值是strick,即不允许分区列全部是动态的,这是为了防止用户有可能原意是只在子分区内进行动态建分区,但是由于疏忽忘记为主分区列指定值了,这将导致一个dml语句在短时间内创建大量的新的分区(对应大量新的文件夹),对系统性能带来影响。修改后即可。
set hive.exec.dynamic.partition.mode=nostrick;
总结:
1、分区表是为了减少查询时候的全表扫描而出现。
2、分区表的现象就是在表的文件夹下多了一个文件夹 而文件夹的名字就是分区 字段=分区值
3、分区字段的值在查询的时候 会显示出来 但是并不代表结构化数据中有这个字段 分区字段是一个虚拟字段 只是用来标识文件
方便用户查询的时候 根据这个标识进行过滤 从而减少了全局扫描
4、分区表的数据通过load data的方式加载 加载的时候要指定分区的值(这个分区的值就是这批数据文件夹名字的值)
5、关于分区字段一定不会是表中存在的字段 如果是直接编译报错 体会什么叫给数据打标识
分桶
1.为了提高join查询时的效率 减少了笛卡尔积的数量,分桶表出现。
clustered by (字段) into num_buckets buckets(如:clustered by (sex) into 2 buckets)
2.分桶的功能默认不开启 需要自己手动开启 set hive.enforce.bucketing = true;
3.分成几桶 也需要自己指定 set mapreduce.job.reduces=N;
4.分通表导入数据的方式:insert+select insert数据来自于后select查询的结果
insert overwrite table stu_buck select * from student cluster by(Sno);

1. 什么是UDF

当 Hive 提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF: user-defined function)。

2.UDF开发步骤示例

新建 JAVA maven 项目
添加 hive-exec-1.2.1.jar 和 hadoop-common-2.7.4.jar 依赖(见参考资料)
1、 写一个 java 类,继承 UDF,并重载 evaluate 方法

package cn.itcast.bigdata.udf
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
 public class Lower extends UDF{
   public Text evaluate(Text s){
     if(s==null){return null;}
     return new Text(s.toString().toLowerCase());
  }
}



Hive的架构


image.png
Hive和数据库比较

Hive 和数据库除了拥有类似的查询语言,再无类似之处。
1)数据存储位置
Hive 存储在 HDFS 。数据库将数据保存在块设备或者本地文件系统中。
2)数据更新
Hive中不建议对数据的改写。而数据库中的数据通常是需要经常进行修改的,
3)执行延迟
Hive 执行延迟较高。数据库的执行延迟较低。当然,这个是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive的并行计算显然能体现出优势。
4)数据规模
Hive支持很大规模的数据计算;数据库可以支持的数据规模较小。

内部表和外部表

1)管理表:当我们删除一个管理表时,Hive也会删除这个表中数据。管理表不适合和其他工具共享数据。
2)外部表:删除该表并不会删除掉原始数据,删除的是表的元数据

4个By区别

1)Sort By:分区内有序;
2)Order By:全局排序,只有一个Reducer;
3)Distrbute By:类似MR中Partition,进行分区,结合sort by使用。
4) Cluster By:当Distribute by和Sorts by字段相同时,可以使用Cluster by方式。Cluster by除了具有Distribute by的功能外还兼具Sort by的功能。但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。

窗口函数

RANK() 排序相同时会重复,总数不会变
DENSE_RANK() 排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算
1) OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化
2)CURRENT ROW:当前行
3)n PRECEDING:往前n行数据
4) n FOLLOWING:往后n行数据
5)UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING表示到后面的终点
6) LAG(col,n):往前第n行数据
7)LEAD(col,n):往后第n行数据
8) NTILE(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型。

自定义UDF、UDTF

在项目中是否自定义过UDF、UDTF函数,以及用他们处理了什么问题,及自定义步骤?
1)自定义过。
2)用UDF函数解析公共字段;用UDTF函数解析事件字段。
自定义UDF:继承UDF,重写evaluate方法
自定义UDTF:继承自GenericUDTF,重写3个方法:initialize(自定义输出的列名和类型),process(将结果返回forward(result)),close
为什么要自定义UDF/UDTF,因为自定义函数,可以自己埋点Log打印日志,出错或者数据异常,方便调试.

Hive优化

1)MapJoin
如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。容易发生数据倾斜。可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。
2)行列过滤
列处理:在SELECT中,只拿需要的列,如果有,尽量使用分区过滤,少用SELECT *。
行处理:在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在Where后面,那么就会先全表关联,之后再过滤。
3)采用分桶技术
4)采用分区技术
5)合理设置Map数
(1)通常情况下,作业会通过input的目录产生一个或者多个map任务。
主要的决定因素有:input的文件总个数,input的文件大小,集群设置的文件块大小。
(2)是不是map数越多越好?
答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。
(3)是不是保证每个map处理接近128m的文件块,就高枕无忧了?
答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。
针对上面的问题2和3,我们需要采取两种方式来解决:即减少map数和增加map数;
6)小文件进行合并
在Map执行前合并小文件,减少Map数:CombineHiveInputFormat具有对小文件进行合并的功能(系统默认的格式)。HiveInputFormat没有对小文件合并功能。
7)合理设置Reduce数
Reduce个数并不是越多越好
(1)过多的启动和初始化Reduce也会消耗时间和资源;
(2)另外,有多少个Reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;
在设置Reduce个数的时候也需要考虑这两个原则:处理大数据量利用合适的Reduce数;使单个Reduce任务处理数据量大小要合适;
8)常用参数

// 输出合并小文件
SET hive.merge.mapfiles = true; -- 默认true,在map-only任务结束时合并小文件
SET hive.merge.mapredfiles = true; -- 默认false,在map-reduce任务结束时合并小文件
SET hive.merge.size.per.task = 268435456; -- 默认256M
SET hive.merge.smallfiles.avgsize = 16777216; 
-- 当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,941评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,397评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,345评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,851评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,868评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,688评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,414评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,319评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,775评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,945评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,096评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,789评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,437评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,993评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,107评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,308评论 3 372
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,037评论 2 355