Apache flink Flink如何在S3中将数据集编写为拼花文件?
如何使用Flink将数据集作为拼花文件写入s3 bucket中。有没有像spark:DF.write.parquet(“write-in-parquet”)这样的直接函数 请帮助我如何编写拼花格式的flink数据集 尝试将数据集转换为(Void、genericord)时遇到问题Apache flink Flink如何在S3中将数据集编写为拼花文件?,apache-flink,parquet,Apache Flink,Parquet,如何使用Flink将数据集作为拼花文件写入s3 bucket中。有没有像spark:DF.write.parquet(“write-in-parquet”)这样的直接函数 请帮助我如何编写拼花格式的flink数据集 尝试将数据集转换为(Void、genericord)时遇到问题 DataSet df=allEvents.flatMap(新的flatMap函数(){ @凌驾 公共void flatMap(Tuple2 longWritableTextTuple2,收集器)引发异常{ JsonAvr
DataSet df=allEvents.flatMap(新的flatMap函数(){
@凌驾
公共void flatMap(Tuple2 longWritableTextTuple2,收集器)引发异常{
JsonAvroConverter converter=新的JsonAvroConverter();
Schema Schema=newschema.Parser().parse(新文件(“test.avsc”);
试一试{
GenericRecord=converter.convertToGenericDataRecord(longWritableTextTuple2.f1.toString().getBytes(),模式);
collector.collect(新的Tuple2(null,record));
}
捕获(例外e){
System.out.println(“转换为avro时出错”)
}
}
});
Job Job=Job.getInstance();
HadoopOutputFormat parquetFormat=新的HadoopOutputFormat(新的AvroParquetOutputFormat(),作业);
setOutputPath(作业,新路径(outputPath));
df.输出(拼花格式);
execute();
请帮我解决我做错的事。我得到了一个例外和这个
代码不起作用。您将通过
新建HadoopOutputFormat(parquetOutputFormat,job)
创建一个Flink OutputFormat,然后将其传递到数据集。输出(xxx)
这份工作来自
import org.apache.hadoop.mapreduce.Job;
...
Job job = Job.getInstance();
parquetOutputFormat
通过以下方式创建:
import org.apache.parquet.hadoop.ParquetOutputFormat;
...
ParquetOutputFormat<MyOutputType> parquetOutputFormat = new ParquetOutputFormat<>();
import org.apache.parquet.hadoop.ParquetOutputFormat;
...
ParquetOutputFormat ParquetOutputFormat=新ParquetOutputFormat();
请看这比使用Spark要复杂一点。我能够在Flink中读写拼花地板数据的唯一方法是通过Hadoop和MapReduce的兼容性。依赖项中需要
hadoop mapreduce客户端核心
和flink hadoop兼容性
。
然后您需要创建一个适当的HadoopOutoutFormat
。您需要这样做:
val job = Job.getInstance()
val hadoopOutFormat = new hadoop.mapreduce.HadoopOutputFormat[Void, SomeType](new AvroParquetOutputFormat(), job)
FileOutputFormat.setOutputPath(job, [somePath])
然后你可以做:
dataStream.writeUsingOutputFormat(hadoopOutFormat)
你没有说你会遇到什么异常,但这里有一个完整的例子说明如何实现这一点 要点是:
- 使用
org.apache.flink.api.java.hadoop.mapreduce.HadoopOutputFormat
- 来自dependency
org.apache.flink:flink-hadoop-compatibility_2.11:1.11.0
是一个适配器,允许您使用为Hadoop开发的输出格式HadoopOutputFormat
- 您需要一个
,因为hadoop的数据集
与键-值对一起工作,我们对键不感兴趣,所以我们使用输出格式
作为键类型,并且该值需要是Avro的Void
或索引记录
通用记录
- 来自dependency
- 使用
org.apache.parquet.avro.AvroParquetOutputFormat
- 来自dependency
org.apache.parquet:parquet avro:1.11.1
- 这个hadoop生产拼花地板
- 这继承自
org.apache.parquet.hadoop.FileOutputFormat
- 来自dependency
- 创建您自己的
- 您不能使用新的GenericData.Record(schema),因为这样的记录是不可序列化的
,Flink要求它是可序列化的java.io.notserializableeexception:org.apache.avro.schema$字段是不可序列化的
- 您仍然需要提供一个
方法,但您可以返回getSchema()
或返回您在静态成员中保留的值(这样就不需要序列化,并且可以避免null
)java.io.notserializableeexception:org.apache.avro.Schema$字段不可序列化
- 您不能使用新的GenericData.Record(schema),因为这样的记录是不可序列化的
import org.apache.avro.Schema;
import org.apache.avro.generic.IndexedRecord;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.DataSet;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.hadoop.mapreduce.HadoopOutputFormat;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.configuration.Configuration;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.parquet.avro.AvroParquetOutputFormat;
import org.apache.parquet.hadoop.metadata.CompressionCodecName;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class MyParquetTest implements Serializable {
public static void main(String[] args) throws Exception {
new MyParquetTest().start();
}
private void start() throws Exception {
final ExecutionEnvironment env = ExecutionEnvironment.createLocalEnvironment();
Configuration parameters = new Configuration();
Stream<String> stringStream = IntStream.range(1, 100).mapToObj(n -> String.format("Entry %d", n));
DataSet<String> text = env.fromCollection(stringStream.collect(Collectors.toCollection(ArrayList::new)));
Job job = Job.getInstance();
HadoopOutputFormat<Void, IndexedRecord> hadoopOutputFormat = new HadoopOutputFormat<>(new AvroParquetOutputFormat<IndexedRecord>(), job);
FileOutputFormat.setCompressOutput(job, true);
FileOutputFormat.setOutputCompressorClass(job, CompressionCodecName.SNAPPY.getHadoopCompressionCodecClass());
FileOutputFormat.setOutputPath(job, new org.apache.hadoop.fs.Path("./my-parquet"));
final Schema schema = new Schema.Parser().parse(MyRecord.class.getClassLoader().getResourceAsStream("schema.avsc"));
AvroParquetOutputFormat.setSchema(job, schema);
DataSet<Tuple2<Void, IndexedRecord>> text2 = text.map(new MapFunction<String, Tuple2<Void, IndexedRecord>>() {
@Override
public Tuple2<Void, IndexedRecord> map(String value) throws Exception {
return Tuple2.of(null, new MyRecord(value));
// IndexedRecord record = new GenericData.Record(schema); // won't work becuase Schema$Field is not serializable
// record.put(0, value);
// return Tuple2.of(null, record);
}
});
text2.output(hadoopOutputFormat);
env.execute("Flink Batch Java API Skeleton");
}
public static class MyRecord implements IndexedRecord {
private static Schema schema;
static {
try {
schema = new Schema.Parser().parse(MyRecord.class.getClassLoader().getResourceAsStream("schema.avsc"));
} catch (IOException e) {
e.printStackTrace();
}
}
private final String value;
public MyRecord(String value) {
this.value= value;
}
@Override
public void put(int i, Object v) {
throw new NotImplementedException("You can't update this IndexedRecord");
}
@Override
public Object get(int i) {
return this.value;
}
@Override
public Schema getSchema() {
return schema; // or just return null and remove the schema member
}
}
}
以及依赖关系:
implementation "org.apache.flink:flink-java:${flinkVersion}"
implementation "org.apache.flink:flink-avro:${flinkVersion}"
implementation "org.apache.flink:flink-streaming-java_${scalaBinaryVersion}:${flinkVersion}"
implementation "org.apache.flink:flink-hadoop-compatibility_${scalaBinaryVersion}:${flinkVersion}"
implementation "org.apache.parquet:parquet-avro:1.11.1"
implementation "org.apache.hadoop:hadoop-client:2.8.3"
我仍然不清楚我是否只想读取一个带有JSON的文件,让我们创建一个数据集,然后如何将其写入拼花格式。我必须为我的json数据定义avro模式?请提供一些细节,因为我是新来的。创建用于写入拼花地板的Avro模式是常见的做法,是的(例如,请参阅)。请注意,这个关于如何做的问题不是Flink的问题,您可能想问一个新问题,这个问题被标记为Parquet和Avro。
{
"name": "aa",
"type": "record",
"fields": [
{"name": "value", "type": "string"}
]
}
implementation "org.apache.flink:flink-java:${flinkVersion}"
implementation "org.apache.flink:flink-avro:${flinkVersion}"
implementation "org.apache.flink:flink-streaming-java_${scalaBinaryVersion}:${flinkVersion}"
implementation "org.apache.flink:flink-hadoop-compatibility_${scalaBinaryVersion}:${flinkVersion}"
implementation "org.apache.parquet:parquet-avro:1.11.1"
implementation "org.apache.hadoop:hadoop-client:2.8.3"