我有以下文件:
城市.dat
Andorra la Vella|ad|Andorra la Vella|20430|42.51|1.51|
Canillo|ad|Canillo|3292|42.57|1.6|
Encamp|ad|Encamp|11224|42.54|1.57|
...
国家.dat
Andorra|ad|Andorra la Vella|Andorra la Vella|69865|468|
United Arab Emirates|ae|Abu Dhabi|Abu Dhabi|2523915|82880|
Afghanistan|af|Kabul|Kabul|28513677|647500|
...
我需要做的是做一个map-side连接来获得country.dat文件中列出的人口(city.dat中的第4列)和每个首都的名称(country.dat中的第3列)。所以我有了基本的想法。两个文件的连接键都是城市值(city.dat中的第1列和country.dat中的第3列)。这样,我应该得到一个表,其中包含所有的信息,我需要一行为每个首都。
但这在hadoop中到底是如何工作的呢?如何告诉hadoop这两个文件中的连接键是什么(我首先需要从每一行中解析出来,不是吗?)我发现的所有代码都是这样的:
inner(tbl(org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat.class,
"/user/cloudera/City.dat"),
tbl(org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat.class,
"/user/cloudera/Country.dat"))
这只是定义了应该连接的两个文件。但是我如何定义连接键以及我定义的记录(在我的例子中,每个文件的一行应该是一个记录)?
2条答案
按热度按时间vxf3dgd41#
您可以将其中一个文件作为分布式缓存传递,另一个作为实际输入传递。
比如说
country.dat
在两种类型的输入中,大小越小,那么在分布式缓存中就有这个。现在,读这个
country.dat
在configure或setup方法中(分别是新的或旧的api),并根据需要创建一个hashmap(将其键入首都),然后根据map方法中的要求使用此hashmap来加入记录。jvlzgdj92#
基本上,map()方法将获取一条记录并将其写入上下文。关键字将是城市和国家名称的串联,值将是文件中的整行,并与文件1或文件2中的某个指示串联在一起。hadoop将完成它的工作,reduce()方法将被传递给您在Map器中编写的每个键和一个iterable,其中包含map()为该键编写的所有值。基本上,这将iterable中来自文件1和文件2的行与源的指示符配对。你的逻辑就是这样。
要回答您的特定问题,您可以读取mapper的setup()方法中的文件1,并将内存中的文件内容存储为哈希表。文件2中每一行的map)(方法的后续调用都可以访问内存中的哈希表。缺点是文件必须足够小才能放入内存,并且会为每个输入片调用setup()方法。