Flink DataStream 异步IO

288 阅读1分钟

通常情况下,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);