我需要定期处理10亿条记录。唯一键可以在1000万的范围内。值是最大200K字符的字符串。
以下是我的问题:
密钥空间是否非常大(1000万)。 Hadoop能够处理如此庞大的密钥空间吗?每个键将有一个减速器,因此将有数百万个减速器。
我想更新reducer本身的数据库。在reducer中,我将合并值(比如它当前值),从DB读取现有值(比如说它的现有值),合并当前值和现有值并更新DB。这是一个正确的策略吗?
每个盒子可同时运行多少个减速器?它是可配置的吗?如果每个盒子一次只运行一个reducer,则会出现问题,因为我无法快速更新DB中的键状态。
我希望工作在2-3小时内完成。我需要多少个盒子(我可以节省最多50个盒子 - 64 GB RAM,8个核心机器)
由于
答案 0 :(得分:3)
您的问题的答案:
一个。你在减速器中得到了错误的Key,Value分布概念。减速器数量不等于唯一映射器输出键的数量。 概念是 - 与映射器中的键相关联的所有值都转到单个reducer。这绝不意味着减速器只能获得一个密钥。
例如,请考虑以下映射器输出:
Mapper(k1,v1), Mapper(k1,v2), Mapper(k1,v3)
Mapper(k2,w1), Mapper(k2,w2)
Mapper(k3,u1), Mapper(k3,u2), Mapper(k3,u3), Mapper(k3,u4)
因此,与 k1 - v1,v2 和 v3 相关的值将进入单个reducer,例如 R1 ,它赢了不要分成多个减速器。但这并不意味着R1只有1个键 k1 来处理。它也可能具有 k2 或 k3 的值。但是对于reducer接收的任何键,与该键关联的所有值都将来到同一个reducer。希望它能清除你的怀疑。
湾您使用的是哪个DB?要减少数据库调用或更新语句,可以在循环完成与特定键相关的值之后,在reducer()的末尾进行查询。
例如:
public static class ReduceJob extends MapReduceBase implements Reducer<Text, Text, Text, Text> {
@Override
public synchronized void reduce(Text key, Iterator<Text> values, OutputCollector<Text, Text> output,
Reporter reporter) throws IOException {
while (values.hasNext()) {
// looping through the values
}
// have your DB update etc. query here to reduce DB calls
}
}
℃。是的,减速器的数量是可配置的。如果要根据作业设置它,可以在作业代码run()方法中添加一行,用于设置缩减器的数量。
jobConf.set("mapred.reduce.tasks", numReducers)
如果要根据计算机设置它,即群集中每台计算机应该有多少个reducer,那么您需要将群集的hadoop配置更改为:
mapred.tasktracker。{map | reduce} .tasks.maximum - 最大数量 MapReduce任务,在给定的TaskTracker上同时运行, 个别。默认为2(2个地图,2个减少),但会改变它 取决于您的硬件。
此处有更多详情:http://hadoop.apache.org/docs/stable/cluster_setup.html#Configuring+the+Hadoop+Daemons
d。如果您的数据文件没有gzip(hadoop InputSplit不能与gZipped文件一起使用),那么按照你的说法,你有200 * 1024 * 10亿字节= 204800 GB或204.800 TB数据,所以如果你想得到它在2-3小时内完成,更好地备用所有50个盒子,如果减速器的内存占用率低,则根据最后的答案增加每台机器的减速器数量。此外,将InputSplit大小增加到大约128MB可能会有所帮助。
谢谢和问候。
Kartikeya Sinha