参考:
《hadoop权威指南》p22,34
1. 应用
a.假设全球每年每天的气温记录数据存在h:dfs的dir/temp.tx文件内,我们需要统计出97,98,99三年内每年的最高气温,自己编写mr程序,并运行。
上述问题完全可以映射成Hive QL来实现。
b.假设hive中dpi表是全球每天内的平均气温,有日期,温度等字段,统计三年内每年最高气温:
select year, max(temp) from dpi where year in ('1997','1998','1999') group by year;
下面只讲解a.
题目:
job:hdfs数据temp.txt+?(mr)+conf=?(结果:97,98,99分别对应的最高温度),自己编写mr,求解?
答:略
执行流程:
temp.txt在hdfs上市一个文件,底层存储在三台机器上:n1:128m,n2:128m,n3:127m,每一分数据按照hdfs将文件划分块大小128m,
hadoop会实行数据本地化map策略:根据数据在本地启动map task,这样会节省传输数据带来的花费和时间。
会将hdfs数据temp.txt分片splitfiles,按照和块大小相同的大小来划分, 1splitfile = 1block,这样本地的一个block就是一份splitfile就是一个block,就会启动一个map,
map:输入:(0,。。。),(1,。。。),。。。键值对作为输入;
map:处理:将除97,98,99三年外的数据过滤掉,并且从每一个键值对的值中提取出,日期和气温两个数据作为输出的key,value,进行分区;
map:输出:(97,...)(97,...)...(97,...)(98,...)...(99,...)(99,...)...
map:存储:在本地disk,因为不是最终结果,存储到hdfs也是多余浪费时空。
(reducer个数我们可以自己指定,可以一个reducer处理一个key(一年),但是如果我们需求改成找出历史上每年内最高气温,然后就会有很多reducer task,这样就会很浪费资源,效率很低;反之,由于一个reducer可以同时处理很多key,
如果把所有的map输出都给一个reducer,这样一个reducer处理起来就会很慢,效率还是很低下,所以要均匀分配reduce,有了分区的概念。
为了将各节点的map输出,均匀分发到不同reducer,每个map任务就会针对输出进行分区,即为每个reducer任务建一个分区。相同键在相同分区里,一个分区可以有很多不同key。
定义分区,可以由用户自定义partition函数控制,但通常用默认的partitioner通过hash函数来分区,很高效。)
reduce任务数量:并非由输入数据的大小决定,而事实上是独立指定的。需要根据需求内容根据作业选择reduce任务数量。
reducer大部分情况不能数据本地化处理,因为单个reducer task通常来自于所有mapper输出,同一个key可能分散在不同节点上,所以需要将不同节点上的map输出进行排序并通过数据传输到统一的一个reducer节点上,
相同key的记录再进行merge成一个组,作为reducer输入,这个过程就是shuffle,
也有特殊情况:完全并行化处理:所有相同key的记录都在相同节点上,这种情况,如果需求只是取最大值,那么在各节点本地进行map排序分组,取最大值,就可以了,不需要shuffle,及通过网络传输给reducer节点也不需要reducer task,只是需要将map结果网络传输到hdfs上即可;
shuffle:将每一个map的输出中相同的分区通过网络传输到reducer所在节点,在每个reducer节点上,将传来的数据根据key来合并分组(merge),输出:(97,...)(98,...)(99,...)
reducer:将输入数据,得到每个value的最大值,输出:(97,40),(98,42),(99,48)
hadoop会将reducer输出通过网络传输到hdfs文件系统上。
《hadoop权威指南》p22,34
1. 应用
a.假设全球每年每天的气温记录数据存在h:dfs的dir/temp.tx文件内,我们需要统计出97,98,99三年内每年的最高气温,自己编写mr程序,并运行。
上述问题完全可以映射成Hive QL来实现。
b.假设hive中dpi表是全球每天内的平均气温,有日期,温度等字段,统计三年内每年最高气温:
select year, max(temp) from dpi where year in ('1997','1998','1999') group by year;
下面只讲解a.
题目:
job:hdfs数据temp.txt+?(mr)+conf=?(结果:97,98,99分别对应的最高温度),自己编写mr,求解?
答:略
执行流程:
temp.txt在hdfs上市一个文件,底层存储在三台机器上:n1:128m,n2:128m,n3:127m,每一分数据按照hdfs将文件划分块大小128m,
hadoop会实行数据本地化map策略:根据数据在本地启动map task,这样会节省传输数据带来的花费和时间。
会将hdfs数据temp.txt分片splitfiles,按照和块大小相同的大小来划分, 1splitfile = 1block,这样本地的一个block就是一份splitfile就是一个block,就会启动一个map,
map:输入:(0,。。。),(1,。。。),。。。键值对作为输入;
map:处理:将除97,98,99三年外的数据过滤掉,并且从每一个键值对的值中提取出,日期和气温两个数据作为输出的key,value,进行分区;
map:输出:(97,...)(97,...)...(97,...)(98,...)...(99,...)(99,...)...
map:存储:在本地disk,因为不是最终结果,存储到hdfs也是多余浪费时空。
(reducer个数我们可以自己指定,可以一个reducer处理一个key(一年),但是如果我们需求改成找出历史上每年内最高气温,然后就会有很多reducer task,这样就会很浪费资源,效率很低;反之,由于一个reducer可以同时处理很多key,
如果把所有的map输出都给一个reducer,这样一个reducer处理起来就会很慢,效率还是很低下,所以要均匀分配reduce,有了分区的概念。
为了将各节点的map输出,均匀分发到不同reducer,每个map任务就会针对输出进行分区,即为每个reducer任务建一个分区。相同键在相同分区里,一个分区可以有很多不同key。
定义分区,可以由用户自定义partition函数控制,但通常用默认的partitioner通过hash函数来分区,很高效。)
reduce任务数量:并非由输入数据的大小决定,而事实上是独立指定的。需要根据需求内容根据作业选择reduce任务数量。
reducer大部分情况不能数据本地化处理,因为单个reducer task通常来自于所有mapper输出,同一个key可能分散在不同节点上,所以需要将不同节点上的map输出进行排序并通过数据传输到统一的一个reducer节点上,
相同key的记录再进行merge成一个组,作为reducer输入,这个过程就是shuffle,
也有特殊情况:完全并行化处理:所有相同key的记录都在相同节点上,这种情况,如果需求只是取最大值,那么在各节点本地进行map排序分组,取最大值,就可以了,不需要shuffle,及通过网络传输给reducer节点也不需要reducer task,只是需要将map结果网络传输到hdfs上即可;
shuffle:将每一个map的输出中相同的分区通过网络传输到reducer所在节点,在每个reducer节点上,将传来的数据根据key来合并分组(merge),输出:(97,...)(98,...)(99,...)
reducer:将输入数据,得到每个value的最大值,输出:(97,40),(98,42),(99,48)
hadoop会将reducer输出通过网络传输到hdfs文件系统上。