我目前正在编写流媒体应用程序,其中:
查询外部系统时:
在Spark中,我会通过mapPartitions做一些事情(如果我有n分区,那么我将只对我的外部系统进行n次查询,并且每个查询将针对微观期间收到的所有警报批处理一个分区)。
现在,我正在寻找Flink,我还没有真正找到在请求外部系统时进行此类分组的最佳方式。
在查看此类用例时,特别是在asyncio(https://ci.apache.org/projects/flink/flink-docs-release-1.4/dev/stream/operators/asyncio.html)时,似乎每个键处理1个查询。
例如,我可以很容易地:
但是通过这样做,我将为每个资源执行1次查询(可能是针对多个警报但链接到相同的密钥,即相同的资源)。 这不是我想要做的,因为它会导致对外部系统的过多查询。
然后,我研究了为我的请求定义一种技术密钥的选项(类似于我想要执行的查询的资源ID%nb的hashCode)。
所以,如果我想并行执行最多4个查询,那么我的密钥将类似于" resourceId.hashCode%4"。
我当时认为没关系,但是当我在运行我的工作时更深入地查看某些指标时,我发现我的查询并没有很好地分发给我的4个操作符实例(其中只有2个正在执行某些操作)。 它用于将键分配给给定运算符实例的机制:
public static int assignKeyToParallelOperator(Object key, int maxParallelism, int parallelism) {
return computeOperatorIndexForKeyGroup(maxParallelism, parallelism, assignToKeyGroup(key, maxParallelism));
}
(在我的例子中,并行度为4,maxParallelism 128和我的键值在[0,4 []范围内(在这样的上下文中,我的2个键转到运算符实例3,2转到运算符实例4)(运算符实例1和2将无关)。 我以为key = 0将转到运算符0,键1转到运算符1,键2转到运算符2,键3转到运算符3,但事实并非如此。
那么你知道在查询外部系统时进行这种分组的最佳方法是什么?
即每个运营商实例对所有警报进行1次查询"已收到"在过去的100ms内通过此运算符实例。
答案 0 :(得分:0)
您可以将聚合器函数放在异步函数的上游,其中该函数(使用定时窗口)输出<resource id><list of alerts to query>
的记录。您可以在聚合器之前通过<resource id>
键入流,然后应该将其流水线化为异步功能。