【问题标题】:Hadoop Buffering vs StreamingHadoop 缓冲与流式处理
【发布时间】:2014-06-17 14:00:52
【问题描述】:

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

【问题讨论】:

    标签: hadoop hive hadoop-streaming


    【解决方案1】:

    在 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)

    【讨论】:

      【解决方案2】:

      Hadoop Streaming 通常是指使用定制的 python 或 shell 脚本来执行 map-reduce 逻辑。 (例如,使用 Hive TRANSFORM 关键字。)

      在这种情况下,Hadoop 缓冲是指 Hive 查询的 map-reduce 作业中的一个阶段,即在从映射器出来的记录被读入 reducer 之后。作者正在解释为什么您应该在 Hive 查询中对连接子句进行排序,以便最大的表在最后;因为它有助于优化 Hive 中连接的实现。

      它们是完全不同的概念。

      回应您的 cmets:

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

      【讨论】:

      • 在触发 HQL 时,您究竟是如何将最后一个表流式传输到联接的,因为那时我们不编写任何自定义 python 脚本。
      • 好的,所以您真正要问的是,在谈论 Hive 的连接实现以及如何优化它们时,流式传输和缓冲的具体含义是什么。我想这些术语是相当超载的。
      • 在 Hive 的连接实现中,它必须从多个表中获取记录,按连接键对它们进行排序,然后以正确的顺序将它们整理在一起。它必须按不同的表分组读取它们,因此它们必须查看来自不同表的组,并且一旦看到所有表,就开始处理它们。第一个表中的第一组需要缓冲(保存在内存中),因为在看到最后一个表之前无法处理它们。由于其他表组在内存中,因此可以对最后一个表进行流式处理(每行在读取时进行处理),并且可以开始连接。
      • 嗨@JeromeBanks,您能否解释一下加入过程的每个步骤的更多细节。例如,首先将表1读取到缓冲区(所有内容还是多少?),如果没有足够的内存会发生什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 2014-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多