Flink 读文本文件TextLineInputFormat + FileSource(批/流一体)+ 目录持续监控

Java 工程要使用文本文件 Source,需要引入 Flink 的文件连接器依赖:

xml 复制代码
<dependency>
  <groupId>org.apache.flink</groupId>
  <artifactId>flink-connector-files</artifactId>
  <version>2.2.0</version>
</dependency>

PyFlink 用户通常可以直接在作业里使用(但如果你集群环境缺少对应 jar,也需要通过 Python dependency management 方式携带)。

2. 为什么用 FileSource + TextLineInputFormat

TextLineInputFormat 解决两件事:

  • 按行切分:每行一个 record
  • 字符集解码:使用 InputStreamReader 支持多种 charset(UTF-8、GBK 等)

而 FileSource 解决两件事:

  • bounded:一次性读完目录/文件(批处理)
  • continuous:持续监控目录,新文件出现就继续读(流式文件输入)

也就是说,你可以用同一套 Source,覆盖两类场景:

  • 离线回放历史日志
  • 实时消费不断落盘的新日志文件

3. 批处理模式(Bounded):读完就结束

目标:把一个文本文件(或目录里所有文本文件)的每一行读成 String,生成 DataStream<String>。

因为文本行一般不自带事件时间,所以不需要 watermark:

java 复制代码
final FileSource<String> source =
    FileSource.forRecordStreamFormat(new TextLineInputFormat(), /* Flink Path */)
        .build();

final DataStream<String> stream =
    env.fromSource(source, WatermarkStrategy.noWatermarks(), "file-source");

适用场景:

  • 跑一次把历史文件处理完(ETL、离线修数、回放)

4. 流处理模式(Continuous):持续监控目录,新文件不断加入

目标:目录持续落文件(例如按小时切日志),Flink 任务一直跑,新文件出现就读,DataStream 会"无限增长"。

通过 monitorContinuously(Duration) 开启目录监控,比如每 1 秒扫描一次:

java 复制代码
final FileSource<String> source =
    FileSource.forRecordStreamFormat(new TextLineInputFormat(), /* Flink Path */)
        .monitorContinuously(Duration.ofSeconds(1L))
        .build();

final DataStream<String> stream =
    env.fromSource(source, WatermarkStrategy.noWatermarks(), "file-source");

适用场景:

  • 应用日志落盘目录(log rolling)
  • 上游系统定时导出文件到目录
  • 简易的"文件流"采集管道(没有 Kafka 也能跑)

5. 生产建议:文本文件"流式监控"最容易踩的坑

5.1 只监控"新文件",不等于"追尾追加写"

大多数文件监控模式更适合"文件落地后不再变"(写完再 rename/commit)。如果你希望读一个不断追加的单文件(类似 tail -f),要非常谨慎:有些文件系统/写入方式会导致重复读或读到半行。

推荐的落地方式:

  • 上游写临时文件(.tmp),写完后 rename 成正式文件名
  • Flink 只消费正式文件名规则(例如不匹配 .tmp)

5.2 监控频率不是越小越好

monitorContinuously(1s) 会频繁扫描目录:

  • 目录文件数大时会产生明显压力
  • 对对象存储(S3/OSS)类系统,list 成本更高

经验:

  • 本地/小目录:1s~5s 可以
  • 大目录/对象存储:10s~60s 起步,并控制目录分区层级(按日期/小时分层)

5.3 字符集与脏数据治理要提前考虑

TextLineInputFormat 基于 InputStreamReader 解码,编码不一致会出现乱码或异常。建议:

  • 统一上游编码(最好 UTF-8)
  • 对异常行做侧输出(side output)或打到 DLQ(如果你后续接 Kafka)

5.4 文本行没有事件时间时,watermark 怎么办

如果你的行里其实包含时间戳(比如日志行开头有 2026-01-15 12:34:56),你可以在 map/flatMap 里解析事件时间,再配置 watermark 策略;否则默认 noWatermarks 没问题。

6. 一句话总结

  • TextLineInputFormat :把文件按"行"读成 String,并处理字符集解码
  • FileSource:同一套代码支持批(bounded)与流(continuous 目录监控)
  • 批:.build() 直接读完结束
  • 流:.monitorContinuously(Duration) 目录新文件持续进入
相关推荐
TLA技术17 分钟前
LogMiner vs 裸日志解析(六):想提速,只能“堆实例”,结果把源库拖垮
数据库·oracle·flink·dba·迁移学习
智商网输送线配件24 分钟前
流水线全套配件直供化落地的三个实操切入维度
大数据·运维·自动化·智商网·流水线设备配件
字节跳动数据平台29 分钟前
几小时的视频找 3 秒镜头,你还在一格格拖进度条?
大数据
IT毕设梦工厂37 分钟前
计算机毕业设计选题推荐:基于大数据的城市噪音数据分析与可视化|毕业设计选题|计算机毕设|选题推荐|毕设指导|项目定制|源码|高质量项目
大数据·信息可视化·数据分析·spark·毕业设计·课程设计·数据可视化
IT古董1 小时前
《FDE前沿部署工程师实战教程》23 - Enterprise AI Event Bus:事件驱动、消息队列与AI工作流自动触发
大数据·数据库·人工智能
阿尔法工场研究院1 小时前
宇树们不想重蹈新造车的覆辙
大数据·人工智能·科技·机器人
中电金信1 小时前
中电金信参编的团体标准《商业银行应用程序接口治理能力要求》正式发布
大数据·运维·人工智能
SelectDB2 小时前
1TB/天 × 30 天日志成本怎么估:核对命令、降冷配置与踩坑记录
大数据·数据库·数据分析
SelectDB2 小时前
日志选型别只比 Loki 和 ELK:三条路径、一份可复制的落地清单
大数据·数据库·数据分析
SelectDB2 小时前
ES 写入拒绝与磁盘暴涨:排查命令、参数调整与改用 Doris 的落地步骤
大数据·数据库·数据分析