通常情况下,Flink访问外部数据,在同一个并行度中式同步进行的,一个请求发送等待接收数据然后才会发送下一个请求。这种情况下虽然Flink有很多并行度,并且可以提高并行度的方式提高读写数据的并发,但是这样效率还是不高。
Flink异步IO就一定程度的解决了这个问题,它可以允许在同一个并行度中异步发送请求,然后多个请求同时等待数据。大大提高了数据读写的效率。
异步IO的前提条件是第三方数据库必须有支持发送异步请求的客户端。
异步IO必须具有顺序处理、事件时间、容错等功能。
官方的例子:
//实现RichAsyncFunction
class AsyncDatabaseRequest extends RichAsyncFunction<String, Tuple2<String, String>> {
private transient DatabaseClient client;
@Override
public void open(Configuration parameters) throws Exception {
//初始化数据库client
client = new DatabaseClient(host, post, credentials);
}
@Override
public void close() throws Exception {
client.close();
}
@Override
public void asyncInvoke(String key, final ResultFuture<Tuple2<String, String>> resultFuture) throws Exception {
final Future<String> result = client.query(key);
// 当查询完毕,返回执行回调
CompletableFuture.supplyAsync(new Supplier<String>() {
@Override
public String get() {
try {
return result.get();
} catch (InterruptedException | ExecutionException e) {
return null;
}
}
}).thenAccept( (String dbResult) -> {
resultFuture.complete(Collections.singleton(new Tuple2<>(key, dbResult)));
});
}
}
// 使用异步IO
/**
* @Param stream: input stream
* @Param AsyncFunction: 自定义异步IO
* @Param 1000: timeout时间
* @Param TimeUnit.MILLISECONDS: timeout单位
* @Param 100: 并行度
*
* unorderedWait/orderedWait: 是否保证有序
*/
DataStream<Tuple2<String, String>> resultStream =
AsyncDataStream.unorderedWait(stream, new AsyncDatabaseRequest(), 1000, TimeUnit.MILLISECONDS, 100);