在减少边连接中,来自多个表的值通常会标记为在减速器阶段标识它们,以查找它们来自哪个表。
考虑两个表的情况下:
在减少呼叫,与这两个表相关联的混合值被重复。
在迭代期间,标记/表格之一的值被本地存储到数组列表中。 (这是缓冲)。
当其他值正在流入并且检测到另一个标记/表的值时,第一个标记的值将从保存的数组列表中获取。两个标记值被连接并写入输出采集器。
与此情况相反,如果较大的表值保存在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()));
}
}
}
}
可以使用下面的提示,以指定该连接的表将在减少侧流式传输:
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)
在启动HQL时,您如何将最后一个表流式传输到连接,因为我们不会编写任何自定义Python脚本。 – HadoopEvangelist
好的,所以你真正要问的是,在讨论Hive的连接实现以及如何优化它们时,流和缓冲特别是指什么。我想这些术语是相当重载的。 –
在Hive的连接实现中,它必须从多个表中获取记录,按连接键对它们进行排序,然后按照正确的顺序将它们整理在一起。它必须按照不同的表格来读取它们,所以它们必须看到来自不同表格的组,并且一旦看到所有表格,就开始处理它们。第一个表中的第一组需要被缓冲(保存在内存中),因为直到看到最后一个表才能处理它们。由于其他表组在内存中,所以最后一个表可以进行流式处理(读取时处理每一行),并且可以开始连接。 –