Flink之kafka消息解析器2

概要

昨天的话题,FlinkSource消费kafka数据自定义反序列化,获取自己想要的数据和类型

实现过程

public class TestWithMetadataDeserializationSchema implements KafkaRecordDeserializationSchema<KafkaMessageWithMetadata> {
  1. 第一步:自定义实现这个接口,这里的泛型一般的都是自定义类
@Override
    public void deserialize(ConsumerRecord<byte[], byte[]> record, Collector<KafkaMessageWithMetadata> out) throws IOException {
        //如果消息为空,返回null
        if (record.value() == null) return;

        KafkaRecordData recordData = new KafkaRecordData();
        recordData.setValue(new String(record.value(), StandardCharsets.UTF_8));

        KafkaMessageWithMetadata messageWithMetadata = new KafkaMessageWithMetadata(
                record.key() != null ? new String(record.key()) : null,
                record.partition(),
                record.offset(),
                recordData,
                record.timestamp()
        );

        out.collect(messageWithMetadata);
    }
  1. 第二步:主要是重写这个方法,注意record就是kafka消费过来的数据,其中包括topic,partition等主要的元数据。获取自己需要数据放回自定义的对象中,并返回。
    注意:KafkaMessageWithMetadata的源码中可以接收MyObjectData类型,所以获取需要的数据放入自定义对象中比较好
 @Override
    public TypeInformation<KafkaMessageWithMetadata> getProducedType() {
        return TypeInformation.of(KafkaMessageWithMetadata.class);
    }
  1. 第三步:这个写一下KafkaMessageWithMetadata类型。这步应该无关紧要,自己可以试试不写,会有什么效果
 KafkaSource<KafkaMessageWithMetadata> kafkaSource = KafkaSource.<KafkaMessageWithMetadata>builder()
                .setBootstrapServers(prop.getProperty("kafka.bootstrap.servers"))
                .setGroupId(prop.getProperty("kafka.group.id_test"))
                .setTopics(prop.getProperty("kafka.topic"))
                .setStartingOffsets(OffsetsInitializer.earliest())
                .setDeserializer(new TestWithMetadataDeserializationSchema())
                .build();
  1. 第四步:KafkaSource设置setDeserializer,参数就是刚刚写的类

遇到的问题

  1. 注意KafkaDeserializationSchemaKafkaRecordDeserializationSchema的区别

刚开始没注意实现了KafkaDeserializationSchema这个接口,发现这个接口对于元数据的操作稍微复杂一点。但是都能实现消费kafka元数据的访问。有兴趣可以试验一下。

public class CustomKafkaDeserializationSchema implements KafkaDeserializationSchema<String> {

    private final SimpleStringSchema stringSchema = new SimpleStringSchema();

    @Override
    public String deserialize(byte[] messageKey, byte[] message, String topic, int partition, long offset) throws IOException {
        // 反序列化消息值
        return stringSchema.deserialize(message);
    }

    @Override
    public boolean isEndOfStream(String nextElement) {
        // 判断是否为结束标志
        return false;
    }

    @Override
    public TypeInformation<String> getProducedType() {
        return TypeInformation.of(String.class);
    }
}
  1. 注意setDeserializersetValueOnlyDeserializer 的区别

setDeserializer这个是自定义序列化采用的
setValueOnlyDeserializer这个是只需要value采用的
对于自己的需求去选择

还有一些bug,日后想起来再记录

你可能感兴趣的:(flink,kafka,大数据)