我决定编写一个简单的自定义FileInputFormat来测试我对inputSplits等的理解。这个练习给我留下了一个严重的问题。
上下文
- 假设我有一个很大的文件,它存储在N块
- 假设我的拆分可能跨越两个块(我已经知道为什么这不是一个好主意了——我只是想提高我对HDFS和
InputSplits
的理解——所以坚持下去) - 假设我有一个方法,它接受
FileStatus, FileSystem
并返回FileInputSplit
的数组:
InputSplit[]getSplits(FileStatus文件,FileSystem fs);
问题
我需要4个值来形成FileInputSplit split = new FileInputSplit(path, start, length, hosts)
我有路径、开始、长度,我需要获取主机,所以对于start
和length
指定的文件的每个部分,我检索位置块final BlockLocation[] blocks = fs.getBlockLocations(file, start, length);
,并从这些块中获取主机。
如果我感兴趣的部分跨越多个区块,我不确定我需要做什么:
- 在形成FileInputSplit时,是否使用
blocks[i]
中的offset, length
- 如何将两个块塞进一个inputSplit
- 有一个combineInputSplit和一个compositeInputSplit,但不确定它是否用于此目的
我的猜测
我猜这没关系,我猜我可以使用文件的开始、长度,只需附加一个包含多个块的所有主机的列表。由于记录读取器只会使用fileSystem来读取文件。所有可能发生的情况是,映射器任务可能需要从不同的节点或机架读取块。
本Jira讨论了您所指的场景。