我试图像下面那样进行流媒体处理,
我将此作为参考:https://jsfiddle.net/n4v63g3L/6/
我的流媒体代码如下:
mappedDataSource
.connect(mappedRuleStream)
.keyBy(..deviceId..)
.process(new RuleProcessorFunction())
.windowAll(new CustomTimeWindowing())
.apply(new AllWindowFunction<ProcessedEvent, Object, TimeWindow>() {
@Override
public void apply(TimeWindow window, Iterable<ProcessedEvent> values, Collector out) throws Exception {
System.out.println("hello");
}
});
RuleProcessorFunction
是:
public class RuleProcessorFunction extends CoProcessFunction<SensorEvent, RuleEvent, ProcessedEvent> {
private transient ValueState<Tuple2<SensorEvent, RuleEvent>> state;
@Override
public void processElement1(SensorEvent value, Context ctx, Collector<ProcessedEvent> out) throws Exception {
System.out.println("process element device id : " + value.deviceId);
System.out.println("process element solution id : " + value.solutionId);
state.update(Tuple2.of(value, null));
RuleEvent rule = state.value().f1;
// execute if there is a defined rule on incoming event
}
@Override
public void processElement2(RuleEvent value, Context ctx, Collector<ProcessedEvent> out) throws Exception {
System.out.println("rule stream element solId :" + value.solutionId + " devId : " + value.deviceId);
state.value().f1 = value;
// store rule in memory
// processed event is gonna be stored window information and downstream is window assignment
ProcessedEvent processedEvent = new ProcessedEvent();
processedEvent.deviceId = value.deviceId;
processedEvent.solutionId = value.solutionId;
processedEvent.windowInfo = value.window;
processedEvent.ruleId = value.ruleId;
out.collect(processedEvent);
}
@Override
public void open(Configuration parameters) throws Exception {
ValueStateDescriptor<Tuple2<SensorEvent, RuleEvent>> stateDescriptor =
new ValueStateDescriptor<>("processor", TypeInformation.of(new TypeHint<Tuple2<SensorEvent, RuleEvent>>() {
}));
state = getRuntimeContext().getState(stateDescriptor);
}
@Override
public void onTimer(long timestamp, OnTimerContext ctx, Collector<ProcessedEvent> out) throws Exception {
// rule triggers
}
}
CustomWindowAssigner
是:
public class CustomTimeWindowing extends TumblingEventTimeWindows {
public CustomTimeWindowing() {
super(1, 0);
}
@Override
public Collection<TimeWindow> assignWindows(Object element, long timestamp, WindowAssignerContext context) {
System.out.println("creating window : ");
ProcessedEvent processedEvent = (ProcessedEvent) element;
int windowInfo = processedEvent.windowInfo;
System.out.println("creating window rule : " + processedEvent.ruleId);
long size = windowInfo * 1000;
System.out.println("window info in milisecond :" + size);
long start = timestamp - (timestamp % size);
long end = start + size;
return Collections.singletonList(new TimeWindow(start, end));
}
}
当ruleEvent出现时,我会添加有关窗口信息的元数据并添加到收集器中以保持流式传输。但如果我在SensorEvent的processElement1中执行此操作,则会再次调用windowAssigner并更改窗口。我希望它在新的/更改的窗口信息出现时进入。
创建这种结构的正确方法是什么?手动管理Windows还是使用这种自定义窗口分配器?
另一个参考:https://techblog.king.com/rbea-scalable-real-time-analytics-king/