NLineInputFormat の getSplitsForFile() fn を調べました。入力ファイル用に InputStream が作成され、その反復と分割が n 行ごとに作成されることがわかりました。効率的ですか?特に、この読み取り操作がマッパー タスクを起動する前に 1 つのノードで発生している場合。5 GB のファイルがある場合はどうなりますか。基本的には、ファイル データが 2 回シークされることを意味します。これがボトルネックである場合、hadoop ジョブはこれをどのようにオーバーライドしますか?
public static List<FileSplit> getSplitsForFile(FileStatus status,
Configuration conf, int numLinesPerSplit) throws IOException {
List<FileSplit> splits = new ArrayList<FileSplit> ();
Path fileName = status.getPath();
if (status.isDirectory()) {
throw new IOException("Not a file: " + fileName);
}
FileSystem fs = fileName.getFileSystem(conf);
LineReader lr = null;
try {
FSDataInputStream in = fs.open(fileName);
lr = new LineReader(in, conf);
Text line = new Text();
int numLines = 0;
long begin = 0;
long length = 0;
int num = -1;
<!-- my part of concern start -->
while ((num = lr.readLine(line)) > 0) {
numLines++;
length += num;
if (numLines == numLinesPerSplit) {
splits.add(createFileSplit(fileName, begin, length));
begin += length;
length = 0;
numLines = 0;
}
}
<!-- my part of concern end -->
if (numLines != 0) {
splits.add(createFileSplit(fileName, begin, length));
}
} finally {
if (lr != null) {
lr.close();
}
}
return splits;
}
私のユースケースを clément-mathieu に提供するための編集
私のデータセットは、それぞれ約2GBの大きな入力ファイルです。ファイルの各行は、データベースのテーブル (私の場合は cassandra) に挿入する必要があるレコードを表します。データベースへの一括トランザクションを n 行ごとに制限したいと考えています。nlineinputformat を使用してこれを行うことに成功しました。私の唯一の懸念は、本番環境で現れる可能性のある隠れたパフォーマンスのボトルネックがあるかどうかです。