事情糟糟,感觉自己没有处理好
连接模式:
Hive中根据数据连接发生的地方将连接模式分为两种。
第一种是Repartition连接,发生在Shuffle和Reduce阶段,我们一般上说的表连接指的是Repartition连接。
另外一种连接是Map join.就是所谓的大表Join小标
普通的表连接
Map的任务读取A,B两个表的数据,按照连接条件发往相同的Reduce。并在Reduce中计算结果。
什么是普通的表连接呢?
select * from A join B on A.a = B.a
从上面的SQL语句中,我们根据上面的图片,进行两个表的连接,根据a的值将两个表中相同的key发往相同的Reduce处理。
Replication连接(Map Join)
在Map阶段实现连接时不匹配条件的记录行的过滤(所谓的不匹配就是B.id=0)这样可以减少下游处理的数据量。
这个东西又回到了上次我们说的那个东西。为什么说Replication连接比Repartition连接好呢?普通的表连接在Reduce里面进行计算。Replication连接在Map阶段就进行连接,提前过滤。
普通的MapJoin:对表类型无特殊限制,只需要配置相应的Hive配置。
Bucket MapJoin:要求使用的表是桶表
Sorted Merge Bucker MapJoin:要求使用的是分桶表
普通的Map连接
先来介绍Map连接,Map Join首先先启动一个作业,读取小表的数据,在内存中构建哈希表,将哈希表写在本地的磁盘,然后将哈希表上传到HDFS中并添加到分布式缓存,其实也就是将这个表分发到每一个map节点,然后在开始启动另外一个作业,读大表。
重点来了,这个时候就会进行表连接,每个map节点里面的哈希表会和大表数据进行匹配。匹配完将结果进行输出
不过要开启Map Join需要开启一些相关配置
set hive.auto.convert.join = true 开启MapJoin
Map Join和普通的表连接的任务信息还不一样
可以看到就和我们上面描述的一样
- 开启一个本地的map任务
- 将结果集写到本地
- 本地上传到hdfs(也就是我们的分布式缓存)
- 开启作业(上面说过,普通的表连接是在shuffle或者Reduce里面进行的,而MapJoin是在Map阶段完成的,因此就不会有Reduce的过程)
桶的Map连接
这里要讲解桶的Map连接,如果不知道什么是分桶表,那先粗略的解释一下,分区表和分桶表都是对表结构的一种修改,分区表的修改就是在hdfs的相关路径下面会增加不同的目录,目录下面会有数据。分区表更像是Windows系统里面的目录,在目录下面会有很多的文件。而分桶表就是目录下面的文件。
创建一个分桶表B
create table A(id string,name string) clustered by (id) into 4 buckets
clustered by (a) into 4 buckets的意思就是让系统计算字段id的哈希值,然后根据哈希值来进行分桶。总共分了4个桶。举个例子
4 % 4 =0
3 % 4 =3
2 % 4 =2
1 % 4 =1
最后面的余数我们可以认为是哈希值,根据他们的哈希值不同将这四个数字分别发送到不同的桶里面,也就是发送到这个目录下不同的文件里面。
既然介绍完了分桶表,那么下面来介绍分桶表的表连接。
先放一个图片
桶的表连接,桶表连接如何连接呢?
select * from A join B on A.id = B.id
两个分桶表A和B.A表的id和B表的id进行连接,因为是分桶表,所以分桶表A的id我们不用在全局查找了,而是直接根据关联的id的哈希值来关联B表对应的字段。
要知道两个关联的id都是直接根据哈希值来到对用的分桶表里面直接拿,两个表的关联,不再是普通的表那样就行全局的关联,筛选。而是定点对定点进行表连接。
上面是排序桶表的map表连接,可以看到文件块1对这表2的所有东西进行连接
注意:使用桶的map连接要保证连接的两个表的分桶数是倍数的关系。
说到这里需要注意的是,上面讲的是桶表的map连接和排序桶的maoLianjie
而且,既然是桶表的Map连接,那么我们需要先开启Map Join
开启Map Join之后再开启桶表连接的相关配置参数
总结:
今天心不在焉的,怎么说呢现在写的是Hive的优化实践,但是我并没有经历过这些,而是通过书籍知道了这些方法。虽然说目前用不到,可能等到我实习的时候,我要是碰到了这个场景,或许我会灵光一现,突然想到在今年今日我曾经根据书籍的指导写下这篇文章。让我真正面对实践上的难题的时候可以迎刃而解。