Apache flink 在RichCoFlatMapFunction中更新外部数据库
我有一个RichCoFlatMapFunctionApache flink 在RichCoFlatMapFunction中更新外部数据库,apache-flink,flink-streaming,Apache Flink,Flink Streaming,我有一个RichCoFlatMapFunction DataStream<Metadata> metadataKeyedStream = env.addSource(metadataStream) .keyBy(Metadata::getId); SingleOutputStreamOperator<Output> outputStream = env.addSource(recordStream) .assignTime
DataStream<Metadata> metadataKeyedStream =
env.addSource(metadataStream)
.keyBy(Metadata::getId);
SingleOutputStreamOperator<Output> outputStream =
env.addSource(recordStream)
.assignTimestampsAndWatermarks(new RecordTimeExtractor())
.keyBy(Record::getId)
.connect(metadataKeyedStream)
.flatMap(new CustomCoFlatMap(metadataTable.listAllAsMap()));
public class CustomCoFlatMap extends RichCoFlatMapFunction<Record, Metadata, Output> {
private transient Map<String, Metadata> datasource;
private transient ValueState<String, Metadata> metadataState;
@Inject
public void setDataSource(Map<String, Metadata> datasource) {
this.datasource = datasource;
}
@Override
public void open(Configuration parameters) throws Exception {
// read ValueState
metadataState = getRuntimeContext().getState(
new ValueStateDescriptor<String, Metadata>("metadataState", Metadata.class));
}
@Override
public void flatMap2(Metadata metadata, Collector<Output> collector) throws Exception {
// if metadata record is removed from table, removing the same from local state
if(metadata.getEventName().equals("REMOVE")) {
metadataState.clear();
return;
}
// update metadata in ValueState
this.metadataState.update(metadata);
}
@Override
public void flatMap1(Record record, Collector<Output> collector) throws Exception {
Metadata metadata = this.metadataState.value();
// if metadata is not present in ValueState
if(metadata == null) {
// get metadata from datasource
metadata = datasource.get(record.getId());
// if metadata found in datasource, add it to ValueState
if(metadata != null) {
metadataState.update(metadata);
Output output = new Output(record.getId(), metadataState.getName(),
metadataState.getVersion(), metadata.getType());
if(metadata.getId() == 123) {
// here I want to update metadata into another Database
// can I do it here directly ?
}
collector.collect(output);
}
}
}
}
数据流metadataKeyedStream=
环境addSource(元数据流)
.keyBy(元数据::getId);
SingleOutputStream运算符outputStream=
环境添加源(记录流)
.assignTimestampsAndWatermarks(新的RecordTimeExtractor())
.keyBy(记录::getId)
.connect(metadataKeyedStream)
.flatMap(新的CustomCoFlatMap(metadataTable.listAllAsMap());
公共类CustomCoFlatMap扩展了RichCoFlatMapFunction{
私有瞬态地图数据源;
私有瞬态值状态元数据状态;
@注入
公共void setDataSource(映射数据源){
this.datasource=数据源;
}
@凌驾
公共void open(配置参数)引发异常{
//读取值状态
metadataState=getRuntimeContext().getState(
新的ValueStateDescriptor(“metadataState”,Metadata.class));
}
@凌驾
公共void flatMap2(元数据、收集器)引发异常{
//如果从表中删除元数据记录,则从本地状态中删除元数据记录
if(metadata.getEventName().equals(“删除”)){
metadataState.clear();
返回;
}
//更新ValueState中的元数据
this.metadataState.update(元数据);
}
@凌驾
公共void flatMap1(记录记录、收集器)引发异常{
元数据元数据=this.metadataState.value();
//如果ValueState中不存在元数据
if(元数据==null){
//从数据源获取元数据
元数据=datasource.get(record.getId());
//如果在数据源中找到元数据,请将其添加到ValueState
if(元数据!=null){
metadataState.update(元数据);
输出=新输出(record.getId(),metadataState.getName(),
metadataState.getVersion(),metadata.getType();
if(metadata.getId()==123){
//这里我想将元数据更新到另一个数据库中
//我可以直接在这里做吗?
}
collect.collect(输出);
}
}
}
}
在这里,在flatmap1方法中,我想更新一个数据库。我可以在flatmap1中执行该操作吗?我这样问是因为它需要一些等待时间来查询数据库,然后更新数据库。虽然原则上可以这样做,但这不是一个好主意。在Flink用户函数中执行同步i/o会导致两个问题:
键控协处理函数
,并将预期的数据库更新作为。然后,可以通过数据库接收器或使用