我有以下文件:
City.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|
...
Country.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"))
这只定义了应该加入的两个文件。但是我如何定义连接键以及我定义为记录的内容(在我的情况下,每个文件的一行应该是一个记录)?
答案 0 :(得分:0)
基本上map()方法将记录,然后将其写入上下文。关键是城市和国家名称的串联,价值将是文件的整行,并与文件1或文件2中的某些描述联系起来.Hadoop会做它的东西和减少( )方法将传递您在映射器中写入的每个键,以及包含map()为该键写入的所有值的Iterable。基本上,这会将Iterable中文件1和文件2中的行与源的指示符配对。你的逻辑从那里开始。
要回答您的具体问题,您可以在mapper的setup()方法中读取文件1,并将文件内容存储为内存作为哈希表。对映射的后续调用)(文件2中每行的方法可以访问内存中的哈希表。缺点是文件必须足够小以适应内存,并且将为每个调用setup()方法输入切片。
答案 1 :(得分:0)
您可以将其中一个文件作为分布式缓存传递,将另一个文件作为实际输入传递。
例如,假设country.dat
在两种类型的输入中的大小都较小,那么在分布式缓存中就有这个。
现在,在配置或设置方法(分别是新的或旧的API)中阅读此country.dat
并根据需要创建HashMap(将其键入首都),然后根据需要在地图中使用此HashMap加入记录的方法。