Flink kafka connector之反序列化方法解析和应用场景

KeyedDeserializationSchema 解析

    KeyedDeserializationSchema是flink-kafka-connector(1.7)的一个重要的类,它的作用是将kafka的消息进行反序列化,我们最常用的新建FlinkKafkaConsumer中的SimpleStringSchema就是该类的一个具体实现,作用就是将kafka message的value吐出来供下游消费。

FlinkKafkaConsumer011 consumer = new FlinkKafkaConsumer011<>("topic", new SimpleStringSchema(), properties)

利用这一个自定义很方便的类,我们可以根据我们的业务实现很多具体的功能

从kafka直接读出JSON

    虽然flink内部提供了JSONKeyValueDeserializationSchema,但是它采用的是Jackson,而我们生产习惯用fastjson,如果我们不关注kafka消息的metadata,而是关注的是消息体的json,我们就可以这么用,而且可以直接将json吐到下游的算子进行处理,省略了一个map的操作。

public class JsonDeserializationSchema implements KeyedDeserializationSchema <JSONObject> {
    @Override
    public JSONObject deserialize(byte[] key, byte[] message, String topic, int partition, long offset){
        try {
            String msg = new String(message, "utf-8");
            return JSONObject.parseObject(msg);
        }catch (Exception e){
            return null;
        }
    }

    @Override
    public boolean isEndOfStream(Tuple2 nextElement) {
        return false;
    }
	.......
}

获取kafka message的元信息

    有时候如果业务方同时消费多个Topic的时候,他希望知道哪条消息是从哪个Topic过来的;或者该消息对应的offset是多少,用这个值来做监控,我们就可以进行如下的改造。除了来源Topic和对应offset之外,它还可以获取kafka消息的key,甚至是时间戳和分区信息。

public class JsonWithMetaDataDeserializationSchema implements KeyedDeserializationSchema <Tuple2<MessageMetaData, JSONObject>> {
    @Override
    public Tuple2<MessageMetaData, JSONObject> deserialize(byte[] key, byte[] message, String topic, int partition, long offset){
        MessageMetaData metaData = new MessageMetaData();
        try {
            String msg = new String(message, "utf-8");
            metaData.setSourceName(topic);
            return new Tuple2<>(metaData, JSONObject.parseObject(msg));
        }catch (Exception e){
            metaData.setDirty(true);
            metaData.setExceptionType(e.getClass().getSimpleName());
            return null;
        }
    }

    @Override
    public boolean isEndOfStream(Tuple2 nextElement) {
        return false;
    }
	......
}

消费到指定位置自动停止

    除了KeyedDeserializationSchema这个类本身的抽象方法deserialize之外,它的父类KafkaDeserializationSchema还有一个方法叫isEndOfStream,这个方法可以用来判断消费流是不是应该终止了。利用这一点,我们可以实现固定消费多少条数据就自动停止任务,这个工具用来测试简直是太好用了,为此我们基于这个CountDeserializationSchema 开发了一个kafka跨集群的同步测试工具叫kafkaDistcp。除了指定条数之外,我们还可以往kafka发送指定格式的消息,然后flink程序消费到这条消息就停止消费,但是注意一点是flink的消费是按照分区来的,所以我们得往每个分区都发一条这样格式的消息,然后判断是否所有分区的“结束”消息都收到了,如果是的话,就停止消费。

public class CountDeserializationSchema implements KeyedDeserializationSchema  <Tuple2<MessageMetaData, String>> {

    private int maxCount;
    private int count;
    public CountDeserializationSchema(int maxCount) {
        this.maxCount=maxCount;
    }

    @Override
    public String deserialize(byte[] key, byte[] message, String topic, int partition, long offset){
        try {
            String msg = new String(message, StandardCharsets.UTF_8);
            count++;
            return msg;
        }catch (Exception e){
            return null;
        }
    }

    @Override
    public boolean isEndOfStream(Tuple2 nextElement) {
        return this.count>=maxCount+1;
    }
	......
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值