有人可以向我解释一下Hadoop Streaming与Buffering之间的区别是什么?
以下是我在Hive中阅读的背景信息:
在连接的每个map / reduce阶段,序列中的最后一个表通过reducer进行流式传输,而其他表被缓冲。因此,通过组织表使得最大的表出现在序列的最后,有助于减少reducer中用于缓冲连接键的特定值的行所需的内存。例如在:
SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1)
答案 0 :(得分:3)
在reduce side join中,多个表中的值通常被标记为在reducer阶段标识它们来自的表。
考虑两个表的情况:
在reduce调用中,迭代与两个表关联的混合值。
在迭代期间,其中一个标记/表的值本地存储在一个arraylist中。 (这是缓冲)。
在传输其余值并检测到另一个标记/表的值时,将从保存的arraylist中获取第一个标记的值。两个标记值连接并写入输出收集器。
将此情况与如下情况进行对比如果较大的表值保存在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 JOIN b ON(a.key = b.key1)JOIN c ON(c.key = b.key1)
答案 1 :(得分:2)
Hadoop Streaming通常是指使用自定义的python或shell脚本来执行map-reduce逻辑。 (例如,使用Hive TRANSFORM关键字。)
在此上下文中,Hadoop缓存是指在将记录从映射器中排序和分组后,将记录读入reducers时,带有连接的Hive查询的map-reduce作业中的阶段。作者解释了为什么你应该在Hive查询中订购join子句,以便最大的表是最后一个;因为它有助于优化Hive中连接的实现。
它们是完全不同的概念。
回应你的意见:
在Hive的连接实现中,它必须从多个表中获取记录,通过连接键对它们进行排序,然后按正确的顺序将它们整理在一起。它必须按不同的表分组读取它们,因此它们必须查看来自不同表的组,并且一旦看到所有表,就开始处理它们。第一个表中的第一组需要缓冲(保留在内存中),因为在看到最后一个表之前无法处理它们。最后一个表可以流式传输(每个行在读取时处理),因为其他表组在内存中,并且连接可以开始。