Flink Stream API 源码走读 - socketTextStream

概述

本文深入分析了 Flink 中 socketTextStream() 方法的源码实现,从用户API调用到最终返回 DataStream 的完整流程。

核心知识点

1. socketTextStream 方法重载链

java 复制代码
// 用户调用入口
env.socketTextStream("hostname", 9999)
    ↓ 补充分隔符参数
env.socketTextStream("hostname", 9999, "\n") 
    ↓ 补充重试次数参数
env.socketTextStream("hostname", 9999, "\n", 0)
    ↓ 创建 SocketTextStreamFunction
addSource(new SocketTextStreamFunction(hostname, port, delimiter, maxRetry), "Socket Stream")

重载过程分析:

  • 第一层:补充分隔符参数(默认 "\n")
  • 第二层:补充重试次数参数(默认 0)
  • 最终:创建 SocketTextStreamFunction 并调用 addSource

2. SourceFunction 的重要说明

java 复制代码
@Deprecated
public class SocketTextStreamFunction implements SourceFunction<String>

⚠️ 重要提醒:

  • SourceFunction 已被标记为 @Deprecated(过时)
  • 官方建议使用新的 Source API
  • 基于 SourceFunction 的架构是老架构
  • 新架构基于 org.apache.flink.api.connector.source.Source

3. addSource 方法的重载链

addSource(function, sourceName) addSource(function, sourceName, null) addSource(function, sourceName, typeInfo, CONTINUOUS_UNBOUNDED) 核心处理逻辑

参数补充过程:

  1. addSource(function, "Socket Stream")
  2. addSource(function, "Socket Stream", null) - 补充 TypeInformation 为 null
  3. addSource(function, "Socket Stream", null, CONTINUOUS_UNBOUNDED) - 补充有界性

4. 核心处理逻辑分析

java 复制代码
private <OUT> DataStreamSource<OUT> addSource(
        final SourceFunction<OUT> function,
        final String sourceName,
        @Nullable final TypeInformation<OUT> typeInfo,
        final Boundedness boundedness) {
    
    // 1. 非空检查
    checkNotNull(function);
    checkNotNull(sourceName);
    checkNotNull(boundedness);
    
    // 2. 抽取类型信息
    TypeInformation<OUT> resolvedTypeInfo = 
        getTypeInfo(function, sourceName, SourceFunction.class, typeInfo);
    
    // 3. 判断是否并行
    boolean isParallel = function instanceof ParallelSourceFunction;
    
    // 4. 序列化检查
    clean(function);
    
    // 5. Function → Operator
    final StreamSource<OUT, ?> sourceOperator = new StreamSource<>(function);
    
    // 6. 返回 DataStreamSource
    return new DataStreamSource<>(
        this, resolvedTypeInfo, sourceOperator, isParallel, sourceName, boundedness);
}

5. 四个核心概念的转换

Function
用户逻辑 Operator
算子封装 Transformation
转换操作 DataStream
用户API

概念解释:

  1. Function: 用户的业务逻辑封装

    • SocketTextStreamFunction - Socket连接和数据读取逻辑
    • 继承自 SourceFunction<String>
  2. Operator: 算子的抽象

    • StreamSource<OUT, ?> - 将Function包装成算子
    • 继承自 AbstractUdfStreamOperator
  3. Transformation: 转换操作的封装

    • LegacySourceTransformation - 包装Operator和相关元信息
    • 包含类型信息、并行度、有界性等
  4. DataStream: 面向用户的流式API

    • DataStreamSource - 继承自 DataStream
    • 支持链式调用(map、filter、keyBy等)

6. 重要参数说明

TypeInformation(类型信息)
java 复制代码
// 为什么需要 TypeInformation?
// Java 泛型在编译后会被类型擦除,Flink需要显式的类型信息来:
// 1. 创建序列化器/反序列化器
// 2. 根据不同类型产生不同的序列化机制
TypeInformation<OUT> resolvedTypeInfo = getTypeInfo(function, sourceName, SourceFunction.class, typeInfo);
Boundedness(有界性)
java 复制代码
// CONTINUOUS_UNBOUNDED 表示无界流
// 在翻译成物理执行计划时会用到这个信息
// 有界流和无界流会生成不同的执行计划
Boundedness.CONTINUOUS_UNBOUNDED
并行性检查
java 复制代码
// 检查是否为并行源函数
boolean isParallel = function instanceof ParallelSourceFunction;
// SocketTextStreamFunction 不是 ParallelSourceFunction,所以 isParallel = false

7. DataStreamSource 的构造

java 复制代码
public DataStreamSource(
    StreamExecutionEnvironment environment,
    TypeInformation<T> outTypeInfo, 
    StreamSource<T, ?> operator,
    boolean isParallel,
    String sourceName,
    Boundedness boundedness) {
    
    // 调用父类构造,创建 LegacySourceTransformation
    super(environment, new LegacySourceTransformation<>(
        sourceName, operator, outTypeInfo, 
        environment.getParallelism(), boundedness));
    
    // 如果不是并行的,设置并行度为1
    if (!isParallel) {
        setParallelism(1);
    }
}

8. 继承关系分析

DataStream<T> SingleOutputStreamOperator<T> DataStreamSource<T> 包含所有流式API
map, filter, keyBy, window等

重要理解:

  • DataStreamSource 本质上就是一个 DataStream
  • 所有的链式调用API都定义在 DataStream
  • SingleOutputStreamOperator 这个命名容易误导,它实际上是个 DataStream

9. DataStream 的内部结构

java 复制代码
public class DataStream<T> {
    // 两个最重要的成员
    protected final StreamExecutionEnvironment environment;  // 执行环境
    protected final Transformation<T> transformation;        // 转换操作
}

关系链:

  • DataStream 包含 Transformation
  • Transformation 包含 Operator
  • Operator 包含 Function

10. 链式调用的实现

java 复制代码
DataStream<String> stream = env.socketTextStream("localhost", 9999)
    .map(...)           // 返回 SingleOutputStreamOperator (实际是DataStream)
    .filter(...)        // 返回 SingleOutputStreamOperator  
    .keyBy(...)         // 返回 KeyedStream
    .window(...)        // 返回 WindowedStream
    .sum(...)           // 返回 SingleOutputStreamOperator
    .print();          // 返回 DataStreamSink

流程:
DataStreamSource → 各种变换 → DataStreamSink

总结

核心流程回顾

  1. 用户调用 env.socketTextStream(hostname, port)
  2. 参数补全 通过重载方法逐步补充参数
  3. Function创建 创建 SocketTextStreamFunction
  4. addSource调用 进入核心处理逻辑
  5. 类型推断 抽取输出数据的类型信息
  6. 并行性检查 判断是否为并行源函数
  7. Function→Operator 封装成 StreamSource
  8. Operator→Transformation 创建 LegacySourceTransformation
  9. 返回DataStream 创建 DataStreamSource

设计模式体现

  • 装饰器模式: Function → Operator → Transformation → DataStream
  • 建造者模式: 通过重载方法逐步构建完整对象
  • 模板方法模式: addSource的处理流程

关键技术点

  • 类型擦除处理: 通过 TypeInformation 解决Java泛型擦除问题
  • 序列化机制: 根据类型信息创建对应的序列化器
  • 并行度控制: 非并行源强制设置并行度为1
  • 有界性标识: 为后续执行计划生成提供信息

下节预告

Flink Stream API 源码走读 map和 flatmap


注意 : 基于 Flink 1.18 版本,SourceFunction 已被标记为过时,实际项目中建议使用新的 Source API。

相关推荐
cd_9492172113 分钟前
九昆仑低碳科技:所罗门群岛全国森林碳汇项目开发合作白皮书
大数据·人工智能·科技
Acrelhuang22 分钟前
工商业用电成本高?安科瑞液冷储能一体机一站式解供能难题-安科瑞黄安南
大数据·开发语言·人工智能·物联网·安全
小王毕业啦22 分钟前
2010-2024年 非常规高技能劳动力(+文献)
大数据·人工智能·数据挖掘·数据分析·数据统计·社科数据·经管数据
言無咎34 分钟前
从规则引擎到任务规划:AI Agent 重构跨境财税复杂账务处理体系
大数据·人工智能·python·重构
私域合规研究1 小时前
【AI应用】AI与大数据融合:中国品牌出海获客的下一代核心引擎
大数据·海外获客
TDengine (老段)2 小时前
金融风控系统中的实时数据库技术实践
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
MMME~2 小时前
Ansible模块速查指南:高效定位与实战技巧
大数据·运维·数据库
计算机毕业编程指导师2 小时前
大数据可视化毕设:Hadoop+Spark交通分析系统从零到上线 毕业设计 选题推荐 毕设选题 数据分析 机器学习 数据挖掘
大数据·hadoop·python·计算机·spark·毕业设计·城市交通
计算机毕业编程指导师2 小时前
【计算机毕设选题】基于Spark的车辆排放分析:2026年热门大数据项目 毕业设计 选题推荐 毕设选题 数据分析 机器学习 数据挖掘
大数据·hadoop·python·计算机·spark·毕业设计·车辆排放
珠海西格3 小时前
远动通信装置为何是电网安全运行的“神经中枢”?
大数据·服务器·网络·数据库·分布式·安全·区块链