在 reduce 侧连接中,来自多个表的值通常被标记以在 reducer 阶段识别它们,因为它们来自表。
考虑两个表的情况:
在reduce调用时,与两个表关联的混合值被迭代。
在迭代期间,标签/表之一的值在本地存储到数组列表中。 (这是缓冲)。
当其余值正在流式传输并检测到另一个标签/表的值时,从保存的数组列表中获取第一个标签的值。两个标签值被连接并写入输出收集器。
对比一下,如果较大的表值保存在 arraylist 中,那么如果 arraylist 超出容量以压倒容器的 JVM 内存,则可能导致 OOM。
void reduce(TextPair key , Iterator <TextPair> values ,OutputCollector <Text,Text> output ,Reporter reporter ) throws IOException {
//buffer for table1
ArrayList <Text> table1Values = new ArrayList <Text>() ;
//table1 tag
Text table1Tag = key . getSecond();
TextPair value = null;
while( values . hasNext() ){
value = values . next() ;
if(value.getSecond().equals(table1Tag)){
table1Values.add (value.getFirst() );
}
else{
for( Text val : table1Values ){
output.collect ( key.getFirst() ,new Text(val.toString() + "\t"+ value.getFirst().toString () ));
}
}
}
}
您可以使用以下提示指定哪些联接表将在 reduce 端进行流式传输:
SELECT /*+ STREAMTABLE(a) */ a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1)