让我们假设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中极少数线程的大规模可伸缩性?
答案 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