适用人群:Flink入门进阶、实时开发、作业调优、故障运维、初学架构理解
一、分布式缓存
1.1 分布式缓存核心简介
分布式缓存最早源自 Hadoop 设计思想:
- 将常用配置文件、小维度表文件托管在 HDFS / 资源管理器
- 集群所有计算节点统一拉取、本地缓存,避免重复拉取、重复传输
Flink 延续并落地该能力:
- 核心目的:每个 TaskManager 预加载一份相同文件/数据,Task 直接本地读取,减少跨节点IO
- 典型场景:大表 Join 小维表、字典映射、配置文件读取、固定码值关联
业务价值:
解决常规 Join shuffle 开销,小表全量缓存到节点本地,实现本地高效关联,无网络洗牌
1.2 核心使用流程(两步走)
- 环境注册:在 ExecutionEnvironment / StreamEnvironment 注册本地/HDFS文件,自定义别名
- 算子读取:在 Rich 算子的 open 生命周期,根据别名获取本地缓存文件
1.3 完整 Java 实战代码
java
public class DistributedCacheDemo {
public static void main(String[] args) throws Exception {
final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
// 第一步:注册缓存文件(支持本地路径 / HDFS路径)
env.registeredCachedFile("/xxx/distributedcache.txt", "distributedCache");
DataSource<String> data = env.fromElements("Linea", "Lineb", "Linec");
DataSet<String> result = data.map(new RichMapFunction<String, String>() {
private List<String> cacheData = new ArrayList<>();
@Override
public void open(Configuration parameters) throws Exception {
// 第二步:根据别名获取缓存文件,本地读取
File cacheFile = getRuntimeContext().getDistributedCache().getFile("distributedCache");
List<String> lines = FileUtils.readLines(cacheFile);
cacheData.addAll(lines);
}
@Override
public String map(String value) throws Exception {
// 直接使用本地缓存数据做关联/映射
return cacheData + " -> " + value;
}
});
result.printToErr();
}
}
1.4 生产强制注意事项
- 缓存文件必须只读,运行期禁止修改,否则多节点数据不一致
- 仅限小文件/小维度表,过大文件会撑爆 TaskManager 内存,引发 OOM
- 缓存文件在 Job 生命周期内常驻,重启才会重新拉取更新
二、故障恢复 & 重启策略
2.1 故障恢复基础认知
实时作业长期运行,网络抖动、脏数据、资源不足、代码异常都会导致任务崩溃;Flink 原生支持自动故障恢复,无需人工干预。
2.2 故障恢复粒度(配置核心)
配置文件:flink-conf.yaml
yaml
jobmanager.execution.failover-strategy
两种取值:
full全局重启- 单个Task报错,整个Job所有Task全部重启
- 缺点:大作业延迟高、资源开销大
region局部重启(推荐)- Flink 将作业划分为多个执行 Region
- 仅重启故障关联最小单元:故障Region + 上游依赖Region + 下游关联Region
- 最大限度缩小故障影响范围,降低延迟
2.3 三大重启策略 & 实战配置
前置默认规则
- 开启 Checkpoint 但未指定重启策略 → 默认 固定延迟重启
- 未开启 Checkpoint → 默认 无重启,报错直接挂掉作业
① 无重启策略
适用:测试作业、一次性离线任务、报错即终止排查
全局配置:
yaml
restart-strategy: none
代码配置:
java
env.setRestartStrategy(RestartStrategies.noRestart());
② 固定延迟重启(生产常用)
自定义:最大重启次数 + 每次重启间隔
示例:重试3次,间隔5秒
全局配置:
yaml
restart-strategy: fixed-delay
restart-strategy.fixed-delay.attempts: 3
restart-strategy.fixed-delay.delay: 5 s
代码配置:
java
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(
3,
Time.seconds(5)
));
③ 失败率重启(高稳核心作业)
按时间段内失败次数 判定,避免无限死循环重启
场景:5分钟内失败超3次,直接判定作业不可用
全局配置:
yaml
restart-strategy: failure-rate
restart-strategy.failure-rate.max-failures-per-interval: 3
restart-strategy.failure-rate.failure-rate-interval: 5 min
restart-strategy.failure-rate.delay: 5 s
代码配置:
java
env.setRestartStrategy(RestartStrategies.failureRateRestart(
3,
Time.minutes(5),
Time.seconds(5)
));
2.4 生产选型建议
- 测试/临时任务:无重启
- 常规实时清洗:固定延迟重启
- 核心金融/支付/订单作业:失败率重启 + 告警联动
三、并行度(作业性能调优核心)
3.1 并行度定义
一个算子被拆分为多个子任务,分布式并行执行的数量,就是并行度
👉 并行度越高,算力越强、吞吐越高,合理配置直接决定作业性能
3.2 四级并行度配置(含优先级)
优先级从高到低:
算子级别 > 执行环境级别 > 提交命令级别 > 全局配置级别
1)算子级别(推荐精细化调优)
单个算子单独指定,精准优化热点算子
java
stream.keyBy(xxx).sum(yyy).setParallelism(8);
2)执行环境级别
全局统一生效,所有算子默认继承,可被算子级别覆盖
java
env.setParallelism(5);
3)提交任务级别
命令行提交临时指定,临时压测/应急调优常用
shell
flink run -p 10 xxx.jar
4)全局配置级别(集群默认)
flink-conf.yaml 集群全局兜底
yaml
parallelism.default: 2
3.3 并行度与 Slot 核心关联(运维必懂)
- TaskManager 是工作节点,Slot 是节点内的执行槽位
- 配置
taskmanager.numberOfTaskSlots: 3→ 单个TM最大并发3个子任务 - 集群总可用并发 = TM数量 × 单TM Slot数量
- 并行度不能超过集群总Slot,否则任务排队、资源不足、调度失败
3.4 生产调优注意事项
- 高吞吐source/sink、聚合热点算子,单独拉高并行度
- 上下游并行度匹配,避免数据倾斜、局部压力过大
- 并行度不能随意拉满,受限于Slot资源,超配会导致调度阻塞
四、全篇核心总结
1. 分布式缓存
- 本质:小文件/小维表节点本地共享,优化大表Join小表
- 用法:注册缓存 → Rich算子open读取
- 红线:只读、小体量、禁止运行期修改
2. 重启策略
- 故障恢复分:全局full / 局部region
- 三大重启:无重启、固定延迟、失败率
- 核心作业优先失败率重启,配合Checkpoint保障数据一致性
3. 并行度
- 四级配置+严格优先级,精细化调优优先算子级别
- 绑定Slot资源,并行度不能脱离集群硬件配置