Flink自定义Sink将数据存到MySQL

如有更佳的保存MySQL方法 欢迎私信或留言分享 相互学习~

依赖

<dependencies>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-scala_2.11</artifactId>
            <version>1.10.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-scala_2.11</artifactId>
            <version>1.10.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka-0.11_2.11</artifactId>
            <version>1.10.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.bahir</groupId>
            <artifactId>flink-connector-redis_2.11</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-statebackend-rocksdb_2.12</artifactId>
            <version>1.10.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-planner_2.11</artifactId>
            <version>1.10.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-planner-blink_2.11</artifactId>
            <version>1.10.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-api-scala-bridge_2.11</artifactId>
            <version>1.10.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-csv</artifactId>
            <version>1.10.1</version>
        </dependency>

    </dependencies>
    <build>
        <plugins> <!-- 该插件用于将 Scala 代码编译成 class 文件 -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.4.6</version>
                <executions>
                    <execution> <!-- 声明绑定到 maven 的 compile 阶段 -->
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

代码

import org.apache.flink.streaming.api.functions.sink.RichSinkFunction

// 自定义Sink
dataStream.addSink( new JDBCSink() )

// 继承RichSinkFunction
class JDBCSink extends RichSinkFunction[输入的数据类型]{

  // 定义sql连接、插入预编译器、更新预编译器
  var conn: Connection = _
  var insertStatement: PreparedStatement = _
  var updateStatement: PreparedStatement = _

  // 重写open函数 在此函数初始化,创建连接和预编译语句
  override def open(parameters: Configuration): Unit = {
	// 初始化连接
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库", "账号", "密码")
    // 初始化插入预编译器
    insertStatement = conn.prepareStatement("INSERT INTO 表名 VALUES (?, ?, ?(占位符));")
    // 初始化更新与编译器
    updateStatement = conn.prepareStatement("UPDATE 表名 SET 字段 = ? WHERE 字段 = ?;")
  }
  
  // 重写close函数 关闭与编译器和sql连接
  override def close(): Unit = {
    insertStatement.close()
    updateStatement.close()
    conn.close()
  }
  // 重写invoke函数 
  override def invoke(value: 输入的数据类型, context: SinkFunction.Context[_]): Unit = {
    // 先执行更新操作 给跟更新预编译器的占位符赋值
    updateStatement.setInt(1, value.count.toInt)
    updateStatement.setString(2, value.url)
    updateStatement.setDouble(3, value.windowEnd)
    // 执行更新
    updateStatement.execute()
    // 判断如果更新的行数为0 则执行插入
    if(updateStatement.getUpdateCount == 0){
      // 给插入预编译器的占位符赋值
      insertStatement.setDouble(1, value.windowEnd)
      insertStatement.setString(2, value.url)
      insertStatement.setInt(3, value.count.toInt)
      // 执行插入
      insertStatement.execute()
    }
  }
}
FlinkSQL 是 Flink 中提供的一种 SQL 执行方式,它可以让用户使用 SQL 语句进行流式数据处理。在 FlinkSQL 中,自定义 Sink 可以用于将处理结果输出到外部存储介质,如 MySQL、ES 等。 首先,在自定义 Sink 之前,需要先定义一个类,继承 Flink 的 RichSinkFunction 接口。该接口包含 open、invoke 和 close 三个方法,分别用于 Sink 的初始化、数据输出和资源释放。自定义 Sink 类应该重写 invoke 方法,用于输出数据。 接下来,在 FlinkSQL 中,使用 CREATE TABLE 定义表时,可以指定表的输出方式为自定义 Sink。例如,定义一个输出流,并将结果输出到 MySQL 中,可以按以下方式定义表: ``` CREATE TABLE result ( word VARCHAR, count BIGINT ) WITH ( 'connector' = 'jdbc', 'url' = 'jdbc:mysql://localhost:3306/test', 'table-name' = 'result', 'username' = 'root', 'password' = 'root', 'sink.buffer-flush.max-rows' = '500', 'sink.buffer-flush.interval' = '2s', 'sink.max-retries' = '5' ) ``` 上述代码中,定义了一个名为 result 的表,其中 word 和 count 字段分别表示统计结果中的单词和出现次数。通过 WITH 关键字,在该表中定义了一个自定义 Sink,并指定了输出的目标地址为本地的 MySQL 数据库,配置了一些参数,如输出缓存刷写的条数、刷写的时间间隔以及重试次数等。 以上是 FlinkSQL 自定义 Sink 的简单介绍,通过自定义 Sink,在 FlinkSQL 中可以很方便地将处理结果输出到外部存储介质。同时,需要根据需求对自定义 Sink 进行优化,尽可能提高数据输出的效率和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值