簡體   English   中英

如何將 protobuf 字節數組從 Flink 寫入 Kafka

[英]How to write protobuf byte array from Flink to Kafka

我是 Flink 的新手。 我想要做的就是將我的 protobuf POJO 作為字節數組放入 kafka。 所以我的FlinkKafkaProducer看起來像這樣:

FlinkKafkaProducer<String> flinkKafkaProducer = createStringProducer(outputTopic, address);
        stringInputStream
                .map(//here returns byte[])
                .addSink(flinkKafkaProducer);

public static FlinkKafkaProducer<String> createStringProducer(String topic, String kafkaAddress) {
        return new FlinkKafkaProducer<>(kafkaAddress, topic, new SimpleStringSchema());
    }

現在它工作正常,但我的輸出是字符串。 我嘗試添加TypeInformationSerializationSchema()而不是new SimpleStringSchema()來更改輸出,但我無法正確調整它。 找不到任何教程。 有人可以幫忙嗎?

所以,我終於弄清楚如何將 protobuf 作為字節數組寫入 kafka 生產者。 問題在於序列化。 對於 POJO,flink 使用 libery Kryo進行自定義反序列化。 編寫 protobuf 的最佳方法是使用ProtobufSerializer.class 在這個例子中,我將從 kafka 字符串消息中讀取並寫入字節數組。 Gradle 依賴項:

 compile (group: 'com.twitter', name: 'chill-protobuf', version: '0.7.6'){
        exclude group: 'com.esotericsoftware.kryo', module: 'kryo'
    }
    implementation 'com.google.protobuf:protobuf-java:3.11.0'

登記:

StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();
environment.getConfig().registerTypeWithKryoSerializer(MyProtobuf.class, ProtobufSerializer.class);

KafkaSerializer 類

@Data
@RequiredArgsConstructor
public class MyProtoKafkaSerializer implements KafkaSerializationSchema<MyProto> {
    private final String topic;
    private final byte[] key;

    @Override
    public ProducerRecord<byte[], byte[]> serialize(MyProto element, Long timestamp) {
                
        return new ProducerRecord<>(topic, key, element.toByteArray());
    }
}

工作

  public static FlinkKafkaProducer<MyProto> createProtoProducer(String topic, String kafkaAddress) {
        MyProtoKafkaSerializer myProtoKafkaSerializer = new MyProtoKafkaSerializer(topic);
        Properties props = new Properties();
        props.setProperty("bootstrap.servers", kafkaAddress);
        props.setProperty("group.id", consumerGroup);
        return new FlinkKafkaProducer<>(topic, myProtoKafkaSerializer, props, FlinkKafkaProducer.Semantic.AT_LEAST_ONCE);
    }

 public static FlinkKafkaConsumer<String> createProtoConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) {
        Properties props = new Properties();
        props.setProperty("bootstrap.servers", kafkaAddress);
        props.setProperty("group.id", kafkaGroup);
        return new FlinkKafkaConsumer<>(topic, new SimpleStringSchema(), props);
    }

DataStream<String> stringInputStream = environment.addSource(flinkKafkaConsumer);
        FlinkKafkaProducer<MyProto> flinkKafkaProducer = createProtoProducer(outputTopic, address);
        stringInputStream
                .map(hashtagMapFunction)
                .addSink(flinkKafkaProducer);

        environment.execute("My test job");

來源

  1. https://ci.apache.org/projects/flink/flink-docs-release-1.10/dev/custom_serializers.html#register-a-custom-serializer-for-your-flink-program
  2. https://flink.apache.org/news/2020/04/15/flink-serialization-tuning-vol-1.html#protobuf-via-kryo

在這方面找到文檔確實似乎很棘手。 我假設您使用 Flink >= 1.9。 在這種情況下,以下應該起作用:

private static class PojoKafkaSerializationSchema implements KafkaSerializationSchema<YourPojo> {
    @Override
    public void open(SerializationSchema.InitializationContext context) throws Exception {}

    @Override
    public ProducerRecord<byte[], byte[]> serialize(YourPojo element,@Nullable Long timestamp) {
        // serialize your POJO here and return a Kafka `ProducerRecord`
        return null;
    }
}

// Elsewhere: 
PojoKafkaSerializationSchema schema = new PojoKafkaSerializationSchema();
FlinkKafkaProducer<Integer> kafkaProducer = new FlinkKafkaProducer<>(
    "test-topic",
    schema,
    properties,
    FlinkKafkaProducer.Semantic.AT_LEAST_ONCE
);

這段代碼主要受此測試用例的啟發,但我沒有時間實際運行它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM