Hadoop 中使用DistributedCache遇到的问题
?
自己在写MAR/REDUCE代码时,遇到了一个问题,一个大数据文件和一个小数据文件匹配计算,但是小数据文件太小,所以想采用HIVE的MAP JOIN的方式,把小数据文件放到直接大数据文件map的datanode的内存中,这样少了MR代码的1对N的数据文件关联。1.MAP、REDUCE本身和之间共享的较大数据量的数据2.布置第三方JAR包,可以避免集群的删减导致部分依赖的机器的JAR包的丢失
1.在HDFS上准备好要共享的数据(text、archive、jar)2.在distributed cache中添加文件3.在mapper或者reducer类中获取数据4.在map或者reduce函数中使用数据
public static void disCache(String dimDir, JobConf conf) throws IOException { FileSystem fs = FileSystem.get(URI.create(dimDir), conf); FileStatus[] fileDir = fs.listStatus(new Path(dimDir)); for (FileStatus file : fileDir) { DistributedCache.addCacheFile(URI.create(file.getPath().toString()), conf); }}因为我利用的数据是HIVE脚本生成的,所以无法指定具体的文件路径,采用这种方式把一张HIVE表的所有数据都加载到cache中。如果能直接明确知道文件名称就简单很多了,例如:DistributedCache.addCacheFile(URI.create(“/mytestfile/file.txt”), conf);3.在mapper或者reducer中获取数据
public void configure(JobConf job) { try { urlFile = DistributedCache.getLocalCacheFiles(job); seoUrlFile = "file://" + urlFile[0].toString(); allUrlFile = "file://" + urlFile[1].toString(); getData(seoUrlFile, seoUrlDim); getData(allUrlFile, allUrlDim); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }}?? ? ?我在流程2中添加了两个文件,通过DistributedCache.getLocalCacheFiles(job)获取Path[],针对不同文件调用getData,把文件数据放在不同的List中seoUrlDim,allUrlDim? ? ?如此一来,distributed cache的过程就结束了,接下来就在map()或者reduce()中使用这些数据就OK了。4.在map或者reduce函数中使用数据? ? ?一定要区分流程3和4,3是获取数据,4是使用数据。我就是在前期没弄明白这个的差异,导致内存溢出。1.FileNotFoundException
2.java.lang.OutOfMemoryError: GC overhead limit exceeded1.FileNotFoundException? ? ?这个问题涉及到DistributedCache.getLocalCacheFiles(job) 这个函数,此函数返回的Path[]是执行map或者reduce的datanode的本地文件系统中路径,但是我在getData中利用的SequenceFile.Reader的默认filesystem是hdfs,这就导致获取数据时是从hdfs上找文件,但是这个文件是在本地文件系统中,所以就会报出这个错误FileNotFoundException。? ? ?例如,DistributedCache.getLocalCacheFiles(job)返回的PATH路径是:/home/dwapp/hugh.wangp/mytestfile/file.txt,在默认文件系统是hdfs时,获取数据时会读hdfs://hdpnn:9000/home/dwapp/hugh.wangp/mytestfile/file.txt,但是我们是在本地文件系统,为了避免数据获取函数选择"错误"的文件系统,我们在/home/dwapp/hugh.wangp/mytestfile/file.txt前加上"file://",这样就会从本地文件系统中读取数据了。就像我例子中的seoUrlFile?=?"file://"?+?urlFile[0].toString();