flink学习与如何在springboot项目中使用flink

flink:Apache Flink 一种流式计算框架,高吞吐低延迟的数据处理方案

原理:把所有数据视为流,由事件驱动,每次事件到达触发计算

与传统批处理的区别:Hadoop/Spark batch 固定数据集处理任务,任务所有逻辑执行完成一次提交

复制代码
  Hadoop优点:分布式文件存储,可动态组装数据库集群,实现高可靠、可容错、可扩展

  可以把多台普通服务器集合成大数据集群,数据在每个节点上分别计算,最后汇总成完整数据

   组成:

   HDFS分布式文件系统-将数据拆分分别存在集群的不同节点上、通过副本机制保证数据安全

   上传 300MB 文件 → 分成 3 个 block → 分布到 3 台机器上,每个 block 3 副本

   包含两个关键角色:NameNode-元数据管理节点-记录数据所在的节点位置

                                     DataNode-存储数据的节点

   MapReduce分布式计算模型-在不同节点上进行不同数据的计算,最后归约汇总输出完整结果

   两个阶段:Map-映射-分布式处理数据分片

                     Reduce-归约-汇总map输出

   Yarn资源调度管理-集群资源调度管理、节点资源调度管理、单个应用的生命周期管理

   使用场景:非实时性的离线数据任务(比如一些T+1更新的分析数据、离线日志分析)

主要使用场景:高实时性业务(监控告警、风控、推荐、广告投放、实时数仓)

在项目中集成flink-示例:动态统计5min内的点击数(强实时性统计,差一秒可能数据变更都非常大)

首先在pom中添加依赖 - 举例在kafka信息流中计算

java 复制代码
<dependencies>
    <!-- Flink 核心依赖 -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java</artifactId>
        <version>1.18.1</version>
    </dependency>

    <!-- 如果需要 Kafka Source/Sink -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-connector-kafka</artifactId>
        <version>1.18.1</version>
    </dependency>

    <!-- Spring Boot 基础依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>在这里插入代码片

注意:Flink 版本建议与生产集群一致,避免依赖冲突。

然后新建一个 Flink 任务类,例如 FlinkStreamJob.java:

java 复制代码
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.connector.kafka.source.KafkaSource;
import org.apache.flink.connector.kafka.sink.KafkaSink;

import org.springframework.stereotype.Component;

@Component
public class FlinkStreamJob {

    public void start() throws Exception {
        // 1. 创建执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2. 配置 Kafka Source - 从kafka读取数据流
        KafkaSource<String> source = KafkaSource.<String>builder()
                .setBootstrapServers("localhost:9092")
                .setTopics("input-topic")
                .setGroupId("flink-group")
                .setValueOnlyDeserializer(new SimpleStringSchema())
                .build();

        DataStream<String> stream = env
                .fromSource(source, WatermarkStrategy.noWatermarks(), "Kafka Source");

        // 3. 数据转换逻辑
        DataStream<String> result = stream
                .map(value -> "Processed: " + value);

        // 4. 输出到 Kafka Sink 将结果流输出到kafka去
        KafkaSink<String> sink = KafkaSink.<String>builder()
                .setBootstrapServers("localhost:9092")
                .setRecordSerializer(KafkaRecordSerializationSchema.builder()
                        .setTopic("output-topic")
                        .setValueSerializationSchema(new SimpleStringSchema())
                        .build())
                .build();

        result.sinkTo(sink);

        // 5. 启动作业
        env.execute("SpringBoot-Flink-Job");
    }
}

在springboot中集成这个任务

例如在 Application.java配置,启动SpringBoot应用时,Flink作业会自动运行

java 复制代码
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.beans.factory.annotation.Autowired;

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private FlinkStreamJob flinkJob;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        flinkJob.start();
    }
}

控制台输出类似:

Starting job SpringBoot-Flink-Job (JobID=xxxxxx)

Connected to Kafka source: input-topic

Producing to Kafka sink: output-topic

此时SpringBoot应用实际上已经成为一个可独立运行的 Flink 流任务服务

**

如果我创建了一个stream流式任务job,中间服务重启了,job会中断吗?

**

结论:如果是在springboot内集成的flink流,会中断,job会中断,内存状态丢失,重启后会重新从头计算

原因:此时flink是由springboot的jvm管理的,服务重启jvm会清空,对应的信息和状态就不存在了,就会中断计算逻辑,等待重启后重新开始

方案 1:启用 Checkpoint + Savepoint(推荐)

在代码中启用 Checkpoint,可以让 Flink 自动保存状态。

当任务重启时,会从最近的 Checkpoint 恢复,不中断计算结果的连续性。

示例:

java 复制代码
env.enableCheckpointing(60000); // 每 60 秒做一次 checkpoint

env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(30000);
env.getCheckpointConfig().setCheckpointTimeout(10000);
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);

// 可选:设置状态后端(例如 RocksDB 或 FileSystem)
env.setStateBackend(new HashMapStateBackend());
env.getCheckpointConfig().setCheckpointStorage("file:///tmp/flink-checkpoints");

效果:

即使服务重启,任务会在下次启动时自动从上次的 checkpoint 恢复

不会重复消费 Kafka

数据唯一不会重复处理

方案 2:把 Flink Job 运行在 独立集群中

即把 Flink Job 从 Spring Boot 进程中"独立"出来,

用 Spring Boot 作为 提交 / 监控 / 管理端。

运行方式:

flink run -c com.example.flinkdemo.job.FlinkKafkaJob

target/springboot-flink-demo-1.0.0.jar

优点:

Job 运行在 Flink 集群中;

不受 Spring Boot 重启影响;

可以自动从 checkpoint 恢复;

高可用 (HA) 可配置多个 JobManager。

Spring Boot 这时只做:

任务发布;

状态监控;

参数配置

相关推荐
d111111111d11 分钟前
了解Modbus
网络·笔记·stm32·单片机·嵌入式硬件·学习
charlie11451419124 分钟前
通用GUI编程技术——图形渲染实战(三十八)——顶点缓冲与输入布局:GPU的第一个三角形
开发语言·c++·学习·图形渲染·win32
我想我不够好。1 小时前
监控学习 4.29 1.5hour
学习
晓晓hh1 小时前
JavaWeb学习——JUnit和日志
学习·junit·单元测试
小超同学你好1 小时前
Transformer 30. MoCo:用「动量编码器 + 队列字典」把对比学习做成可扩展的“字典查找”
深度学习·学习·transformer
光影少年1 小时前
前端SSR和ssg区别
前端·vue.js·人工智能·学习·react.js
筱_智1 小时前
Docker学习-超详细-通俗易懂(从入门到精通)
学习·docker·容器
也许明天y1 小时前
LangChain4j + Spring Boot 多智能体协调架构原理深度解析
spring boot·后端·agent
噜噜噜阿鲁~2 小时前
python学习笔记 | 8.2、函数式编程-返回函数
笔记·python·学习
小郑加油2 小时前
python学习Day8-9天:函数(def)的基础运用
python·学习