Flink的常用API

Apache Flink 提供了多层次的 API 体系,从底层的细粒度控制到高层的声明式操作,满足不同场景的需求。以下是 Flink 中最常用的几类 API 及其特点:

一、低级 API(ProcessFunction)

定位:最底层的 API,提供对数据流的细粒度控制,支持状态管理和时间操作,适合实现复杂业务逻辑。
核心特点:

  • 可访问事件时间(Event Time)、处理时间(Processing Time)和水印(Watermark)
  • 支持注册定时器(基于时间触发操作)
  • 可操作键控状态(Keyed State)和算子状态(Operator State)

常用类:

  • ProcessFunction:基础处理函数,处理单一流
  • KeyedProcessFunction:处理键控流(经 keyBy 分组后的流),支持状态和定时器
  • CoProcessFunction:处理两条输入流,可定义各自的处理逻辑

示例(KeyedProcessFunction 实现定时器): 
 
 
public class TimerProcessFunction extends KeyedProcessFunction<String, Event, String> {
    private ValueState<Long> countState;

    @Override
    public void open(Configuration parameters) {
        // 初始化状态
        countState = getRuntimeContext().getState(
            new ValueStateDescriptor<>("count", Long.class)
        );
    }

    @Override
    public void processElement(Event value, Context ctx, Collector<String> out) throws Exception {
        Long count = countState.value();
        count = (count == null) ? 1L : count + 1;
        countState.update(count);
        
        // 注册10秒后的定时器(基于事件时间)
        long timerTime = ctx.timestamp() + 10000;
        ctx.timerService().registerEventTimeTimer(timerTime);
    }

    @Override
    public void onTimer(long timestamp, OnTimerContext ctx, Collector<String> out) throws Exception {
        // 定时器触发时输出结果
        out.collect("Key: " + ctx.getCurrentKey() + ", 10秒内计数: " + countState.value());
    }
}
 

二、核心 API(DataStream & DataSet)

1. DataStream API(流处理)

定位:处理无限数据流(连续产生的数据)的核心 API,支持流处理的全生命周期操作。
核心操作:

  • 转换(Transformations):
    • map:一对一转换(如格式转换)
    • filter:过滤符合条件的元素
    • flatMap:一对多转换(如拆分字符串)
    • keyBy:按 key 分组(将流转换为 KeyedStream)
    • window:基于时间或数量的窗口划分(如滚动窗口、滑动窗口)
    • reduce/aggregate:聚合操作(如求和、计数)
  • 输出(Sinks):将结果写入外部系统(如 Kafka、HDFS、数据库)

示例(统计单词出现次数):
 
 
DataStream<String> text = env.socketTextStream("localhost", 9999);
DataStream<Tuple2<String, Integer>> counts = text
    .flatMap((String line, Collector<Tuple2<String, Integer>> out) -> {
        for (String word : line.split(" ")) {
            out.collect(new Tuple2<>(word, 1));
        }
    })
    .keyBy(tuple -> tuple.f0)  // 按单词分组
    .window(TumblingProcessingTimeWindow.of(Time.seconds(5)))  // 5秒滚动窗口
    .sum(1);  // 累加计数

counts.print();
 

2. DataSet API(批处理,逐步被流批一体替代)

定位:处理有限数据集(静态数据)的 API,基于批处理模型。
核心操作:

  • map/filter:与 DataStream 类似
  • groupBy:按字段分组
  • reduce/aggregate:聚合(如求平均值)
  • join:关联两个数据集(如内连接、外连接)

注意:Flink 1.12+ 主推 “流批一体”,建议使用 DataStream API 并通过 execution.mode 配置切换流 / 批模式,DataSet API 逐渐被弱化。

三、高层 API(Table API & SQL)

定位:声明式 API,语法类似 SQL,适合快速实现数据分析逻辑,支持流批统一处理。
核心特点:

  • 基于关系模型(表、列、视图),与 SQL 标准高度兼容
  • 可与 DataStream/DataSet 无缝转换
  • 自动优化执行计划,降低开发成本

核心概念:

  • TableEnvironment:表的执行环境,负责表的注册和查询执行
  • Table:内存中的关系型数据结构,支持链式操作
  • SQL Query:通过 SQL 语句操作表

示例(Table API 与 SQL 结合):
 
 
 
 
// 初始化环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tEnv = StreamTableEnvironment.create(env);

// 从DataStream创建表
DataStream<Order> orderStream = env.fromElements(
    new Order("user1", "productA", 100),
    new Order("user2", "productB", 200)
);
tEnv.createTemporaryView("orders", orderStream);

// Table API查询:筛选金额>150的订单
Table resultTable = tEnv.from("orders")
    .filter($("amount").isGreater(150))
    .select($("user"), $("product"));

// SQL查询:统计每个用户的总消费
Table sqlResult = tEnv.sqlQuery(
    "SELECT user, SUM(amount) as total FROM orders GROUP BY user"
);

// 转换为DataStream输出
tEnv.toDataStream(resultTable).print();
 

四、Connector API

定位:连接外部系统的接口,用于读取(Source)和写入(Sink)数据。
常用连接器:

  • 消息队列:Kafka、RabbitMQ
  • 文件系统:HDFS、本地文件
  • 数据库:MySQL(JDBC)、HBase、Elasticsearch
  • 其他:Redis、Kinesis 等

示例(从 Kafka 读取数据,写入 MySQL):
 
 
// 从Kafka读取
DataStream<String> kafkaSource = env.addSource(
    new FlinkKafkaConsumer<>("topic", new SimpleStringSchema(), properties)
);

// 转换为POJO
DataStream<User> userStream = kafkaSource.map(...);

// 写入MySQL
userStream.addSink(
    JdbcSink.sink(
        "INSERT INTO users (id, name) VALUES (?, ?)",
        (ps, user) -> {
            ps.setInt(1, user.getId());
            ps.setString(2, user.getName());
        },
        JdbcExecutionOptions.builder().withBatchSize(100).build(),
        new JdbcConnectionOptions.JdbcConnectionOptionsBuilder()
            .withUrl("jdbc:mysql://localhost:3306/db")
            .withUsername("user")
            .withPassword("pass")
            .build()
    )
);
 

总结

  • ProcessFunction:适合复杂逻辑(如状态管理、定时器),灵活性最高但开发成本高。
  • DataStream API:流处理核心,平衡灵活性和开发效率,推荐用于大多数流处理场景。
  • Table API & SQL:适合数据分析和简单业务,开发速度快,支持流批统一。
  • Connector API:负责与外部系统交互,是数据输入输出的基础。

根据业务复杂度选择合适的 API 可大幅提升开发效率。
posted @ 2025-07-30 15:32  飘来荡去evo  阅读(19)  评论(0)    收藏  举报