自定义FileInputFormat始终将一个文件拆分分配给一个插槽

时间:2019-02-15 13:59:33

标签: protocol-buffers apache-flink flink-streaming

我一直在将protobuf记录写入我们的s3存储桶。我想使用flink数据集api从中读取数据。因此,我实现了自定义FileInputFormat以实现此目的。代码如下。

public class ProtobufInputFormat extends FileInputFormat<StandardLog.Pageview> {
    public ProtobufInputFormat() {
    }

    private transient boolean reachedEnd = false;

    @Override
    public boolean reachedEnd() throws IOException {
        return reachedEnd;
    }

    @Override
    public StandardLog.Pageview nextRecord(StandardLog.Pageview reuse) throws IOException {
        StandardLog.Pageview pageview = StandardLog.Pageview.parseDelimitedFrom(stream);
        if (pageview == null) {
            reachedEnd = true;
        }
        return pageview;
    }

    @Override
    public boolean supportsMultiPaths() {
        return true;
    }
}


public class BatchReadJob {

    public static void main(String... args) throws Exception {

        String readPath1 = args[0];

        ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();


        ProtobufInputFormat inputFormat =  new ProtobufInputFormat();
        inputFormat.setNestedFileEnumeration(true);

        inputFormat.setFilePaths(readPath1);

        DataSet<StandardLog.Pageview> dataSource = env.createInput(inputFormat);

        dataSource.map(new MapFunction<StandardLog.Pageview, String>() {
            @Override
            public String map(StandardLog.Pageview value) throws Exception {
                return value.getId();
            }
        }).writeAsText("s3://xxx", FileSystem.WriteMode.OVERWRITE);
        env.execute();

    }

}

问题是flink总是将一个文件拆分分配给一个并行插槽。换句话说,它总是处理与并行性相同数量的文件分割。

我想知道实现自定义FileInputFormat的正确方法是什么。

谢谢。

1 个答案:

答案 0 :(得分:0)

我相信您看到的行为是因为ExecutionJobVertex用等于顶点(数据源)并行度的FileInputFormat. createInputSplits()参数调用minNumSplits方法。因此,如果您想要不同的行为,则必须重写createInputSplits方法。

尽管您没有说出您实际想要的行为。例如,如果只希望每个文件分割一个,则可以覆盖testForUnsplittable()子类中的FileInputFormat方法,以始终返回true;还应将(受保护的)unsplittable布尔值设置为true。