Hadoop缓冲与流媒体

时间:2014-06-17 14:00:53

标签: hadoop hive hadoop-streaming

有人可以向我解释一下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) 

2 个答案:

答案 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的连接实现中,它必须从多个表中获取记录,通过连接键对它们进行排序,然后按正确的顺序将它们整理在一起。它必须按不同的表分组读取它们,因此它们必须查看来自不同表的组,并且一旦看到所有表,就开始处理它们。第一个表中的第一组需要缓冲(保留在内存中),因为在看到最后一个表之前无法处理它们。最后一个表可以流式传输(每个行在读取时处理),因为其他表组在内存中,并且连接可以开始。