0

我有以下文件:

城市数据

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 Join 以获取 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"))

这只是定义了应该连接的两个文件。但是如何定义连接键以及我定义为记录的内容(在我的情况下,每个文件的一行应该是记录)?

4

2 回答 2

0

基本上 map() 方法将获取一条记录,然后您将其写入上下文。键是城市和国家名称的连接,值是文件中的整行,并带有一些关于它是来自文件 1 还是文件 2 的指示。Hadoop 会做它的事情,reduce() 方法将是传递您在映射器中编写的每个键和一个包含 map() 为该键写入的所有值的 Iterable。基本上,这会将 Iterable 中文件 1 和文件 2 中的行与源指示符配对。你的逻辑从那里开始。

要回答您的具体问题,您可以在映射器的 setup() 方法中读取文件 1 并将我记忆中的文件内容存储为哈希表。随后调用 map)( 文件 2 中每一行的方法都可以访问内存中的该哈希表。缺点是文件必须足够小以适合内存,并且将为每个文件调用 setup() 方法输入切片。

于 2012-11-05T15:41:25.507 回答
0

您可以将其中一个文件作为分布式缓存传递,另一个作为实际输入。

例如,说这country.dat两种类型的输入中尺寸较小的,然后将其放在分布式缓存中。

现在,country.dat在 configure 或 setup 方法(分别为新 API 或旧 API)中读取此内容并根据需要创建一个 HashMap(将其键入首都),然后在 map 方法中根据需要使用此 HashMap 来加入记录。

于 2012-12-13T19:34:28.143 回答