MapReduce之Shuffle

承接上文MapReduce之Map阶段

我们需要将map后的数据往外写。

收集数据

我们写出的数据是("I", 1)

在这里插入图片描述

我们需要往kvbuffer中写key和value。

写key的时候我们既要写I,又要写它的位置,不然怎么能找到它呢?

在这里插入图片描述

写的时候,如果剩余内存不够用了,就会发生溢写:

在这里插入图片描述
I之前,我们已经有1这个位置了:

在这里插入图片描述

写了I之后就有了它的ASCII值了:

在这里插入图片描述

接着写1这个值,因为我们的1是Long,占8个字节,所以会占用kvbuffer的8个位置:

在这里插入图片描述

此时我们的bufindex增加到了10,它可是每写一次都会往上涨的。

接下来就要存元数据了:

在这里插入图片描述

注意到那几个常数:

在这里插入图片描述

这里就存了四个数,一个是分区,因为这里是I,按照自定义分区,分区为1。然后还有key开始的位置,value开始的位置,value的长度(此处为8)。

还记得我们刚开始的kvindex是21264396,经过计算现在的kvindex是21264392:

在这里插入图片描述

这就说明它往前跳了4格,因为接下来kvindex同样要+0,+1,+2,+3存分区,keyStart,valueStart,valueLength。

我们再看写出like的情况:

在这里插入图片描述

在这里插入图片描述
同样,kvmeta也要put一波,kvindex再次减4:

在这里插入图片描述

如果bufferRemaining用完了,就会发生溢写。(不管是kvbuffer中存数据,还是kvmeta中存元数据,bufferRemaining都会不断减少)。

另外一种溢写的条件是所有的数据都读完了。

我们紧跟最后一个词hadoop的脚步,看发生了什么:

在这里插入图片描述

排序和溢写

我们先记录下最后的kvbuffer和kvmeta相关参数:

在这里插入图片描述

一路跟下去:

在这里插入图片描述

我们看到map阶段结束了。现在进入output.close(mapperContext)

我们看到它首先进行排序:

在这里插入图片描述

首先注意一点,就是在排序前后,kvbuffer并没有变:

在这里插入图片描述

这是我将其复制出来进行观察的结果:

0 = 1
1 = 73
2 = 0
3 = 0
4 = 0
5 = 0
6 = 0
7 = 0
8 = 0
9 = 1
10 = 4
11 = 108
12 = 105
13 = 107
14 = 101
15 = 0
16 = 0
17 = 0
18 = 0
19 = 0
20 = 0
21 = 0
22 = 1
23 = 4
24 = 106
25 = 97
26 = 118
27 = 97
28 = 0
29 = 0
30 = 0
31 = 0
32 = 0
33 = 0
34 = 0
35 = 1
36 = 1
37 = 73
38 = 0
39 = 0
40 = 0
41 = 0
42 = 0
43 = 0
44 = 0
45 = 1
46 = 4
47 = 108
48 = 105
49 = 107
50 = 101
51 = 0
52 = 0
53 = 0
54 = 0
55 = 0
56 = 0
57 = 0
58 = 1
59 = 5
60 = 115
61 = 99
62 = 97
63 = 108
64 = 97
65 = 0
66 = 0
67 = 0
68 = 0
69 = 0
70 = 0
71 = 0
72 = 1
73 = 1
74 = 73
75 = 0
76 = 0
77 = 0
78 = 0
79 = 0
80 = 0
81 = 0
82 = 1
83 = 4
84 = 108
85 = 105
86 = 107
87 = 101
88 = 0
89 = 0
90 = 0
91 = 0
92 = 0
93 = 0
94 = 0
95 = 1
96 = 6
97 = 112
98 = 121
99 = 116
100 = 104
101 = 111
102 = 110
103 = 0
104 = 0
105 = 0
106 = 0
107 = 0
108 = 0
109 = 0
110 = 1
111 = 1
112 = 73
113 = 0
114 = 0
115 = 0
116 = 0
117 = 0
118 = 0
119 = 0
120 = 1
121 = 4
122 = 104
123 = 97
124 = 116
125 = 101
126 = 0
127 = 0
128 = 0
129 = 0
130 = 0
131 = 0
132 = 0
133 = 1
134 = 6
135 = 104
136 = 97
137 = 100
138 = 111
139 = 111
140 = 112
141 = 0
142 = 0
143 = 0
144 = 0
145 = 0
146 = 0
147 = 0
148 = 1
149 = 0

其次,它排序排的是元数据,就是kvmeta的排序,先按分区排,分区一样的按照key排。

在这里插入图片描述

溢写的时候是按照分区一个一个溢写的,每个分区都是反向溢写,也就是说,我们先循环0号分区,然后0号分区最后一个kv是("hadoop", 1),那么我们就会先溢写这对kv:

在这里插入图片描述

数据溢写完之后,就会有一个spill0.out的文件:

在这里插入图片描述

当然现在索引数据还在内存,没有到达1MB:

在这里插入图片描述

合并

我们可能会得到许多spill.out和spill.index文件,我们需要将其合并成一个大文件,这可以避免同时读取大量小文件带来的开销。

在合并之前,我们释放了kvbuffer的内存:

在这里插入图片描述

因为我们的溢写文件只有一个,所以只需改名就行了。

在sort阶段结束后,我们有了一个数据文件和一个索引文件:

在这里插入图片描述

此时shuffle阶段结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值