Flink 自定义 Source 定时触发广播流查询 MySQL

在大数据处理的世界里,Apache Flink 是一种非常流行的分布式流处理框架。在某些情况下,你可能需要定时查询 MySQL 数据库,并将结果作为广播流发送到其他操作中。本文将逐步教你如何实现这个功能。

整体流程

以下是实现“Flink 自定义 Source 定时触发广播流查询 MySQL”的流程:

步骤 描述
1 创建 MySQL 数据库及表并插入数据
2 创建 Flink 项目及必要依赖
3 编写自定义 Source 类
4 配置 Flink Job,添加自定义 Source
5 运行作业并验证结果

1. 创建 MySQL 数据库及表

首先,你需要有一个 MySQL 数据库和相应的表。你可以运行以下 SQL 来创建它:

CREATE DATABASE IF NOT EXISTS test_db;

USE test_db;

CREATE TABLE IF NOT EXISTS user_data (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    age INT
);

INSERT INTO user_data (id, name, age) VALUES (1, 'Alice', 30);
INSERT INTO user_data (id, name, age) VALUES (2, 'Bob', 25);

提示: 请确保你的 MySQL 服务正在运行,并可以通过 JDBC 连接。

2. 创建 Flink 项目及必要依赖

在你的 Maven 项目中,添加 Flink 和 MySQL Connector 的依赖项。在 pom.xml 中添加以下内容:

<dependencies>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-java</artifactId>
        <version>1.14.0</version>
    </dependency>
    <dependency>
        <groupId>mysql/mysql-connector-java</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
    </dependency>
</dependencies>

解释: 这里我们使用的 Flink 版本是 1.14.0,你可以根据所需的最新版本进行修改。

3. 编写自定义 Source 类

自定义 Source 类用于定时查询 MySQL 数据库。以下是一个示例:

import org.apache.flink.streaming.api.functions.source.SourceFunction;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.TimeUnit;

public class MySQLSource implements SourceFunction<User> {
    private volatile boolean isRunning = true;

    @Override
    public void run(SourceContext<User> ctx) throws Exception {
        String jdbcUrl = "jdbc:mysql://localhost:3306/test_db";
        String user = "your-username";    // 替换为你的 MySQL 用户名
        String password = "your-password";  // 替换为你的 MySQL 密码
        
        // 创建数据库连接
        Connection connection = DriverManager.getConnection(jdbcUrl, user, password);
        
        while (isRunning) {
            // 查询 MySQL 数据
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("SELECT id, name, age FROM user_data");
            while (resultSet.next()) {
                // 把查询到的数据发送到上下文
                ctx.collect(new User(resultSet.getInt("id"), resultSet.getString("name"), resultSet.getInt("age")));
            }
            
            // 等待 10 秒再执行下一次查询
            TimeUnit.SECONDS.sleep(10);
        }
        
        connection.close();
    }

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

// 用户类
class User {
    public int id;
    public String name;
    public int age;

    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

解释: MySQLSource 类实现了 SourceFunction 接口,每隔 10 秒从 MySQL 查询数据并发送到上下文。

4. 配置 Flink Job,添加自定义 Source

下面是一个简单的 Flink Job 来运行我们的 MySQLSource

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

public class FlinkMySQLJob {
    public static void main(String[] args) throws Exception {
        // 创建执行环境
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        
        // 添加自定义源
        env.addSource(new MySQLSource())
           .name("MySQL Source")
           .print();  // 打印输出到控制台
        
        // 运行 Flink Job
        env.execute("Flink MySQL Broadcast Job");
    }
}

解释: 该 Flink Job 将 MySQLSource 添加为数据源,并打印输出结果。

5. 运行作业并验证结果

确保 MySQL 服务正在运行。然后,你可以通过以下命令运行 Flink Job:

mvn clean package

然后使用 Flink 集群运行你的 JAR 文件。在控制台中,你应能看到每 10 秒从 MySQL 查询的数据。

pie
    title MySQL Data Processing
    "查询数据": 50
    "处理数据": 30
    "传输数据": 20

解释: 饼状图展示了 MySQL 数据处理的三个主要步骤。

结尾

通过上述步骤,你已经学会了如何在 Apache Flink 中实现自定义 Source,以定时查询 MySQL 数据库并将结果广播到流中。在实际应用中,这样的处理方式可以有效地将动态数据源与流处理相结合,以实现灵活的数据处理流程。希望这篇文章能够帮助到你,祝你在大数据开发的路上越来越顺利!