Flink自带的Source源算子以及自定义数据源Source

Flink的DataStream API(基础篇)

Flink程序主要是分为
Source -> Transform -> Sink
本篇文章主要介绍的是Flink的源算子

Source源算子

POJO类的定义:

POJO类定义为一个数据类型,Flink会把这样的类作为一个特殊的POJO数据类型,方便数据的解析和序列化

POJO的规范:

  • 是公有的
  • 有一个无参的构造方法
  • 所有的属性都是公有的
  • 所有属性的数据类型都是可以序列化的
从集合中读取数据
package com.dcit.chacpter01;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import java.util.ArrayList;

public class StreamSource {
    public static void main(String[] args) throws Exception {
        /**
         * 从集合中读取数据
         */
        // 1.创建Flink运行时环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        ArrayList<Event> source = new ArrayList<>();
        // Event是自定义的POJO数据类    url  user timestamp
        source.add(new Event("./home","chaochao",1000L));
        source.add(new Event("./home","lisi",2000L));
	   // 从集合中直接读取数据
        DataStreamSource<Event> eventDataStreamSource = env.fromCollection(source);
        // 打印
        eventDataStreamSource.print();
        // 执行
        env.execute();
    }
}
从文件中读取数据

env.readTextFile(“xxxx.txt”)

从Scoket中读取数据
DataStream<String> stream = env.socketTextStream("hadoop102",8888);
从Kafka中读取数据

想要以 Kafka 作为数据源获取数据,我们只需要引入 Kafka 连接器的依赖。Flink 官

方提供的是一个通用的 Kafka 连接器,它会自动跟踪最新版本的 Kafka 客户端。目前最新版本

只支持 0.10.0 版本以上的 Kafka,读者使用时可以根据自己安装的 Kafka 版本选定连接器的依

赖版本。这里我们需要导入的依赖如下。

需要添加依赖

然后调用 env.addSource(),传入 FlinkKafkaConsumer 的对象实例就可以了。

pom.xml文件

<dependency>
 <groupId>org.apache.flink</groupId>
 <artifactId>flink-connector-kafka_${scala.binary.version}</artifactId>
 <version>${flink.version}</version>
</dependency>
        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers","hadoop102:9092");
        properties.setProperty("group.id", "consumer-group");
        properties.setProperty("key.deserializer",
                "org.apache.kafka.common.serialization.StringDeserializer");
        properties.setProperty("value.deserializer",
                "org.apache.kafka.common.serialization.StringDeserializer");
        properties.setProperty("auto.offset.reset", "latest");



        DataStreamSource<String> DS = env.addSource(
                new FlinkKafkaConsumer<String>("clicks", new SimpleStringSchema(), properties)
        );

创建 FlinkKafkaConsumer 时需要传入三个参数:

  • 第一个参数 topic,定义了从哪些主题中读取数据。可以是一个 topic,也可以是 topic

列表,还可以是匹配所有想要读取的 topic 的正则表达式。当从多个 topic 中读取数据

时,Kafka 连接器将会处理所有 topic 的分区,将这些分区的数据放到一条流中去。

  • 第二个参数是一个 DeserializationSchema 或者 KeyedDeserializationSchema。Kafka 消

息被存储为原始的字节数据,所以需要反序列化成 Java 或者 Scala 对象。上面代码中

使用的 SimpleStringSchema,是一个内置的 DeserializationSchema,它只是将字节数

组简单地反序列化成字符串。DeserializationSchema 和 KeyedDeserializationSchema 是

公共接口,所以我们也可以自定义反序列化逻辑。

  • 第三个参数是一个 Properties 对象,设置了 Kafka 客户端的一些属性。
自定义Source

env.addSource(new SourceFunction())

定义一个ClickSource 实现SourceFunction接口 实现run方法和canel方法

然后在main方法里的addSource(new CliceSource()) 将ClicksSouce传入即可

package com.dcit.chacpter01;

import org.apache.flink.streaming.api.functions.source.SourceFunction;
import sun.security.util.Length;

import java.util.Calendar;
import java.util.Random;

public class ClickSource implements SourceFunction<Event> {
    public volatile boolean running = true;
    @Override
    public void run(SourceContext<Event> sourceContext) throws Exception {
        //随机数据
        Random random = new Random();
        //定义选取的数据
        String [] users = {"Mary","Alice","Bob","Cary"};
        String[] urls = {"./home", "./cart", "./fav", "./prod?id=1",
                "./prod?id=2"};
        while (running){
            Thread.sleep(2000);
            long time = Calendar.getInstance().getTimeInMillis();
            sourceContext.collect(
                    new Event(urls[random.nextInt(urls.length)],users[random.nextInt(users.length)]
                    ,time
                    )
            )
            ;
        }

    }

    @Override
    public void cancel() {
        running = false;
    }
}

    DataStreamSource<Event> ds = env.addSource(new ClickSource());

注意:实现的SourceFunction这个接口是不能设置并行度的

​ 如果需要调整并行度那么要继承 ParallelSourceFunction 接口 里面的重写方法和之前那个一样

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink是一个高性能流式处理引擎,可以读取各种各样的数据源,包括自定义自定义是使用Flink的一种方式,主要是为了读取一些非标准的数据源或者改善性能表现。 自定义source是一个接口,需要实现org.apache.flink.streaming.api.functions.source.SourceFunction接口。该接口只有两个方法,一个是run(),另一个是cancel()。在run()中实现数据读取的逻辑,cancel()用于取消读取。自定义source主要包括数据什么时候开始读取,如何读取数据及什么时候读取结束等。 实现自定义source需要在程序入口处调用StreamExecutionEnvironment对象中的addSource()方法,将自定义source添加到批处理中。示例如下: ```java DataStreamSource<String> dataSource = env.addSource(new MySource()); ``` 其中,MySource自定义数据源。 在自定义source中,可以采用文件缓存方式来提升读取性能。通过FileChannel打开文件,使用ByteBuffer读取文件,然后将ByteBuffer通过Flink的DataStream传递给后续算子处理。这种方式可以大大提升文件读取的性能,减少文件IO的次数。示例如下: ```java try { FileInputStream inputStream = new FileInputStream(filePath); FileChannel inChannel = inputStream.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024 * 5); while (inChannel.read(buffer) != -1) { buffer.flip(); sourceContext.collect(buffer); buffer.clear(); } } catch (IOException e) { e.printStackTrace(); } ``` 自定义source的实现需要根据具体的数据源进行,但总体来说,实现自定义并不复杂,只需要理解Flink数据处理的机制,并编写封装好的代码即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值