【发布时间】:2021-12-22 21:37:57
【问题描述】:
当我对部分数据执行一些计算时,我有一个用例,这些计算取决于上下文(中间状态)。
例如:我有一些订单并对其进行一些计算。对按交易品种字段分组的订单执行计算。
class Order {
LocalDateTime ts;
String symbol;
....
}
所以我决定按符号字段键入订单并为每个组保留单独的状态:
DataStream<Order> orders = tableEnv.toDataStream(selectStatement, Order.class);
orders.keyBy(Order::getSymbol).flatMap(new SymbolExecutionContext()).addSink(jdbcSink);
带状态的函数:
public class SymbolExecutionContext extends RichFlatMapFunction<Order, OrderBookRow> {
private transient ValueState<OrderBook> orderBookState;
@Override
public void flatMap(Order input, Collector<OrderBookRow> out) throws Exception {
OrderBook orderBook = this.orderBookState.value();
if (orderBook == null) {
orderBook = new OrderBook(input.getSymbol());
this.orderBookState.update(orderBook);
orderBook = this.orderBookState.value();
}
final List<OrderBookRow> execute = OrderBookService.execute(input, orderBook);
for (final OrderBookRow orderBookRow : execute) {
out.collect(orderBookRow);
}
this.orderBookState.update(orderBook);
}
@Override
public void open(Configuration config) {
ValueStateDescriptor<OrderBook> descriptor = new ValueStateDescriptor<OrderBook>("orderbook", OrderBook.class, null);
orderBookState = getRuntimeContext().getState(descriptor);
}
}
所以我为每个独特的符号创建了新的 OrderBook。 OrderBook 表示符号上下文,其中对具有相同符号的每个订单执行一些计算。
但它似乎不起作用。如果只有一个符号,它会很好地工作。如果不止一个,它会产生无效的结果(缺失或不准确),并且结果或多或少是不可预测的。
Flink 作业以批处理方式执行。
有没有更好的方法来处理这个用例?
【问题讨论】:
-
还有什么重要的,我希望以有序的方式处理订单(按时间戳字段排序)