大数据:Hive
  n9WuM56whH67 2023年11月02日 43 0

原文链接:https://blog.csdn.net/mayaohao/article/details/122004618

1.1 什么是 Hive

1) hive 简介 Hive:由 Facebook 开源用于解决海量结构化日志的数据统计工具。 Hive 是基于 Hadoop 的一个==数据仓库工具==,可以将结构化的数据文件映射为一张表,并提供类 SQL 查询功能 2) Hive 本质:将 HQL 转化成 MapReduce 程序 image.png (1)Hive 处理的数据存储在 HDFS (2)Hive 分析数据底层的实现是 MapReduce (3)执行程序运行在 Yarn 上

1.2Hive 的优缺点

1.2.1 优点

(1)操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)。 (2)避免了去写 MapReduce,减少开发人员的学习成本。 (3)Hive的==执行延迟比较高==,因此 Hive 常用于数据分析,对实时性要求不高的场合。 (4)Hive优势在于处理大数据,对于处理小数据没有优势,因为 Hive 的执行延迟比较高。 (5)Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。

1.2.2 缺点

(1)Hive的HQL表达能力有限

  • 迭代式算法无法表达
  • 数据挖掘方面不擅长,由于 MapReduce 数据处理流程的限制,效率更高的算法却 无法实现。

(2)Hive 的效率比较低

  • Hive 自动生成的 MapReduce 作业,通常情况下不够智能化
  • Hive 调优比较困难,粒度较粗

1.3 Hive 架构原理

image.png 1)==元数据:Metastore== 元数据包括:表名、表所属的数据库(默认是 default)、表的拥有者、列/分区字段、 表的类型(是否是外部表)、表的数据所在目录等; 默认存储在自带的 derby 数据库中,推荐使用 MySQL 存储 Metastore image.png 2)==驱动器:Driver== (1)解析器(SQL Parser):将 SQL 字符串转换成抽象语法树 AST,这一步一般都用第 三方工具库完成,比如 antlr;对 AST 进行语法分析,比如表是否存在、字段是否存在、SQL 语义是否有误。 (2)编译器(Physical Plan):将 AST 编译生成逻辑执行计划。 (3)优化器(Query Optimizer):对逻辑执行计划进行优化。 (4)执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于 Hive 来 说,就是 MR/Spark。 image.png Hive 通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的 Driver, 结合元数据(MetaStore),将这些指令翻译成 MapReduce,提交到 Hadoop 中执行,最后,将执行返回的结果输出到用户交互接口。

1.4 内部表和外部表

1.4.1元数据、原始数据

1)删除数据时: 内部表:元数据、原始数据,全删除; 外部表:元数据 只删除;

2)生产环境下,什么时候创建内部表,什么时候创建外部表? 绝大多数场景都是外部表。自己使用的临时表,才会创建内部表

1.4.2 内部表

与数据库中的table在概念上是类似的,每一个table在hive中都有一个对应的目录存储数据,所有的table数据(不包括 external table ) 都保存在这个目录中。删除表时 元数据和数据都会被删除

1.4.3 外部表

指向已经在HDFS中存在的数据 可以创建 Partition,它和内部表在元数据的组织上相同的 而实际数据的存储有较大差异。外部表只有一个过程 加载数据和创建表同时完成 并不会移动到数据库目录中,只有与外部数据建立一个连接 当删除一个外部表时 仅删除一个连接和元数据。

1.4.4 4 个 By 区别

1)==Order By==:全局排序,只有一个 Reducer; hive中的order by跟传统的sql语言中的order by 作用是一样的,会对查询结果做一次全局排序。 所以说 只有hive的sql中制定了对order所有数据都会到同一个reducer进行处理(不管有多少map 也不管文件有多少的block 只会启动一reducer) 但是对于大量数据这将会消耗很长时间执行。这里跟传统的sql有一点区别:如果指定了hive.mapred.mode=strict (默认是nonstrict) 这时就必须指定limit 来限制输出条数 原因是所有的数据 都会在同一个reducer端进行数据量大的情况下可能不能出结果, 那么在这样的严格模式下必须输出指定的条数。

2)==Sort By==:分区内有序; hive中指定了sort by 那么在每个reducer端都会做排序 也就是说保证了局部有序 (每个reducer 出来的数据都是有序的 但是不能保证所有的数据都是有序的 除非只有一个reducer) 好处是:执行了局部排序之后可以为接下去的全局排序提高不少效率(其实就是做一次归并排序就可以做到全局排序了)。

3)==Distrbute By==:类似 MR 中 Partition,进行分区,结合 sort by 使用。 Distribute by和sort by 一起用,distribute by 是控制map的输出在reducer 是如何划分的 举个例子 我们有张表 mid指这个store所属的商户,money是这个商户的盈利,name 是这个 store的名字 执行hive语句,select mid ,money,name from store distribute by mid sort by mid asc,money asc. 我们所有的mid相同的数据会被传送到同一个reducer去处理,这就是因为指定了distribute by mid 这样的话就可以统计出每个商户中各个商店的盈利的排序(这个肯定是全局有序的,因为相同的商户会放到同一个reducer去处理),这里需要注意的是distribute by 必须要写在sort by之前。

4)==Cluster By==:当 Distribute by 和 Sorts by 字段相同时,可以使用 Cluster by 方式。Cluster by 除了具有 Distribute by 的功能外还兼具Sort by的功能。Cluster by 的功能是 dirtribute by和sort by相结合,如下两个语句是等价的

select mid,money,name from store cluster by mid
Select mid,money,name from store distribute by  mid sort by mid

但是cluster by指定的列只能是降序的不能指定ASC,DESC。 在生产环境中 Order By 用的比较少,容易导致 OOM。 在生产环境中 Sort By+ Distrbute By 用的多。

1.5 企业级调优

1.5.1 执行计划 explain

1.5.2 fetch抓取

hive-default.xml.tmplate文件中hive.fetch.task.conversion默认more 老版本默认minimal改成more全局查找,字段查找,limit 查找不走mr ##1.5.3本地模式 set hive.exec.mode.local.auto=true;不走yarn调度数量少跟运行环境有关提交给本地or yarn。

1.5.4表优化

1)大小表 join mapjoin

  • 小表缓存到内存,慢慢加载大表数据;
  • 在map里面找小表对应的数据,小表放左、大表放右 内部已经做了优化.

2)开启 MapJoin 参数设置

  • 设置自动选择 Mapjoin,set hive.auto.convert.join = true; 默认为 true
  • 大表小表的阈值设置(默认 25M 以下认为是小表):set hive.mapjoin.smalltable.filesize = 25000000;(根据集群资源来定)

1.6 MapJoin 工作机制

image.png
1 ) Task A ,它是一个 Local Task (在客户端本地执行的 Task ),负责扫描小表 b 的数据,将其转换成一个 HashTable 的数据结构,并写入本地 的 文 件 中 , 之 后 将 该 文 件 加 载 到DistributeCache 中。 2 ) Task B ,该任务是一个没有 Reduce 的 MR ,启动 MapTasks 扫描大表 a ,在 Map 阶段,根据 a 的每一条记录去和 DistributeCache 中 b 表对应的HashTable关联,并直接输出结果。 3 )由 于 MapJoin 没有 Reduce ,所以由 Map 直接输出结果文件,有多少个 Map Task ,就有多少个结果文件。

1.6.1 建大表、小表和 JOIN 后表的语句。

create table bigtable(id bigint, t bigint, uid string, keyword string,url_rank int, click_num int, click_url string) row format delimitedfields terminated by '\t';
// 创建小表
create table smalltable(id bigint, t bigint, uid string, keyword string,
url_rank int, click_num int, click_url string) row format delimited
fields terminated by '\t';
// 创建 join 后表的语句
create table jointable(id bigint, t bigint, uid string, keyword string,
url_rank int, click_num int, click_url string) row format delimited
fields terminated by '\t';

1)分别向大表和小表中导入数据

hive (default)> load data local inpath '/opt/module/data/bigtable' into
table bigtable;
hive (default)>load data local inpath '/opt/module/data/smalltable' into
table smalltable;

2)小表 JOIN 大表语句

insert overwrite table jointable
select b.id, b.t, b.uid, b.keyword, b.url_rank, b.click_num, b.click_url
  from smalltable s
  join bigtable b  on b.id = s.id;

3)大表 JOIN 小表语句

insert overwrite table jointable
select b.id, b.t, b.uid, b.keyword, b.url_rank, b.click_num, b.click_url
from bigtable b
join smalltable s on s.id = b.id;

最后执行计划可知:大表 小表位置颠倒都是一样的。先扫描小表、再扫描大表,走的是mapjoin。默认mapjoin是开启的,如果关掉mapjoi,他会走reducejoin,执行计划的体现。

1.6.2 大表 Join 大表

**1)空 KEY 过滤(用于非inner) ** 有时 join 超时是因为某些 key 对应的数据太多,而相同 key 对应的数据都会发送到相同 的 reducer 上,从而导致内存不够。此时我们应该仔细分析这些异常的 key ,很多情况下, 这些 key 对应的数据是异常数据,我们需要在 SQL 语句中进行过滤。 join自动过滤空值 但是leftjoin就不同了 可能左边有空值 过滤不掉 inner join不用手动过滤空值 2)测试不过滤空 id

hive (default)> insert overwrite table jointable select n.* from nullidtable n left join bigtable o on n.id = o.id;

3)测试过滤空 id

hive (default)> insert overwrite table jointable select n.* from (select* from nullidtable where id is not null) n left join bigtable o on n.id =o.id;

4)空 key 转换 有时虽然某个 key 为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join 的结果中,此时我们可以表 a 中 key 为空的字段赋一个随机的值,使得数据随机均匀地分不到不同的 reducer 上。 5)不随机分布空 null 值 (1)设置 5 个 reduce 个数

set mapreduce.job.reduces = 5;

(2) JOIN 两张表

insert overwrite table jointable
select n.* from nullidtable n left join bigtable b on n.id = b.id;

结果:如下图所示,可以看出来,出现了数据倾斜,某些 reducer 的资源消耗远大于其他 reducer。 image.png 6)随机分布空 null 值 (1)设置 5 个 reduce 个数

set mapreduce.job.reduces = 5;

(2) JOIN 两张表

insert overwrite table jointable
select n.* from nullidtable n full join bigtable o on
nvl(n.id,rand()) = o.id; 

(这里随机数要注意 比如后面是 1 2 3 不能保证连接上 会破坏原先的真实性原先如果是 1 2 3 前面可以给 A BC 不能连上) 结果:如下图所示,可以看出来,消除了数据倾斜,负载均衡 reducer 的资源消耗 image.png

相对均衡 (数据倾斜情况下 真实生产环境很有可能导致出不来结果! 倾斜的那个)

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

n9WuM56whH67
最新推荐 更多

2024-05-31