详解Flink读取不同格式kafka数据的使用与实现


Flink有封装好的读写kafka数据的connector可以直接使用,但不同的数据格式该使用什么方法获取?自己想要的自定义数据格式,如byte[]等原生没有,又该如何实现?下面进行详细介绍。

1. Flink读取Kafka数据

引入的pom依赖(根据具体kafka的版本选择,笔者使用的kafka是0.9版本)

<dependency>
	<groupId>org.apache.flink</groupId>
	<artifactId>flink-connector-kafka-0.9_2.11</artifactId>
	<version>1.7.1</version>
</dependency>

下面以常用的读取String格式数据为例进行说明,具体使用方法如下:

import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer09;
import org.apache.kafka.clients.consumer.ConsumerConfig;

import java.util.Properties;

public class KafkaUtils {

    public static FlinkKafkaConsumer09<String> getStringConsumer(String topic, String broker, String groupid) {

        Properties properties = new Properties();
        properties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, broker);
        properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, groupid);

        FlinkKafkaConsumer09<String> myConsumer = new FlinkKafkaConsumer09<String>(topic, new SimpleStringSchema(),
            properties);

        // 从上次消费offset处读取
        myConsumer.setStartFromGroupOffsets();

        return myConsumer;
    }

从上述可知,消费kafka除了需要topic, broker, groupid信息, SimpleStringSchema才是控制读取到的数据类型为String的。进入FlinkKafkaConsumer09构造方法,可以看到DeserializationSchemaKeyedDeserializationSchema的作用是将获取到的byte[]类型数据反序列化为flink的类对象,SimpleStringSchema即是实现DeserializationSchema接口的一个子类。那么我们就可以去自己实现这两个接口得到自定义的数据类型。
在这里插入图片描述
在这里插入图片描述

2. 读取不同数据类型的kafka数据

从小节1可知,我们可以通过实现DeserializationSchema或KeyedDeserializationSchema来得到自己不同格式类型的数据。

在这里插入图片描述

图1 DeserializationSchema已实现类

新建类实现DeserializationSchema的deserialize(byte[] message)方法即可生成新的获取其它格式数据的schema类。如SimpleStringSchema类的实现方式如下:
在这里插入图片描述
我们如果不想让数据反序列化,想要直接读取byte[]格式的数据,就在deserialize方法中,把message直接返回即可。

在这里插入图片描述

图2 KeyedDeserializationSchema已实现类

KeyedDeserializationSchema接口相比DeserializationSchema包含更多信息,DeserializationSchema仅能处理kafka消息的消息体message,而KeyedDeserializationSchema还可以拿到每条message的messageKey、topic、partition和offset。例如JSONKeyValueDeserializationSchema类就是将这些信息封装成了JSON对象,使得获取到的DataStream每条数据格式都是一个JSON对象。源码中实现如下:
在这里插入图片描述
得到DataStream<ObjectNode>,可以通过访问ObjectNode对象去获取每条数据的具体信息。

当然也可以自己去实现这两个方法,获得自己任意想要的数据格式。例如,笔者想要获取Tuple2<String, byte[]>格式的kafka数据,f0位置为topic, partition, offset组成的UUID去标识每条消息的唯一性,f1位置为原message,那么如下实现即可。

import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.util.serialization.KeyedDeserializationSchema;
import java.util.UUID;
import static org.apache.flink.api.java.typeutils.TypeExtractor.getForClass;

public class ByteWithMetaDeserialzationSchema implements KeyedDeserializationSchema<Tuple2<String, byte[]>> {

    Tuple2<String, byte[]> tuple = null;

    @Override
    public Tuple2<String, byte[]> deserialize(byte[] messageKey, byte[] message,
                                              String topic, int partition, long offset) {
        tuple = new Tuple2<>();


        String messageId = new StringBuilder()
            .append(topic).append("_")
            .append(partition).append("_")
            .append(offset).toString();

        tuple.f0 = UUID.nameUUIDFromBytes(messageId.getBytes()).toString();

        tuple.f1 = message;
        return tuple;
    }

    @Override
    public boolean isEndOfStream(Tuple2<String, byte[]> nextElement) {
        return false;
    }

    @Override
    public TypeInformation<Tuple2<String, byte[]>> getProducedType() {
        Class clazz = Tuple2.class;
        return getForClass(clazz);
    }
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值