Flink 状态设计理念-附源码
1. 流处理的本质需求:必须"记忆"
1.1 无状态计算的严重局限
问题: 如果没有状态,流处理系统只能做"即时映射":
// ❌ 无状态:只能处理单条数据
dataStream.map(event -> event.getValue() * 2)
但真实业务需要"记忆力":
场景1:聚合统计(来自源码示例)
// ❌ 无状态:只能处理单条数据
dataStream.map(event -> event.getValue() * 2)
必须记住: 之前累加的总和
- 计算过去1小时的订单总额
- 统计每个用户的点击次数
- 计算移动平均值
场景2:模式检测(状态机示例)
从 Flink 官方示例 StateMachineExample 中看到:
private static class SummingReducer implements ReduceFunction<Tuple2<Long, Long>> {
@Override
public Tuple2<Long, Long> reduce(Tuple2<Long, Long> value1, Tuple2<Long, Long> value2) {
return new Tuple2<>(value1.f0, value1.f1 + value2.f1);
}
}
必须记住: 每个实体的当前状态
- 欺诈检测:检测"小额支付后立即大额支付"
- 用户行为分析:连续3次登录失败
- 设备监控:温度连续上升趋势
场景3:去重
// 检测非法的状态转换
public class StateMachineExample {
// 每个地址维护一个状态机
// 必须记住当前处于什么状态
private ValueState<State> currentState;
@Override
public void flatMap(Event event, Collector<Alert> out) {
State state = currentState.value();
// 根据当前状态判断新事件是否合法
State newState = state.transition(event);
if (newState == State.InvalidTransition) {
out.collect(new Alert(event));
}
currentState.update(newState);
<