单有复制的数据处理的时候,我们可以把表装换成流来处理
工具类 KafkaUtilpublic class KafkaUtil {
private final static String BOOTSTRAP_SERVERS="master:9092";
public static String getKafkaDDL(String topic, String groupId) {
return " with ('connector' = 'kafka', " +
" 'topic' = '" + topic + "'," +
" 'properties.bootstrap.servers' = '" + BOOTSTRAP_SERVERS + "', " +
" 'properties.group.id' = '" + groupId + "', " +
" 'format' = 'json', " +
" 'scan.startup.mode' = 'group-offsets')";
}
public static String getUpsertKafkaDDL(String topic) {
return "WITH ( " +
" 'connector' = 'upsert-kafka', " +
" 'topic' = '" + topic + "', " +
" 'properties.bootstrap.servers' = '" + BOOTSTRAP_SERVERS + "', " +
" 'key.format' = 'json', " +
" 'value.format' = 'json' " +
")";
}
}
Flink Sql装换的实体类
@Data
public class CouponUseOrderBean {
// 优惠券领用记录 id
String id;
// 优惠券 id
String coupon_id;
// 用户 id
String user_id;
// 订单 id
String order_id;
// 优惠券使用日期(下单)
String date_id;
// 优惠券使用时间(下单)
String using_time;
// 历史数据
String old;
// 时间戳
String ts;
}
实现
public class DwdTradeOrderPreProcess {
public static void main(String[] args) throws Exception {
// TODO 1. 环境准备
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(4);
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
// TODO 2. 状态后端设置
env.enableCheckpointing(3000L, CheckpointingMode.EXACTLY_ONCE);
env.getCheckpointConfig().setCheckpointTimeout(60 * 1000L);
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(3000L);
env.getCheckpointConfig().enableExternalizedCheckpoints(
CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION
);
env.setRestartStrategy(RestartStrategies.failureRateRestart(
3, Time.days(1), Time.minutes(1)
));
env.setStateBackend(new HashMapStateBackend());
env.getCheckpointConfig().setCheckpointStorage(
"hdfs://hadoop102:8020/ck"
);
System.setProperty("HADOOP_USER_NAME", "atguigu");
// TODO 3. 从 Kafka 读取业务数据,封装为 Flink SQL 表
tableEnv.executeSql("create table `topic_db` ( " +
"`database` string, " +
"`table` string, " +
"`data` map, " +
"`type` string, " +
"`old` string, " +
"`ts` string " +
")" + KafkaUtil.getKafkaDDL("topic_db", "dwd_tool_coupon_order"));
// TODO 4. 读取优惠券领用表数据,封装为流
Table couponUseOrder = tableEnv.sqlQuery("select " +
"data['id'] id, " +
"data['coupon_id'] coupon_id, " +
"data['user_id'] user_id, " +
"data['order_id'] order_id, " +
"date_format(data['using_time'],'yyyy-MM-dd') date_id, " +
"data['using_time'] using_time, " +
"`old`, " +
"ts " +
"from topic_db " +
"where `table` = 'coupon_use' " +
"and `type` = 'update' ");
DataStream couponUseOrderDS = tableEnv.toAppendStream(couponUseOrder, CouponUseOrderBean.class);
// TODO 5. 过滤满足条件的优惠券下单数据,封装为表
SingleOutputStreamOperator filteredDS = couponUseOrderDS.filter(
couponUseOrderBean -> {
String old = couponUseOrderBean.getOld();
if(old != null) {
Map oldMap = JSON.parseObject(old, Map.class);
Set changeKeys = oldMap.keySet();
return changeKeys.contains("using_time");
}
return true;
}
);
Table resultTable = tableEnv.fromDataStream(filteredDS);
tableEnv.createTemporaryView("result_table", resultTable);
// TODO 6. 建立 Upsert-Kafka dwd_tool_coupon_order 表
tableEnv.executeSql("create table dwd_tool_coupon_order( " +
"id string, " +
"coupon_id string, " +
"user_id string, " +
"order_id string, " +
"date_id string, " +
"order_time string, " +
"ts string, " +
"primary key(id) not enforced " +
")" + KafkaUtil.getUpsertKafkaDDL("dwd_tool_coupon_order"));
// TODO 7. 将数据写入 Upsert-Kafka 表
tableEnv.executeSql("" +
"insert into dwd_tool_coupon_order select " +
"id, " +
"coupon_id, " +
"user_id, " +
"order_id, " +
"date_id, " +
"using_time order_time, " +
"ts from result_table");
env.execute();
}
}



