Java ApacheFlink:使用mapPartition按顺序处理数据
我正在尝试一个简单的Flink程序,它只需要获取一个文件,反转文件中的字符串并写出它 程序运行时,只有各行出现故障 例如 文件输入Java ApacheFlink:使用mapPartition按顺序处理数据,java,apache-flink,Java,Apache Flink,我正在尝试一个简单的Flink程序,它只需要获取一个文件,反转文件中的字符串并写出它 程序运行时,只有各行出现故障 例如 文件输入 Thing,Name Person,Vineet Fish,Karp Dog,Fido 输出文件 Fish,praK Thing,emaN Person,teeniV Dog,odiF 我期待着: Thing,emaN Person,teeniV Fish,praK Dog,odiF 下面是我为实现这一目标而编写的程序: package testflink;
Thing,Name
Person,Vineet
Fish,Karp
Dog,Fido
输出文件
Fish,praK
Thing,emaN
Person,teeniV
Dog,odiF
我期待着:
Thing,emaN
Person,teeniV
Fish,praK
Dog,odiF
下面是我为实现这一目标而编写的程序:
package testflink;
import java.util.Iterator;
import java.util.StringJoiner;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.operators.DataSource;
import org.apache.flink.core.fs.FileSystem.WriteMode;
import org.apache.flink.util.Collector;
public class BatchJob {
public static void main(String[] args) throws Exception {
final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
System.err.println(env.getParallelism());
DataSource<String> file = env.readTextFile("./data.csv");
file.mapPartition((Iterable<String> values, Collector<String> out) -> {
System.err.println("************* " + out.hashCode() + " Begin");
Iterator<String> iterator = values.iterator();
while (iterator.hasNext()) {
String tuple = iterator.next();
System.err.println("************* " + out.hashCode() + tuple);
String[] split = tuple.split(",");
String tuple1Rev = new StringBuilder(split[1]).reverse().toString();
out.collect(new StringJoiner(",").add(split[0]).add(tuple1Rev).toString());
}
System.err.println("************* " + out.hashCode() + " End");
}).returns(String.class).writeAsText("./dataO.csv", WriteMode.OVERWRITE).setParallelism(1);
env.execute("Flink Batch Java API Skeleton");
System.out.println("Done");
}
}
包testflink;
导入java.util.Iterator;
导入java.util.StringJoiner;
导入org.apache.flink.api.java.ExecutionEnvironment;
导入org.apache.flink.api.java.operators.DataSource;
导入org.apache.flink.core.fs.FileSystem.WriteMode;
导入org.apache.flink.util.Collector;
公共类批处理作业{
公共静态void main(字符串[]args)引发异常{
final ExecutionEnvironment env=ExecutionEnvironment.getExecutionEnvironment();
System.err.println(env.getParallelism());
数据源文件=env.readTextFile(“./data.csv”);
file.mapPartition((Iterable值,收集器输出)->{
System.err.println(“**********”+out.hashCode()+“Begin”);
迭代器迭代器=值。迭代器();
while(iterator.hasNext()){
字符串元组=迭代器.next();
System.err.println(“***********”+out.hashCode()+元组);
String[]split=tuple.split(“,”);
字符串tuple1Rev=新的StringBuilder(拆分[1]).reverse().toString();
out.collect(新StringJoiner(“,”).add(split[0]).add(tuple1Rev.toString());
}
System.err.println(“**********”+out.hashCode()+“End”);
}).returns(String.class).writesText(“./dataO.csv”,WriteMode.OVERWRITE).setParallelism(1);
execute(“Flink批处理Java API框架”);
系统输出打印项次(“完成”);
}
}
- 是否可以维护输入顺序?附近有什么好工作吗李>
- 我知道当有可用的
方法时,我正在读取csv&拆分字符串。问题是csv每行/元组可以有一个动态的COMLUMN数。我无法理解如何将其转换为每个元组具有动态列数的数据源。MapPartition需要定义的类型-如何在运行时替换readAsCsv()
-Tuple0
Tuple25
- 还有最后一个问题-我可以限制分区在
参数中的值不超过n吗Iterable values
提前感谢!:) Flink的
mapPartition
维护每个并行分区中记录的顺序。但是,用例中的问题是如何将数据分配给MapPartition操作符的并行任务
您使用的是一个TextInputFormat
,它将输入文件划分为多个输入拆分,这些拆分由数据源操作符的并行实例独立处理。每个数据源实例在本地将其所有记录转发给后续的MapPartition操作符,这会将其结果记录转发给接收器。管道如下所示:
source_1 -> mapPartition_1 -> sink_1
source_2 -> mapPartition_2 -> sink_2
source_3 -> mapPartition_3 -> sink_3
...
因此,从源代码开始,所有记录都按顺序处理。但是,由于输入拆分是随机分配给源任务的,而接收器是独立运行的(没有协调),因此输出只是部分排序(从同一拆分读取的记录是有序的)
将源的并行度设置为1没有帮助,因为它将以循环方式将其结果记录发送给后续任务,以利用后续操作符的并行度。另外,将整个作业的并行度设置为1也没有帮助,因为拆分仍然可以由单个源任务以随机顺序处理。我知道的唯一解决方案是在写入结果之前对每个输入记录进行编号。Flink的
mapPartition
维护每个并行分区中记录的顺序。但是,用例中的问题是如何将数据分配给MapPartition操作符的并行任务
您使用的是一个TextInputFormat
,它将输入文件划分为多个输入拆分,这些拆分由数据源操作符的并行实例独立处理。每个数据源实例在本地将其所有记录转发给后续的MapPartition操作符,这会将其结果记录转发给接收器。管道如下所示:
source_1 -> mapPartition_1 -> sink_1
source_2 -> mapPartition_2 -> sink_2
source_3 -> mapPartition_3 -> sink_3
...
因此,从源代码开始,所有记录都按顺序处理。但是,由于输入拆分是随机分配给源任务的,而接收器是独立运行的(没有协调),因此输出只是部分排序(从同一拆分读取的记录是有序的)
将源的并行度设置为1没有帮助,因为它将以循环方式将其结果记录发送给后续任务,以利用后续操作符的并行度。另外,将整个作业的并行度设置为1也没有帮助,因为拆分仍然可以由单个源任务以随机顺序处理。我知道的唯一解决方案是在写入结果之前对每个输入记录进行编号。除此之外?:)除此之外?:)我现在有了一个csv,在上面我进行了排序。第一列是行号。它按字典分类。如何使其成为正确的数字排序?将该行拆分为一个
Tuple2
,其中行号为整数,其余行为字符串。然后你可以在整型字段上排序。我现在有一个csv,我在上面排序。第一列是行号。它按字典分类。如何使其成为正确的数字排序?将该行拆分为一个Tuple2
,其中行号为整数,其余行为字符串。然后可以在整数字段上排序。