|
@@ -6,8 +6,11 @@ import com.aliyun.odps.account.Account;
|
|
import com.aliyun.odps.account.AliyunAccount;
|
|
import com.aliyun.odps.account.AliyunAccount;
|
|
import com.aliyun.odps.data.Record;
|
|
import com.aliyun.odps.data.Record;
|
|
import com.aliyun.odps.task.SQLTask;
|
|
import com.aliyun.odps.task.SQLTask;
|
|
|
|
+import com.tencent.ads.model.DailyReportsGetListStruct;
|
|
import com.tencent.ads.model.HourlyReportsGetListStruct;
|
|
import com.tencent.ads.model.HourlyReportsGetListStruct;
|
|
import flink.zanxiangnet.ad.monitoring.maxcompute.MaxComputeLog;
|
|
import flink.zanxiangnet.ad.monitoring.maxcompute.MaxComputeLog;
|
|
|
|
+import flink.zanxiangnet.ad.monitoring.pojo.dto.AdDataOfDayDTO;
|
|
|
|
+import flink.zanxiangnet.ad.monitoring.pojo.dto.AdStatOfDayODSDTO;
|
|
import flink.zanxiangnet.ad.monitoring.pojo.entity.*;
|
|
import flink.zanxiangnet.ad.monitoring.pojo.entity.*;
|
|
import flink.zanxiangnet.ad.monitoring.pojo.properties.ApplicationProperties;
|
|
import flink.zanxiangnet.ad.monitoring.pojo.properties.ApplicationProperties;
|
|
import flink.zanxiangnet.ad.monitoring.pojo.properties.KafkaProperties;
|
|
import flink.zanxiangnet.ad.monitoring.pojo.properties.KafkaProperties;
|
|
@@ -20,6 +23,11 @@ import flink.zanxiangnet.ad.monitoring.util.JsonUtil;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.flink.api.common.eventtime.*;
|
|
import org.apache.flink.api.common.eventtime.*;
|
|
import org.apache.flink.api.common.serialization.SimpleStringSchema;
|
|
import org.apache.flink.api.common.serialization.SimpleStringSchema;
|
|
|
|
+import org.apache.flink.api.common.state.MapState;
|
|
|
|
+import org.apache.flink.api.common.state.MapStateDescriptor;
|
|
|
|
+import org.apache.flink.api.common.state.ValueState;
|
|
|
|
+import org.apache.flink.api.common.state.ValueStateDescriptor;
|
|
|
|
+import org.apache.flink.api.common.typeinfo.Types;
|
|
import org.apache.flink.configuration.Configuration;
|
|
import org.apache.flink.configuration.Configuration;
|
|
import org.apache.flink.connector.kafka.source.KafkaSource;
|
|
import org.apache.flink.connector.kafka.source.KafkaSource;
|
|
import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer;
|
|
import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer;
|
|
@@ -48,8 +56,8 @@ import org.springframework.beans.BeanUtils;
|
|
import java.time.Duration;
|
|
import java.time.Duration;
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
|
+import java.time.LocalTime;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
-import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
public class AdStatJob {
|
|
public class AdStatJob {
|
|
@@ -142,8 +150,7 @@ public class AdStatJob {
|
|
.trigger(new Trigger<AdDataOfMinuteODS, TimeWindow>() {
|
|
.trigger(new Trigger<AdDataOfMinuteODS, TimeWindow>() {
|
|
@Override
|
|
@Override
|
|
public TriggerResult onElement(AdDataOfMinuteODS adDataOfMinuteODS, long time, TimeWindow timeWindow, TriggerContext triggerContext) throws Exception {
|
|
public TriggerResult onElement(AdDataOfMinuteODS adDataOfMinuteODS, long time, TimeWindow timeWindow, TriggerContext triggerContext) throws Exception {
|
|
- System.out.println("eventTime:" + DateUtil.formatLocalDateTime(DateUtil.milliToLocalDateTime(time)) +
|
|
|
|
- " | 水印时间:" + DateUtil.formatLocalDateTime(DateUtil.milliToLocalDateTime(triggerContext.getCurrentWatermark())));
|
|
|
|
|
|
+ // FIXME 水印时间没有意义!拿到数据是 Long.MAX
|
|
if (timeWindow.maxTimestamp() <= triggerContext.getCurrentWatermark()) {
|
|
if (timeWindow.maxTimestamp() <= triggerContext.getCurrentWatermark()) {
|
|
// 到了窗口的最大生命周期
|
|
// 到了窗口的最大生命周期
|
|
return TriggerResult.FIRE_AND_PURGE;
|
|
return TriggerResult.FIRE_AND_PURGE;
|
|
@@ -187,8 +194,10 @@ public class AdStatJob {
|
|
SingleOutputStreamOperator<AdStatOfHourDWD> adHourDWDStream = adHourODSStream.keyBy(AdDataOfHourODS::getAdId)
|
|
SingleOutputStreamOperator<AdStatOfHourDWD> adHourDWDStream = adHourODSStream.keyBy(AdDataOfHourODS::getAdId)
|
|
.countWindow(1).process(new ProcessWindowFunction<AdDataOfHourODS, AdStatOfHourDWD, Long, GlobalWindow>() {
|
|
.countWindow(1).process(new ProcessWindowFunction<AdDataOfHourODS, AdStatOfHourDWD, Long, GlobalWindow>() {
|
|
private Odps odps;
|
|
private Odps odps;
|
|
- private final Map<Long, Long> lastAdQueryTime = new ConcurrentHashMap<>();
|
|
|
|
- private final Map<Long, Map<String, Map<Integer, AdStatOfHourDWD>>> historyAdData = new ConcurrentHashMap<>();
|
|
|
|
|
|
+ // 上次查询的天数据
|
|
|
|
+ private ValueState<String> lastQueryDayState;
|
|
|
|
+ // 聚合的天的数据
|
|
|
|
+ private MapState<String, AdStatOfHourDWD> historyReduceState;
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public void open(Configuration conf) {
|
|
public void open(Configuration conf) {
|
|
@@ -202,58 +211,44 @@ public class AdStatJob {
|
|
odps.getRestClient().setRetryLogger(new MaxComputeLog());
|
|
odps.getRestClient().setRetryLogger(new MaxComputeLog());
|
|
odps.setEndpoint(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ENDPOINT));
|
|
odps.setEndpoint(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ENDPOINT));
|
|
odps.setDefaultProject(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_PROJECT_NAME));
|
|
odps.setDefaultProject(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_PROJECT_NAME));
|
|
|
|
+
|
|
|
|
+ lastQueryDayState = getRuntimeContext().getState(new ValueStateDescriptor<>("lastQueryDayState", String.class));
|
|
|
|
+ historyReduceState = getRuntimeContext().getMapState(new MapStateDescriptor<>("historyReduceState", Types.STRING, Types.POJO(AdStatOfHourDWD.class)));
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public void process(Long elementsCount, ProcessWindowFunction<AdDataOfHourODS, AdStatOfHourDWD, Long, GlobalWindow>.Context context, Iterable<AdDataOfHourODS> iterable, Collector<AdStatOfHourDWD> collector) throws Exception {
|
|
public void process(Long elementsCount, ProcessWindowFunction<AdDataOfHourODS, AdStatOfHourDWD, Long, GlobalWindow>.Context context, Iterable<AdDataOfHourODS> iterable, Collector<AdStatOfHourDWD> collector) throws Exception {
|
|
AdDataOfHourODS element = iterable.iterator().next();
|
|
AdDataOfHourODS element = iterable.iterator().next();
|
|
LocalDate statDay = DateUtil.parseLocalDate(element.getStatDay());
|
|
LocalDate statDay = DateUtil.parseLocalDate(element.getStatDay());
|
|
- Integer hour = element.getHour();
|
|
|
|
|
|
+ LocalDateTime statTime = LocalDateTime.of(statDay, LocalTime.of(element.getHour(), 0, 0));
|
|
long now = System.currentTimeMillis();
|
|
long now = System.currentTimeMillis();
|
|
- Long adId = element.getAdId();
|
|
|
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
|
|
|
- Map<String, Map<Integer, AdStatOfHourDWD>> historyData = historyAdData.computeIfAbsent(adId, key -> new HashMap<>());
|
|
|
|
- Long lastQueryTime = lastAdQueryTime.get(adId);
|
|
|
|
|
|
+ String lastQueryDay = lastQueryDayState.value();
|
|
// 从 maxCompute拉取指定 广告的历史数据
|
|
// 从 maxCompute拉取指定 广告的历史数据
|
|
- if (lastQueryTime == null || (now - lastQueryTime) > 3 * 60 * 60 * 1000) {
|
|
|
|
- LocalDate endTime = LocalDate.now(), beginTime = statDay.minusDays(40);
|
|
|
|
- Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_hour_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginTime) + "\" AND stat_day <= \"" + DateUtil.formatLocalDate(endTime) + "\" AND ad_id = " + element.getAdId() + ";");
|
|
|
|
|
|
+ if (lastQueryDay == null || !lastQueryDay.equals(DateUtil.formatLocalDate(today))) {
|
|
|
|
+ LocalDate endDay = today, beginDay = statDay.minusDays(60);
|
|
|
|
+ Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_hour_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginDay) + "\" AND stat_day <= \"" + DateUtil.formatLocalDate(endDay) + "\" AND ad_id = " + element.getAdId() + ";");
|
|
instance.waitForSuccess();
|
|
instance.waitForSuccess();
|
|
List<Record> records = SQLTask.getResult(instance);
|
|
List<Record> records = SQLTask.getResult(instance);
|
|
- List<AdStatOfHourDWD> historyList = records.stream()
|
|
|
|
|
|
+ Map<String, AdStatOfHourDWD> historyHourMap = records.stream()
|
|
.map(AdStatOfHourDWD::byMaxCompute)
|
|
.map(AdStatOfHourDWD::byMaxCompute)
|
|
.sorted((o1, o2) -> new Long(o1.getCreateTime().getTime() - o2.getCreateTime().getTime()).intValue())
|
|
.sorted((o1, o2) -> new Long(o1.getCreateTime().getTime() - o2.getCreateTime().getTime()).intValue())
|
|
- .collect(Collectors.toList());
|
|
|
|
- for (AdStatOfHourDWD adStatOfHourDWD : historyList) {
|
|
|
|
- Map<Integer, AdStatOfHourDWD> hourMapping = historyData.computeIfAbsent(adStatOfHourDWD.getStatDay(), key -> new HashMap<>());
|
|
|
|
- hourMapping.put(adStatOfHourDWD.getHour(), adStatOfHourDWD);
|
|
|
|
- }
|
|
|
|
- lastAdQueryTime.put(adId, now);
|
|
|
|
|
|
+ .collect(Collectors.toMap(data -> data.getStatDay() + data.getHour(), data -> data, (val1, val2) -> val2));
|
|
|
|
+ historyReduceState.clear();
|
|
|
|
+ historyReduceState.putAll(historyHourMap);
|
|
|
|
+ lastQueryDayState.update(DateUtil.formatLocalDate(today));
|
|
}
|
|
}
|
|
- // 找到这个号当天内上个小时统计的数据
|
|
|
|
- AdStatOfHourDWD lastHourData = null;
|
|
|
|
- // 往前查 40天,找到广告上一次聚合的数据
|
|
|
|
- for (int i = 0; i < 40; i++) {
|
|
|
|
- Map<Integer, AdStatOfHourDWD> mapData = historyData.get(DateUtil.formatLocalDate(statDay.minusDays(i)));
|
|
|
|
- if (mapData == null || mapData.isEmpty()) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- for (Map.Entry<Integer, AdStatOfHourDWD> temp : mapData.entrySet()) {
|
|
|
|
- if (temp.getKey() >= hour) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- if (lastHourData != null && lastHourData.getHour() >= temp.getKey()) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- lastHourData = temp.getValue();
|
|
|
|
- }
|
|
|
|
- if (lastHourData != null) {
|
|
|
|
|
|
+ AdStatOfHourDWD lastReduceData = null;
|
|
|
|
+ for (int i = 1; i < 60 * 24; i++) {
|
|
|
|
+ LocalDateTime time = statTime.minusHours(i);
|
|
|
|
+ lastReduceData = historyReduceState.get(DateUtil.formatLocalDate(time.toLocalDate()) + time.getHour());
|
|
|
|
+ if (lastReduceData != null) {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- AdStatOfHourDWD newStatData = AdStatOfHourDWD.reduce(lastHourData, element, now);
|
|
|
|
- Map<Integer, AdStatOfHourDWD> hourDataMapping = historyData.computeIfAbsent(newStatData.getStatDay(), key -> new HashMap<>());
|
|
|
|
- hourDataMapping.put(newStatData.getHour(), newStatData);
|
|
|
|
|
|
+
|
|
|
|
+ AdStatOfHourDWD newStatData = AdStatOfHourDWD.reduce(lastReduceData, element, now);
|
|
collector.collect(newStatData);
|
|
collector.collect(newStatData);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -264,7 +259,7 @@ public class AdStatJob {
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------- 处理广告的天数据 -----------------------------------------
|
|
// ------------------------------------------------------- 处理广告的天数据 -----------------------------------------
|
|
- /*Properties adStreamOfDayProps = new Properties();
|
|
|
|
|
|
+ Properties adStreamOfDayProps = new Properties();
|
|
adStreamOfDayProps.load(AdStatJob.class.getResourceAsStream("/ad_stream_of_day.properties"));
|
|
adStreamOfDayProps.load(AdStatJob.class.getResourceAsStream("/ad_stream_of_day.properties"));
|
|
KafkaSource<String> adStreamOfDaySource = buildKafkaSource(adStreamOfDayProps);
|
|
KafkaSource<String> adStreamOfDaySource = buildKafkaSource(adStreamOfDayProps);
|
|
|
|
|
|
@@ -320,14 +315,13 @@ public class AdStatJob {
|
|
});
|
|
});
|
|
|
|
|
|
SingleOutputStreamOperator<AdStatOfDayDWD> adDayDWDStream = adDayODSStreamSplit.getSideOutput(adDayStreamRollDayTag)
|
|
SingleOutputStreamOperator<AdStatOfDayDWD> adDayDWDStream = adDayODSStreamSplit.getSideOutput(adDayStreamRollDayTag)
|
|
- // 打水印,允许延迟 10天(应为允许回滚 10天),同时指定事件时间
|
|
|
|
- .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfDayODS>forBoundedOutOfOrderness(Duration.ofDays(10L))
|
|
|
|
- .withTimestampAssigner((SerializableTimestampAssigner<AdDataOfDayODS>) (adDay, l) -> DateUtil.localDateToMilli(DateUtil.parseLocalDate(adDay.getStatDay())))
|
|
|
|
- ).keyBy(AdDataOfDayODS::getAdId)
|
|
|
|
|
|
+ .keyBy(AdDataOfDayODS::getAdId)
|
|
.countWindow(1).process(new ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>() {
|
|
.countWindow(1).process(new ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>() {
|
|
private Odps odps;
|
|
private Odps odps;
|
|
- private final Map<Long, Long> lastAdQueryTime = new ConcurrentHashMap<>();
|
|
|
|
- private final Map<Long, Map<String, AdStatOfDayDWD>> historyAdData = new ConcurrentHashMap<>();
|
|
|
|
|
|
+ // 上次查询的天数据
|
|
|
|
+ private ValueState<String> lastQueryDayState;
|
|
|
|
+ // 之前聚合的昨天的数据
|
|
|
|
+ private MapState<String, AdStatOfDayDWD> historyReduceState;
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public void open(Configuration conf) {
|
|
public void open(Configuration conf) {
|
|
@@ -341,44 +335,41 @@ public class AdStatJob {
|
|
odps.getRestClient().setRetryLogger(new MaxComputeLog());
|
|
odps.getRestClient().setRetryLogger(new MaxComputeLog());
|
|
odps.setEndpoint(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ENDPOINT));
|
|
odps.setEndpoint(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ENDPOINT));
|
|
odps.setDefaultProject(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_PROJECT_NAME));
|
|
odps.setDefaultProject(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_PROJECT_NAME));
|
|
|
|
+
|
|
|
|
+ lastQueryDayState = getRuntimeContext().getState(new ValueStateDescriptor<>("lastQueryDayState", String.class));
|
|
|
|
+ historyReduceState = getRuntimeContext().getMapState(new MapStateDescriptor<>("historyReduceState", String.class, AdStatOfDayDWD.class));
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public void process(Long elementsCount, ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>.Context context, Iterable<AdDataOfDayODS> iterable, Collector<AdStatOfDayDWD> collector) throws Exception {
|
|
public void process(Long elementsCount, ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>.Context context, Iterable<AdDataOfDayODS> iterable, Collector<AdStatOfDayDWD> collector) throws Exception {
|
|
AdDataOfDayODS element = iterable.iterator().next();
|
|
AdDataOfDayODS element = iterable.iterator().next();
|
|
- Long adId = element.getAdId();
|
|
|
|
LocalDate statDay = DateUtil.parseLocalDate(element.getStatDay());
|
|
LocalDate statDay = DateUtil.parseLocalDate(element.getStatDay());
|
|
long now = System.currentTimeMillis();
|
|
long now = System.currentTimeMillis();
|
|
|
|
|
|
- Map<String, AdStatOfDayDWD> historyData = historyAdData.computeIfAbsent(adId, key -> new HashMap<>());
|
|
|
|
- Long lastQueryTime = lastAdQueryTime.get(adId);
|
|
|
|
|
|
+ String lastQueryDay = lastQueryDayState.value();
|
|
// 从 maxCompute查找广告的历史数据
|
|
// 从 maxCompute查找广告的历史数据
|
|
- if (lastQueryTime == null || (now - lastQueryTime) > 60 * 60 * 1000) {
|
|
|
|
|
|
+ if (lastQueryDay == null || !lastQueryDay.equals(DateUtil.formatLocalDate(LocalDate.now()))) {
|
|
LocalDate endTime = LocalDate.now(), beginTime = statDay.minusDays(60);
|
|
LocalDate endTime = LocalDate.now(), beginTime = statDay.minusDays(60);
|
|
Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_day_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginTime) + "\" AND stat_day <= \"" + DateUtil.formatLocalDate(endTime) + "\" AND ad_id = " + element.getAdId() + ";");
|
|
Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_day_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginTime) + "\" AND stat_day <= \"" + DateUtil.formatLocalDate(endTime) + "\" AND ad_id = " + element.getAdId() + ";");
|
|
instance.waitForSuccess();
|
|
instance.waitForSuccess();
|
|
List<Record> records = SQLTask.getResult(instance);
|
|
List<Record> records = SQLTask.getResult(instance);
|
|
- List<AdStatOfDayDWD> list = records.stream()
|
|
|
|
|
|
+ Map<String, AdStatOfDayDWD> historyData = records.stream()
|
|
.map(AdStatOfDayDWD::byMaxCompute)
|
|
.map(AdStatOfDayDWD::byMaxCompute)
|
|
- .sorted((o1, o2) -> new Long(o1.getCreateTime().getTime() - o2.getCreateTime().getTime()).intValue()).collect(Collectors.toList());
|
|
|
|
- for (AdStatOfDayDWD adStatOfDayDWD : list) {
|
|
|
|
- historyData.put(adStatOfDayDWD.getStatDay(), adStatOfDayDWD);
|
|
|
|
- }
|
|
|
|
- lastAdQueryTime.put(adId, now);
|
|
|
|
|
|
+ .sorted((o1, o2) -> new Long(o1.getCreateTime().getTime() - o2.getCreateTime().getTime()).intValue())
|
|
|
|
+ .collect(Collectors.toMap(AdStatOfDayDWD::getStatDay, data -> data, (val1, val2) -> val2));
|
|
|
|
+ historyReduceState.clear();
|
|
|
|
+ historyReduceState.putAll(historyData);
|
|
|
|
+ lastQueryDayState.update(DateUtil.formatLocalDate(LocalDate.now()));
|
|
}
|
|
}
|
|
- AdStatOfDayDWD newStatData = null;
|
|
|
|
|
|
+ AdStatOfDayDWD lastReduceData = null;
|
|
for (int i = 1; i <= 60; i++) {
|
|
for (int i = 1; i <= 60; i++) {
|
|
- AdStatOfDayDWD oldStatData = historyData.get(DateUtil.formatLocalDate(statDay.minusDays(i)));
|
|
|
|
- if (oldStatData == null) {
|
|
|
|
- continue;
|
|
|
|
|
|
+ lastReduceData = historyReduceState.get(DateUtil.formatLocalDate(statDay.minusDays(i)));
|
|
|
|
+ if (lastReduceData != null) {
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
- newStatData = AdStatOfDayDWD.reduce(oldStatData, element, now);
|
|
|
|
- break;
|
|
|
|
}
|
|
}
|
|
- if (newStatData == null) {
|
|
|
|
- newStatData = AdStatOfDayDWD.reduce(null, element, now);
|
|
|
|
- }
|
|
|
|
- historyData.put(newStatData.getStatDay(), newStatData);
|
|
|
|
|
|
+ AdStatOfDayDWD newStatData = AdStatOfDayDWD.reduce(lastReduceData, element, now);
|
|
|
|
+ historyReduceState.put(DateUtil.formatLocalDate(statDay), newStatData);
|
|
collector.collect(newStatData);
|
|
collector.collect(newStatData);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -388,7 +379,7 @@ public class AdStatJob {
|
|
.addSink(new TunnelBatchStreamSink<>(AdStatOfDayDWD.class));
|
|
.addSink(new TunnelBatchStreamSink<>(AdStatOfDayDWD.class));
|
|
|
|
|
|
SingleOutputStreamOperator<AdStatOfDayDWD> adDayDWDYearStream = adDayODSStreamSplit.getSideOutput(adDayStreamRollYearTag)
|
|
SingleOutputStreamOperator<AdStatOfDayDWD> adDayDWDYearStream = adDayODSStreamSplit.getSideOutput(adDayStreamRollYearTag)
|
|
- .keyBy((KeySelector<AdDataOfDayODS, Long>) AdDataOfDayODS::getAdId)
|
|
|
|
|
|
+ .keyBy(AdDataOfDayODS::getAdId)
|
|
.countWindow(1).process(new ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>() {
|
|
.countWindow(1).process(new ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>() {
|
|
// 上次聚合的结果
|
|
// 上次聚合的结果
|
|
private AdStatOfDayDWD lastReduce;
|
|
private AdStatOfDayDWD lastReduce;
|
|
@@ -403,7 +394,7 @@ public class AdStatJob {
|
|
//.addSink(new TunnelBatchSink<>(AdStatOfDayDWD.class, 30000L, 365L, 6));
|
|
//.addSink(new TunnelBatchSink<>(AdStatOfDayDWD.class, 30000L, 365L, 6));
|
|
new KeyedBatchStream<>("adDayDWDYearStream", adDayDWDYearStream.keyBy(AdStatOfDayDWD::getStatDay), 4000L, 60 * 1000L)
|
|
new KeyedBatchStream<>("adDayDWDYearStream", adDayDWDYearStream.keyBy(AdStatOfDayDWD::getStatDay), 4000L, 60 * 1000L)
|
|
.toBatch()
|
|
.toBatch()
|
|
- .addSink(new TunnelBatchStreamSink<>(AdStatOfDayDWD.class));*/
|
|
|
|
|
|
+ .addSink(new TunnelBatchStreamSink<>(AdStatOfDayDWD.class));
|
|
|
|
|
|
env.execute();
|
|
env.execute();
|
|
}
|
|
}
|