Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache flink Flink如何在S3中将数据集编写为拼花文件?_Apache Flink_Parquet - Fatal编程技术网

Apache flink Flink如何在S3中将数据集编写为拼花文件?

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

如何使用Flink将数据集作为拼花文件写入s3 bucket中。有没有像spark:DF.write.parquet(“write-in-parquet”)这样的直接函数

请帮助我如何编写拼花格式的flink数据集

尝试将数据集转换为(Void、genericord)时遇到问题

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
    • HadoopOutputFormat
      是一个适配器,允许您使用为Hadoop开发的输出格式
    • 您需要一个
      数据集
      ,因为hadoop的
      输出格式
      与键-值对一起工作,我们对键不感兴趣,所以我们使用
      Void
      作为键类型,并且该值需要是Avro的
      索引记录
      通用记录
  • 使用
    org.apache.parquet.avro.AvroParquetOutputFormat
    • 来自dependency
      org.apache.parquet:parquet avro:1.11.1
    • 这个hadoop生产拼花地板
    • 这继承自
      org.apache.parquet.hadoop.FileOutputFormat
  • 创建您自己的
    • 您不能使用新的GenericData.Record(schema),因为这样的记录是不可序列化的
      java.io.notserializableeexception:org.apache.avro.schema$字段是不可序列化的
      ,Flink要求它是可序列化的
    • 您仍然需要提供一个
      getSchema()
      方法,但您可以返回
      null
      或返回您在静态成员中保留的值(这样就不需要序列化,并且可以避免
      java.io.notserializableeexception:org.apache.avro.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"