4、如何在flink任务中读取外部数据源(DataStream API)

1、Flink读取外部数据源的方式

Flink是一个流批一体的分布式计算框架,它不会存储数据,编写Flink计算任务的第一步就是通过连接器去读取外部数据

Flink提供了多种`预定义 data sources` 来读取外部数据,如 文件、目录、Socket、集合、Kafka等外部数据源,另外也是要通过自定义数据源来读取外部数据


2、数据源的类型 

Flink 中读取的数据源,根据知否支持切片,分为 非并行数据源 和 并行数据源 两大类

           并行数据源      :  可以将数据源拆分成多个 子任务,并行执行( 并行度允许大于1)

        非并行数据源     :    不可以将数据源拆分,只能有单独的任务处理数据 (并行度必须1)    

我们可以通过 StreamExecutionEnvironment.addSource(SourceFunction) 将一个 source对象 关 联到编写的 flink应用程序中
        Flink API中 自带了许多 SourceFunction的实现类

        我们也可以 通过实现 SourceFunction接口 来编写 自定义的非并行的source对象
                           通过实现 ParallelSourceFunction 接口
                                  继承 RichParallelSourceFunction 类 来编写 自定义的并行source对象


3、Flink 中的数据类型(TypeInformation)

Flink 会将外部的数据加载到 DataStreamSource 对象中,加载过程中会将外部的数据的类型转换为 Flink 定义的数据类型

为了方便 数据序列化和反序列化,Flink定义了自己的数据类型系统

扫描二维码关注公众号,回复: 16174927 查看本文章


4、从集合中读取数据

Flink任务怎样读取集合中的数据


5、从文件中读取数据

Flink任务怎样读取文件中的数据


6、从Socket中读取数据

语法说明:

语法:
    def socketTextStream(hostname: String, port: Int, delimiter: Char = '\n', maxRetry: Long = 0):
        DataStream[String] =
    asScalaStream(javaEnv.socketTextStream(hostname, port))
功能:
    执行监控,socket中的文本流,按行读取数据(默认分隔符为 \n)
参数:
    hostname : socket服务ip
    prot     : socket服务端口号
    Char     : 行分隔符
    maxRetry : 当 socket服务 停止时,flink程序 重试连接时间(单位为秒)
               =0 时,表示 连接不到 socket服务后,立刻停止 flink程序
               =-1 时,表示 永远保持重试连接
tips:
    scala API 只提供了一种 socketTextStream方法的实现
    如果想使用其他参数,需要使用java api

代码示例:

package com.baidu.datastream.source;

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

// --------------------------------------------------------------------------------------------
//  TODO 从Socket中读取数据
// --------------------------------------------------------------------------------------------

/*
 *  TODO socketTextStream(hostname: String, port: Int, delimiter: String, maxRetry: Long)
 *  功能说明:
 *       包含从套接字接收到的字符串的数据流
 *  参数说明:
 *       @hostname  : 指定ip
 *       @port      : 指定端口号
 *       @delimiter : 指定元素分隔符(默认为\n)
 *       @maxRetry  :  指定连接失败时,重试连接的时间间隔(以秒为单位)
 *                     默认为为0,表示连接失败时,程序立即终止
 *                     负值时,表示一直重试连接
 * */

public class ReadSocket {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2.将socket作为数据源(开启socket端口: nc -lk 9999)
        env.socketTextStream("localhost", 9999).print();

        // 3.触发程序执行
        env.execute();
    }
}

7、从Kafka中读取数据

传送门:Flink任务怎样读取Kafka中的数据


6. 从DataGen中读取数据

传送门:从DataGen中读取数据


7. 自定义数据源

7.1 自定义非并行数据源

 代码示例:

/*
* TODO 自定义非并行数据源
*    实现步骤:
*        1.实现 SourceFunction接口
*        2.实现 run方法
*           调用 collect方法 发送数据
*        3.实现 cancel方法
*   注意事项:
*        1.接口的泛型为 数据源的数据类型
* */
class CustomNonParallelSource extends SourceFunction[String] {
  // 标志位,用来控制循环的退出
  var isRunning = true

  override def run(ctx: SourceFunction.SourceContext[String]): Unit = {
    val list = List("刘备1", "关羽2", "张飞3", "赵云4", "马超5")

    while (isRunning) {
      // 调用 collect 方法向下游发送数据
      list.foreach(
        e => {
          ctx.collect(e)
          Thread.sleep(1000)
        }
      )

    }

  }

  // 通过将 isRunning 设置为false,来终止消息的发送
  override def cancel(): Unit = isRunning = false
}

  /*
  * TODO 从 自定义数据源中 读取数据
  *
  * */
  test("从 自定义非并行数据源中 读取数据") {

    // 1. 获取流执行环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment

    // 2. 将 自定义数据源 作为数据源
    val ds: DataStream[String] = env.addSource(new CustomNonParallelSource).setParallelism(1)

    // 3. 打印DataStream
    ds.print().setParallelism(1)

    // 4. 出发程序执行
    env.execute()
  }

执行结果:

7.2 自定义并行数据源

代码示例:

/*
* TODO 自定义并行数据源
*    实现步骤:
*        1.实现 ParallelSourceFunction接口 或者 继承RichParallelSourceFunction
*        2.实现 run方法
*           调用 collect方法 发送数据
*        3.实现 cancel方法
*   注意事项:
*        1.接口的泛型为 数据源的数据类型
* */
class CustomParallelSource extends RichParallelSourceFunction[String] {
  // 标志位,用来控制循环的退出
  var isRunning = true

  override def run(ctx: SourceFunction.SourceContext[String]): Unit = {
    val list = List("刘备1", "关羽2", "张飞3", "赵云4", "马超5")

    while (isRunning) {
      // 调用 collect 方法向下游发送数据
      // 调用 collect 方法向下游发送数据
      list.foreach(
        e => {
          ctx.collect(e)
          Thread.sleep(1000)
        }
      )

    }
  }

  // 通过将 isRunning 设置为false,来终止消息的发送
  override def cancel(): Unit = isRunning = false
}


  test("从 自定义并行数据源中 读取数据") {

    // 1. 获取流执行环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment

    // 2. 将 自定义数据源 作为数据源
    val ds: DataStream[String] = env.addSource(new CustomParallelSource).setParallelism(4)

    // 3. 打印DataStream
    ds.print().setParallelism(1)

    // 4. 出发程序执行
    env.execute()
  }

执行结果:

7.3 使用自定义数据源读取MySQL

传送门:使用自定义源算子读取MySQL

猜你喜欢

转载自blog.csdn.net/weixin_42845827/article/details/129845245