这取决于文件系统.
局部性的工作方式是你必须实施获取块位置,对于给定的文件,在 Hadoop FileSYSstem 接口内部。例如,您可以看到:
一个示例实现,来自glusterfs-hadoop 文件系统实现 https://github.com/gluster/glusterfs-hadoop/blob/master/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterVolume.java, 在这儿:
public BlockLocation[] getFileBlockLocations(FileStatus file,long start,long len) throws IOException{
File f=pathToFile(file.getPath());
BlockLocation[] result=null;
result=attr.getPathInfo(f.getPath(), start, len);
if(result==null){
log.info("Problem getting destination host for file "+f.getPath());
return null;
}
return result;
}
在上面您可以看到文件的元数据是通过 gluster 特定的包装器提供的,这些包装器调用 gluster 特定的命令来确定哪些节点存储文件的实际内容。然后,BlockLocation[] 数组作为作业调度程序的提示,它将尝试将任务本地化到分片确定其块位置的位置。
但最终,调度程序的工作是处理分割,而不是块。因此,分割可以小于或大于文件系统块。如果它较大,则分割的某些部分很可能会通过网络进行流式传输。如果它小得多,那么您可能会获得更多的局部性,但可能会付出更多总体任务数的代价。
优化时,请记住每个输入分割最终都会馈送到映射器。
在 HDFS 中,默认值往往比其他文件系统更好地调整。
通过在 hadoop 兼容文件系统中实现更细粒度的阻塞 (getBlockLocations),您可以增加块的数量以及这些块的复制。
增加块的数量可以提高特定块在本地上下文中运行的概率。
此外,您还可以在运行时切换输入拆分数量(最大和最小)作为 MapReduce 作业参数的一部分。通过更新此值,您可能会提高性能(即机器的使用),但也可能会降低局部性(更多的分割意味着,如果某些机器本质上更快,mapreduce 可以将分割流式传输到非本地机器,这可能会抢占很多任务。)