Flink:基于某些计算,使用新列来丰富数据集

时间:2017-01-17 14:56:45

标签: count dataset apache-flink

我正在尝试使用数据集进行简单处理。

考虑具有两列String类型的数据集。对于这个数据集,我想添加第Long类型的第三列,它累积到目前为止在数据集中看到的记录数。

示例:

输入:

A,B

B,C

C,d

输出:

A,B,1

B,C,2

C,d,3

我尝试过以下解决方案,但结果很奇怪:

    DataSet<Tuple2<String, String>> csvInput = env.readCsvFile("src/main/resources/data_file")
            .ignoreFirstLine()
            .includeFields("11")
            .types(String.class,String.class);

    long cnt=0;
    DataSet<Tuple3<String, String, Long>> csvOut2 = csvInput.map(new MyMapFunction(cnt));


private static class MyMapFunction implements MapFunction<Tuple2<String, String>, Tuple3<String, String, Long>> {

    long cnt;
    public MyMappingFunction(long cnt) {
        this.cnt = cnt;
    }

    @Override
    public Tuple3<String, String, Long> map(Tuple2<String, String> m) throws Exception {

        Tuple3 <String ,String, Long> resultTuple = new Tuple3(m.f0,m.f1, Long.valueOf(cnt));

        cnt++;
        return resultTuple;
    }
}

当我将此解决方案应用于包含100个条目的文件时,我得到的计数为47而不是100.计数器在53处重新启动。同样,当我将其应用于更大的文件时,计数器会以某种方式从某个时间重置为时间,所以我不知道线的总数。

请您解释为什么我的实施会以这种方式运作?另外,什么可能解决我的问题?

谢谢!

1 个答案:

答案 0 :(得分:0)

这是一个多线程问题。你有几个任务槽?

我必须在运行之前清理你的代码 - 我建议将来发布完整的工作示例,以便你有机会获得更多答案。

跟踪计数的方式不是线程安全的,因此如果您有多个任务槽,则计数值不准确会出现问题。

如数据工匠字数统计示例所示,正确的计数方法是使用元组中的第3个插槽来简单地存储值1,然后对数据集求和。

resultTuple = new Tuple3(m.f0,m.f1, 1L);

然后

csvOut2.sum(2).print();

其中2是包含值1的元组的索引。