Flink中的map/flatMap/keyBy算子

Flink中的map/flatMap/keyBy算子

map算子

代码来源于尚硅谷课程的资料
1.使用::符号

//将每行数据转换为json对象
SingleOutputStreamOperator<JSONObject> jsonObjDs = kafkaDs.map (JSON::parseObject);

2.使用Lambda表达式

//TODO 3.将每行数据转换为JavaBean对象

        SingleOutputStreamOperator<UserRegisterBean> userRegisterDs = kafkaDS.map (line -> {
   
   
            JSONObject jsonObject = JSON.parseObject (line);
            String createTime = jsonObject.getString ("create_time");
            return new UserRegisterBean ("", "", 1L, DateFromatUtil.toTs (createTime, true));
        });

3.使用富函数类,其中open方法是初始化方法,当算子map方法被调用之前,open()首先会被调用。

// TODO 5.使用状态编程做新老访客标记校验
        SingleOutputStreamOperator<JSONObject> jsonObjWithNewFlagDS = keyedStream.map (new RichMapFunction<JSONObject, JSONObject> () {
   
   

            private ValueState<String> lastVisitState;


            @Override
            public void open(Configuration parameters) throws Exception {
   
   
                lastVisitState = getRuntimeContext ().getState (new ValueStateDescriptor<String> ("last-visit", String.class))
<think>我们正在处理一个关于Flinkmap算子使用算子状态来计算数据量的代码示例请求。根据引用[3],我们知道在Flink中,算子状态可以通过实现CheckpointedFunction接口来使用,该接口定义了与状态持久化和检查点相关的操作。同时,引用[1]提到状态操作符和用户自定义函数在流处理中用于保存数据或计算结果。我们的目标:在map算子中维护一个计数器状态,每次处理一个元素就将计数器加1,从而统计该算子任务处理的数据总量。注意:由于是并行任务,每个并行子任务会独立维护一个计数器,因此得到的是该子任务处理的数据量。如果需要全局数据量,可能需要使用KeyedStream和Reduce等操作。步骤:1.创建一个实现了MapFunction和CheckpointedFunction的类。-MapFunction:定义数据转换逻辑,这里我们除了原样输出数据(或进行其他转换)外,还要更新计数状态。-CheckpointedFunction:管理状态,包括在快照时保存状态和从快照恢复时恢复状态。2.在CheckpointedFunction中:-定义状态:使用ListState来存储状态。因为算子状态可以是列表形式,我们只需要一个计数器,因此可以将一个长整型值放在列表中。-初始化状态:在initializeState方法中,从状态上下文中获取或初始化状态。-快照状态:在snapshotState方法中,将当前计数器的值存入状态。3.在MapFunction的map方法中,处理每条数据时更新计数器。4.注意:由于我们使用列表状态,实际上我们存储的是一个只有一个元素的列表(即计数器的值)。代码示例:注意:根据引用[4],FlinkFlatMap算子示例展示了如何解析JSON,我们这里使用Map算子,并且只关注计数。另外,根据引用[5],Flink有23种算子,其中map是常用的一种。下面给出代码示例:</think> 在 Flink 中使用 Map 算子配合算子状态实现数据量统计的代码示例如下。这里基于 `CheckpointedFunction` 接口实现状态管理,包含完整的状态初始化和快照机制: ```java import org.apache.flink.api.common.functions.MapFunction; import org.apache.flink.api.common.state.ListState; import org.apache.flink.api.common.state.ListStateDescriptor; import org.apache.flink.runtime.state.FunctionInitializationContext; import org.apache.flink.runtime.state.FunctionSnapshotContext; import org.apache.flink.streaming.api.checkpoint.CheckpointedFunction; public class StatefulCounterMap implements MapFunction<String, Long>, CheckpointedFunction { // 声明算子状态(状态列表) private transient ListState<Long> counterState; // 本地计数器 private long localCounter = 0L; @Override public Long map(String value) { // 每收到一条数据,计数器增加 localCounter++; return localCounter; } @Override public void snapshotState(FunctionSnapshotContext context) throws Exception { // 检查点触发时:清空状态并保存当前计数 counterState.clear(); counterState.add(localCounter); } @Override public void initializeState(FunctionInitializationContext context) throws Exception { // 初始化算子状态(使用列表状态存储单值) ListStateDescriptor<Long> descriptor = new ListStateDescriptor<>("counterState", Long.class); counterState = context.getOperatorStateStore().getListState(descriptor); // 从状态恢复历史值 if (context.isRestored()) { for (Long count : counterState.get()) { localCounter += count; // 恢复之前保存的计数 } } } } ``` **部署到流处理作业中**: ```java StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 启用检查点(必须配置才能持久化状态) env.enableCheckpointing(5000); // 每5秒做一次检查点 DataStream<String> inputStream = env.socketTextStream("localhost", 9999); DataStream<Long> resultStream = inputStream .map(new StatefulCounterMap()) // 应用自定义算子 .setParallelism(2); // 设置并行度 resultStream.print(); env.execute("Stateful Counter Job"); ``` ### 关键特性说明 1. **状态恢复机制**: - 作业重启时通过 `initializeState()` 自动加载历史状态值 - 支持作业扩缩容时状态自动重分布[^3] 2. **容错保证**: - 通过 `snapshotState()` 周期保存状态快照 - 配合 Checkpoint 机制保证 *exactly-once* 语义[^3] 3. **状态类型选择**: - 使用 `ListState` 而非 `ValueState`:支持状态重分区 - 可存储多个值(本例中只存总计数)[^1] > **注意事项**: > - 算子状态为**当前并行子任务**的计数(非全局总计) > - 若需全局统计,需配合 `keyBy().reduce()` 方案 > - 状态存储需配置持久化后端(如 RocksDB)以支持大状态[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值