在Hadoop中为Map函数输入拆分

时间:2014-09-08 08:33:01

标签: python hadoop hadoop-streaming hadoop2 hadoop-partitioning

这是我在Hadoop中的第一个实现。我正在尝试在Map Reduce中为概率数据集实现我的算法。在我的数据集中,最后一列将具有一些id(数据集中唯一ID的数量等于我的集群中的节点数)。我必须根据此列值划分数据集,并且每个记录集应由我的集群中的每个节点处理。

例如,如果我的群集中有三个节点,对于下面的数据集,一个节点应处理id = 1的所有记录,另一个id = 2,另一个id = 3

name time  dept  id
--------------------
 b1  2:00pm z1   1
 b2  3:00pm z2   2
 c1  4:00pm y2   1
 b3  3:00pm z3   3
 c4  4:00pm x2   2

我的地图功能应将每个分割作为输入并在每个节点中并行处理。

我只是想了解,在Hadoop中可以采用哪种方法。要么输入此数据集作为我的map函数的输入,要么使用map传递附加参数以根据id值拆分数据。 或者事先将数据拆分为" n"(节点数)子集并将其加载到节点中,如果这是正确的方法,如何根据值和不同的负载拆分数据节点。因为,我从读数中理解的是,hadoop根据指定的大小将数据拆分为块。如何在加载时指定特定条件。只是为了加起来,我正在用python编写我的程序。

有人请指教。感谢

2 个答案:

答案 0 :(得分:1)

最简单的事情可能是让映射器输出id为key的数据,这将保证一个reducer将获取特定id的所有记录,然后在reducer阶段进行处理。

例如,

输入数据:

 b1  2:00pm z1   1
 b2  3:00pm z2   2
 c1  4:00pm y2   1
 b3  3:00pm z3   3
 c4  4:00pm x2   2

映射器代码:

#!/usr/bin/env python
import sys
for line in sys.stdin:
    line = line.strip()
    cols = line.split("\t")
    key = cols[-1]
    print key + "\t" + line

地图输出

 1  b1  2:00pm z1   1
 2  b2  3:00pm z2   2
 1  c1  4:00pm y2   1
 3  b3  3:00pm z3   3
 2  c4  4:00pm x2   2

减速机1输入:

 1  b1  2:00pm z1   1
 1  c1  4:00pm y2   1

减速机2输入:

 2  b2  3:00pm z2   2

减速机3输入:

 3  b3  3:00pm z3   3

减速机代码:

#!/usr/bin/env python
import sys
for line in sys.stdin:
    line = line.strip()
    cols = line.split("\t")
    orig_line = "\t".join(cols[1:])
    # do stuff...

请注意,这样一个reducer可能会获得多个键,但数据将被排序,您可以使用 mapred.reduce.tasks 选项控制reducers的数量。

修改 如果你想在每个键的reducer中收集你的数据,你可以做这样的事情(不确定它会按原样运行,但你明白了)

#!/usr/bin/env python
import sys
def process_data(key_id, data_list):
   # data_list has all the lines for key_id

last_key = None
data = []
for line in sys.stdin:
    line = line.strip()
    cols = line.split("\t")
    key = cols[0]
    if last_key and key != last_key:
        process_data(last_key, data)
        data = []
    orig_line = "\t".join(cols[1:])
    data.append(orig_line)
    last_key = key
process_data(last_key, data)

如果您不担心减速器步骤中的内存不足,可以像这样简化代码:

#!/usr/bin/env python
import sys
from collections import defaultdict
def process_data(key_id, data_list):
   # data_list has all the lines for key_id

all_data = defaultdict(list)
for line in sys.stdin:
    line = line.strip()
    cols = line.split("\t")
    key = cols[0]
    orig_line = "\t".join(cols[1:])
    all_data[key].append(orig_line)
for key, data in all_data.iteritems():
    process_data(key, data)

答案 1 :(得分:0)

如果我理解了您的问题,最好的方法是将数据集加载到 hive 表中,然后在python中编写 UDF 。在那之后,做这样的事情:

select your_python_udf(name, time, dept, id) from table group by id;

这看起来像是简化阶段,所以你可能在启动查询之前需要这个

set mapred.reduce.tasks=50;

如何创建自定义UDF:

Hive Plugins

Create Function