介绍
并没有排序的功能
distribute by 会根据指定 字段的值,将记录 分发到不同的 reduce 中
分区规则
默认是对指定列的值取 hash 值,然后hash值对reduce的个数取模,余数相同的分到一个区。也就意味着 同一个分区 中的 字段不一定相同。
相当于调用 MapReduce 的 HashPartitioner
注意: reduce 的数量要大于1,才能体现出来
与 sort by 关系
每个reduce中的数据并 不是有序的。因此,distribute by 经常和 sort by 配合使用。Hive 要求 distribute by 语句要写在 sort by 语句之前
一句话解释
distribute by 根据列的值,将数据分给不同的 reduce,最终保存到文件中
与 sort by 区别
sort by 不是根据后面的列值进行分发 reduce
语法
select * from 表名 distribute by 列名 sort by 列名 [asc/desc];
例
emp 表中的记录有3类 deptno,设置3个 reducer:
set mapreduce.job.reduces=3;
查看 reducer数量:
set mapreduce.job.reduces;
执行下面sql:
insert overwrite local directory '/program/result_dist/'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
select ename,deptno,sal from emp distribute by deptno ;
执行结果:
有 3 类deptno,那么设置 3 个reducer,每类 deptno 分给一个reducer,每个 reducer 生成 1 个文件
最终每一类 deptno,保存在 一个文件中
每个文件中的数据不会做排序
原理
对部门编号 10、20、30 封装成 IntWritable,再算 hash,然后对 2 取模,观察执行结果:
public static void main(String[] args) {
IntWritable t = new IntWritable(10);
IntWritable t2 = new IntWritable(20);
IntWritable t3 = new IntWritable(30);
System.out.println( t.hashCode()%3 + "-"+t.hashCode());
System.out.println( t2.hashCode()%3 + "-"+t2.hashCode());
System.out.println( t3.hashCode()%3 + "-"+t3.hashCode());
}
结果如下:
1-10
2-20
0-30
结论:
- 说明 0号文件 是部门编号
10的数据 - 说明 1号文件 是部门编号
20的数据 - 说明 3号文件 是部门编号
30的数据
reduce 数量是 2
如果 reducer 数量不是3,是2,那么分类的策略会不同,有1个文件是空的,没有数据
原理
对部门编号 10、20、30 封装成 IntWritable,再算 hash,然后对 2 取模,观察执行结果:
public static void main(String[] args) {
IntWritable t = new IntWritable(10);
IntWritable t2 = new IntWritable(20);
IntWritable t3 = new IntWritable(30);
System.out.println( t.hashCode()%2 + "-"+t.hashCode());
System.out.println( t2.hashCode()%2 + "-"+t2.hashCode());
System.out.println( t3.hashCode()%2 + "-"+t3.hashCode());
}
结果如下:
0-10
0-20
0-30
结论:说明 0号文件有数据,1号文件是空的
感谢:
https://blog.csdn.net/u012369535/article/details/89639434
