Flink Join 核心解析:类型、原理、实操

        Flink 中的 Join 是用于关联两个或多个数据流 / 数据集的核心操作,分为批处理(Batch)Join流处理(Stream)Join两大类。批处理 Join 基于静态数据集,逻辑与传统数据库 Join 类似;而流处理 Join 基于无限数据流,需结合窗口状态实现,是 Flink 流处理的重点和难点。以下是详细解析。

一、Flink Join 的核心分类

        Flink Join 主要分为两大维度:

维度 类型 适用场景 核心原理
数据形态 批处理 Join(DataSet API) 静态数据集关联(如历史数据) 基于内存 / 磁盘的哈希 Join、排序合并 Join
数据形态 流处理 Join(DataStream API) 实时数据流关联(如实时订单 + 用户) 基于窗口 / 状态存储,在窗口内关联数据
Join 逻辑 Inner Join(内连接) 只保留两边都匹配的数据 仅输出匹配的记录
Join 逻辑 Left Outer Join(左外连接) 保留左表所有数据,右表匹配的数据 左表无匹配时,右表字段为 null
Join 逻辑 Right Outer Join(右外连接) 保留右表所有数据,左表匹配的数据 右表无匹配时,左表字段为 null
Join 逻辑 Full Outer Join(全外连接) 保留两边所有数据 无匹配时对应字段为 null

注意:Flink 1.12+ 主推 Table API/SQL 实现 Join,其语法更简洁、功能更完善(支持更多 Join 类型),而 DataStream API 需手动实现窗口 / 状态管理。

二、批处理 Join(DataSet API)

        批处理 Join 针对静态数据集,语法和逻辑与传统数据库 Join 一致,Flink 会根据数据量自动选择哈希 Join排序合并 Join优化性能。

1. 核心原理

  • 哈希 Join:将小数据集加载到内存中构建哈希表,遍历大数据集进行匹配(适用于小表 + 大表);
  • 排序合并 Join:将两个数据集排序后,遍历并合并匹配的数据(适用于大表 + 大表)。

2. 代码实操(Java)

import org.apache.flink.api.common.functions.JoinFunction;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.DataSet;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.tuple.Tuple3;

public class BatchJoinExample {
    public static void main(String[] args) throws Exception {
        // 1. 创建批处理执行环境
        ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

        // 2. 定义左表:用户数据(用户ID,用户名)
        DataSet<Tuple2<Integer, String>> userDataSet = env.fromElements(
                Tuple2.of(1, "Alice"),
                Tuple2.of(2, "Bob"),
                Tuple2.of(3, "Charlie")
        );

        // 3. 定义右表:订单数据(订单ID,用户ID,金额)
        DataSet<Tuple3<Integer, Integer, Double>> orderDataSet = env.fromElements(
                Tuple3.of(101, 1, 99.9),
                Tuple3.of(102, 2, 199.9),
                Tuple3.of(103, 4, 299.9) // 用户ID=4,左表无匹配
        );

        // 4. Inner Join:按用户ID关联,保留两边匹配的数据
        DataSet<Tuple3<Integer, String, Double>> innerJoinResult = userDataSet
                .join(orderDataSet)
                .where(0) // 左表的关联字段:用户ID(Tuple2的第0位)
                .equalTo(1) // 右表的关联字段:用户ID(Tuple3的第1位)
                .with(new JoinFunction<Tuple2<Integer, String>, Tuple3<Integer, Integer, Double>, Tuple3<Integer, String, Double>>() {
                  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路边草随风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值