Flink-源算子-读取数据的几种方式

Flink可以从各种来源获取数据,然后构建DataStream进行转换处理。一般将数据的输入来源称为数据源(data source),而读取数据的算子就是源算子(source operator)。所以,source就是我们整个处理程序的输入端。

在Flink1.12以前,旧的添加source的方式,是调用执行环境的addSource()方法:

java 复制代码
DataStream<String> stream = env.addSource(...);

方法传入的参数是一个"源函数"(source function),需要实现SourceFunction接口。

从Flink1.12开始,主要使用流批统一的新Source架构:

java 复制代码
DataStreamSource<String> stream = env.fromSource(...)

Flink直接提供了很多预实现的接口,此外还有很多外部连接工具也帮我们实现了对应的Source,通常情况下足以应对我们的实际需求。

从集合中读取数据

最简单的读取数据的方式,就是在代码中直接创建一个Java集合,然后调用执行环境的fromCollection方法进行读取。这相当于将数据临时存储到内存中,形成特殊的数据结构后,作为数据源使用,一般用于测试。

java 复制代码
public static void main(String[] args) throws Exception {

    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

    
List<Integer> data = Arrays.asList(1, 22, 3);
        DataStreamSource<Integer> ds = env.fromCollection(data);

	stream.print();

    env.execute();
}

从文件读取数据

真正的实际应用中,自然不会直接将数据写在代码中。通常情况下,我们会从存储介质中获取数据,一个比较常见的方式就是读取日志文件。这也是批处理中最常见的读取方式。

java 复制代码
public static void main(String[] args) throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        FileSource<String> fileSource = FileSource.forRecordStreamFormat(new TextLineInputFormat(), new Path("input/word.txt")).build();

        env.fromSource(fileSource,WatermarkStrategy.noWatermarks(),"file")
    .print();

        env.execute();
}

说明:

  • 参数可以是目录,也可以是文件;还可以从HDFS目录下读取,使用路径hdfs://...;

  • 路径可以是相对路径,也可以是绝对路径;

  • 相对路径是从系统属性user.dir获取路径:idea下是project的根目录,standalone模式下是集群节点根目录;

从socket读取数据

不论从集合还是文件,我们读取的其实都是有界数据。在流处理的场景中,数据往往是无界的。

我们之前用到的读取socket文本流,就是流处理场景。但是这种方式由于吞吐量小、稳定性较差,一般也是用于测试。

java 复制代码
DataStream<String> stream = env.socketTextStream("localhost", 7777);

从数据生成器读取数据

Flink从1.11开始提供了一个内置的DataGen 连接器,主要是用于生成一些随机数,用于在没有数据源的时候,进行流任务的测试以及性能测试等。

java 复制代码
  // 如果有n个并行度, 最大值设为a
        // 将数值 均分成 n份,  a/n ,比如,最大100,并行度2,每个并行度生成50个
        // 其中一个是 0-49,另一个50-99
        env.setParallelism(2);

        /**
         * 数据生成器Source,四个参数:
         *     第一个: GeneratorFunction接口,需要实现, 重写map方法, 输入类型固定是Long
         *     第二个: long类型, 自动生成的数字序列(从0自增)的最大值(小于),达到这个值就停止了
         *     第三个: 限速策略, 比如 每秒生成几条数据
         *     第四个: 返回的类型
         */
public class DataGeneratorDemo {
    public static void main(String[] args) throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);

        DataGeneratorSource<String> dataGeneratorSource =
                new DataGeneratorSource<>(
                        new GeneratorFunction<Long, String>() {
                            @Override
                            public String map(Long value) throws Exception {
                                return "Number:"+value;
                            }
                        },
                        Long.MAX_VALUE,
                        RateLimiterStrategy.perSecond(10),
                        Types.STRING
                );


        env
                .fromSource(dataGeneratorSource, WatermarkStrategy.noWatermarks(), "datagenerator")
                .print();


        env.execute();
    }
}

从Kafka读取数据

Flink官方提供了连接工具flink-connector-kafka,直接帮我们实现了一个消费者FlinkKafkaConsumer,它就是用来读取Kafka数据的SourceFunction。

所以想要以Kafka作为数据源获取数据,我们只需要引入Kafka连接器的依赖。Flink官方提供的是一个通用的Kafka连接器,它会自动跟踪最新版本的Kafka客户端。目前最新版本只支持0.10.0版本以上的Kafka。

java 复制代码
public class SourceKafka {
    public static void main(String[] args) throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        KafkaSource<String> kafkaSource = KafkaSource.<String>builder()
            .setBootstrapServers("hadoop102:9092")
            .setTopics("topic_1")
            .setGroupId("atguigu")
            .setStartingOffsets(OffsetsInitializer.latest())
            .setValueOnlyDeserializer(new SimpleStringSchema()) 
            .build();

        DataStreamSource<String> stream = env.fromSource(kafkaSource, WatermarkStrategy.noWatermarks(), "kafka-source");

        stream.print("Kafka");

        env.execute();
    }
}
相关推荐
智海观潮4 小时前
Unity Catalog与Apache Iceberg如何重塑Data+AI时代的企业数据架构
大数据·人工智能·ai·iceberg·catalog
柏峰电子5 小时前
市政道路积水监测系统:守护城市雨天出行安全的 “智慧防线”
大数据·人工智能·安全
威斯软科的老司机6 小时前
AR远程协作系统设计:虚实融合场景下的设备维护操作指引界面
大数据·ar·可视化
java叶新东老师9 小时前
docker in docker - 在docker容器中使用宿主机的docker
linux·运维·flink
陆水A9 小时前
数仓主题域划分
大数据·数据仓库·数据库开发·etl·etl工程师
道一云黑板报9 小时前
Spark初探:揭秘速度优势与生态融合实践
大数据·分布式·spark·流式处理
字节跳动数据平台10 小时前
火山引擎多模态数据湖:AI时代的数据湖如何挖掘图片、视频、语音的“富矿”?
大数据
野生技术架构师11 小时前
系统改造:一次系统领域拆分的实战复盘
java·大数据·开发语言
时序数据说12 小时前
分布式时序数据库的特点解析
大数据·数据库·分布式·物联网·时序数据库·iotdb
WJ.Polar12 小时前
Python与Spark
大数据·分布式·spark