【发布时间】:2019-04-16 18:52:27
【问题描述】:
通常,如果我们使用 parquet 或 ORC 创建 Hive 表,那么它会扫描我们在选择查询中提到的特定列。
但是可以说,我有 10 个 CSV 文件,并在上面创建了一个外部表。现在如果我做select col1, col2, col3 from external_table; 那么它会扫描我的所有行并且reducer 只会选择选定的列或者它将如何工作?
【问题讨论】:
通常,如果我们使用 parquet 或 ORC 创建 Hive 表,那么它会扫描我们在选择查询中提到的特定列。
但是可以说,我有 10 个 CSV 文件,并在上面创建了一个外部表。现在如果我做select col1, col2, col3 from external_table; 那么它会扫描我的所有行并且reducer 只会选择选定的列或者它将如何工作?
【问题讨论】:
简短回答: Mapper 逐行读取文件拆分并将行转换为仅包含必要列的中间行,执行初始过滤、聚合和其他转换。
Reducer 从 mapper 接收中间行并进行最终处理:聚合、排序等。
长答案:
MR 上的 Hive 和 Tez 上的 Hive 使用 MapReduce framework 原语来构建整个处理作业。
CSV 文件正在拆分,MapReduce framework 为 InputFormat 生成的每个 InputSplit 生成一个映射任务。
映射将输入记录转换为中间记录。转换后的中间记录不需要与输入记录的类型相同。发出的记录中仅包含必要的列。给定的输入对可以映射到零个或多个输出对,映射器进行初始过滤和聚合。
Mapper 的输出被排序,然后每个 Reducer 分区,分区的总数与 reducer 的数量相同。
中间的排序输出总是以简单的(key-len, key, value-len, value) 格式存储。应用程序可以控制是否以及如何压缩中间输出。
Reducer 将共享一个键的一组中间值减少为一组较小的值。换句话说,Reducer 进行最终聚合,必要时进行排序。
Reducer 有 3 个主要阶段:shuffle、sort 和 reduce。 随机播放
Reducer 的输入是映射器的排序输出。在这个阶段,框架通过 HTTP 获取所有映射器输出的相关分区。 排序
在此阶段,框架通过键对 Reducer 输入进行分组(因为不同的映射器可能输出相同的键)。
洗牌和排序阶段同时发生;在获取地图输出时,它们会被合并。
在 Reduce 阶段,为分组输入中的每个 <key, (list of values)> 对调用 reduce(WritableComparable, Iterator, OutputCollector, Reporter) 方法。
reduce 任务的输出通常被写入文件系统。
如果不需要减少,将减少任务的数量设置为零是合法的。 在这种情况下,映射任务的输出直接进入文件系统。
Tez 上的 Hive 将复杂作业(由许多 map 和 reduce 步骤组成)构建为单个 DAG(顶点是处理步骤 - 映射器或化简器,边 - 它们之间的数据传输)并且可以跳过不必要的步骤并且不写入中间结果到持久存储 (HDFS)。
在MapReduce 文档中阅读更多详细信息。
【讨论】:
是的,对于 CSV 或以面向行的方法存储数据的地方,读取所有行(即所有列),如果有任何 group by 或聚合,那么 reducer 将进行聚合。
【讨论】: