我正在尝试使用数据集进行简单处理。
考虑具有两列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处重新启动。同样,当我将其应用于更大的文件时,计数器会以某种方式从某个时间重置为时间,所以我不知道线的总数。
请您解释为什么我的实施会以这种方式运作?另外,什么可能解决我的问题?
谢谢!
答案 0 :(得分:0)
这是一个多线程问题。你有几个任务槽?
我必须在运行之前清理你的代码 - 我建议将来发布完整的工作示例,以便你有机会获得更多答案。
跟踪计数的方式不是线程安全的,因此如果您有多个任务槽,则计数值不准确会出现问题。
如数据工匠字数统计示例所示,正确的计数方法是使用元组中的第3个插槽来简单地存储值1,然后对数据集求和。
resultTuple = new Tuple3(m.f0,m.f1, 1L);
然后
csvOut2.sum(2).print();
其中2是包含值1的元组的索引。