执行REST调用的Flink转换(async,Future,Netty)

时间:2016-08-07 02:40:49

标签: asynchronous netty apache-flink

让我们假设Flink每秒收到1000条推文的流,而在流程的某个地方,它需要将它们归类为垃圾邮件。我有一群例如20台机器提供"分类"通过REST API进行微服务,他们可以提供每秒10k条推文的最大吞吐量,延迟时间为3秒。这意味着在最坏的情况下,我可能会有30k的推文即可,而且还可以。我想要从Flink使用这个服务,实现将是这样的:

public class Classifier implements MapFunction<Tweet, TweetWithClass> {
  @Override
  public TweetWithClass map(Tweet tweet) {
    TweetWithClass twc = new TweetWithClass(tweet);
    twc.classes = (new Post('http://my.classifier.com', data = tweet.body)).bodyAsStringArrayFromJson();
    return twc;
  }
}

DataSet<TweetWithClass> outTweets = inTweets.map(new Classifier()).setParallelism(30000);

现在,考虑到这个API,我的猜测是Flink除了启动30k线程之外别无选择,这可能会很糟糕。我在源代码中看到Flink使用Netty,我想它可以通过使用异步调用更有效地支持这个操作......如果存在虚构的漂亮的Netty,Flink和Java API,这将看起来像这样:

public class Classifier implements MapFunction<Tweet, TweetWithClass> {
  @Override
  public Future<TweetWithClass> map(Tweet tweet) {
    Future<String[]> classes = (new NettyPost('http://my.classifier.com', data = tweet.body)).asyncBodyAsStringArrayFromJson();
    return classes.onGet( (String[] classes) -> new TweetWithClass(tweet, twc.classes) );
  }
}

DataSet<TweetWithClass> outTweets = inTweets.nettyMap(new Classifier()).setMaxParallelism(30000);

有没有办法使用异步调用来获得Flink中极少数线程的大规模可伸缩性?

1 个答案:

答案 0 :(得分:2)

我知道这是一个相对古老的问题,但截至Flink 1.2(2017年2月发布),Flink正是为此提供了一个API。 它被称为异步I / O.

使用异步I / O,您可以对外部数据库或外部Web服务执行异步调用,并在将来通过回调获取结果。

可在此处找到更多信息:https://ci.apache.org/projects/flink/flink-docs-release-1.3/dev/stream/asyncio.html