使用动态编程的二分图分布式处理<! - ? - >

时间:2017-06-25 14:34:12

标签: event-handling dynamic-programming graph-algorithm distributed-computing apache-flink

Data model

我试图找出有效的算法来处理分布式文件(FaaS更精确)环境。

Bruteforce方法将是O(D * F * R),其中:

  • D是要处理的文件数量

  • F是过滤器的数量

  • R是单个过滤器

  • 中规则的最高数量

我可以认为:

  • 单个过滤器的规则不超过10个

  • 某些过滤器可能会共享规则(因此它是N对N的关系)

  • 规则是布尔函数(谓词)所以我可以尝试利用早期切割,这意味着如果我有f()&amp;&amp; g()&amp;&amp; h()使用f()计算为false然后我根本不需要处理g()和h()并且可以立即返回false。

  • 单个文档中的
  • 字段数量始终相同(约5-10)

  • 过滤器,规则和文档已在数据库中

  • 每个过滤器至少有一个规则

使用共享(第二个假设)我有一个想法,首先针对每个规则处理Document,然后(在完成之后)使用已经计算的规则计算结果的每个Filter。这样,如果Rule被共享,那么我只计算一次。但是,它没有利用早期切割(第三种假设)。

第二个想法是使用早期切割作为略微优化的强力,但它不会使用规则共享。

规则共享看起来像子问题共享,因此备忘和动态编程可能会有所帮助。

我注意到,过滤规则关系是二分图。不太确定它是否可以帮助我。我也注意到,我可以使用反向集并在每个Rule store中对应Set。但是,这会产生循环依赖性,并可能导致数据库中的失步问题。

默认的想法是文档是流式传输的,每个文档都是创建FaaS实例来处理它的事件。但是,这可能会强制每个FaaS实例查询所有过滤器,因为Shared-Nothing体系结构而使我处于O(F * D)查询。

样本过滤器:

{
    'normalForm': 'CONJUNCTIVE',
    'rules':
    [
        {
            'isNegated': true,
            'field': 'X',
            'relation': 'STARTS_WITH',
            'value': 'G',
        },
        {
            'isNegated': false,
            'field': 'Y',
            'relation': 'CONTAINS',
            'value': 'KEY',
        },
}

或以更浓缩的形式:

document -> !document.x.startsWith("G") && document.y.contains("KEY")

for Document:

{
    'x': 'CAR',
    'y': 'KEYBOARD',
    'z': 'PAPER',
}

评估为真。

我可以稍微更改数据模型,流式传输其他内容而不是Document(例如过滤器),并使用任何nosql数据库和工具来帮助它。 Apache Flink(事件处理)和MongoDB(使用它的规则检索Filter的单个查询)或者Neo4j(模型看起来像二分图)看起来可以帮助我,但不确定它。

是否可以有效处理(关于 - 可能是 - 数据库查询)?什么工具适合?

我一直在想,如果我正在尝试解决一些可能有用的定理和算法的更一般(数学)问题的特殊情况。

编辑:我的最新想法:像Redis一样收集缓存中的所有文档。然后单个事件启动并发布N个函数(如在函数中作为服务),并且每个函数选择F / N(过滤器数除以实例数 - 因此只需在实例之间均匀分布过滤器)这样每个过滤器都从数据库只有一次。

现在,每个实例都会从缓存中传输所有文档(一个文档应该小于1MB,同时我应该有1-10k,因此应该适合缓存)。这样,每个文档只从数据库中选择一次(缓存)。

我减少了数据库读取操作(仍然多次选择一些规则),但我仍然没有利用跨过滤器的规则共享。我可以通过使用文档数据库故意忽略它。这样选择Filter I也会得到它的规则。仍然 - 我必须重新计算它的价值。

我想这就是我使用Shared Nothing可扩展架构所获得的东西?

1 个答案:

答案 0 :(得分:0)

我意识到虽然我的图形确实(在理论上)是二分的,但(实际上)它将是一组不相交的二分图(因为并非所有规则都将被共享)。这意味着,我可以在不同的FaaS实例上独立处理这些不相交的部分,而无需重新计算相同的规则。

这减少了处理单个二分连通图的问题。现在,我可以使用动态编程的好处,只有当内存i共享时才能共享规则计算的结果,所以我不能在不牺牲这个好处的情况下进一步划分(和分配)这个问题。所以我这样想:如果我已经决定,我将不得不重新计算一些规则,那么与我将得到的不相交的部分相比,它会更低。

这实际上是最小切割问题,其中(幸运的是)多项式复杂度已知算法。

然而,在我的情况下,这可能并不理想,因为我不想削减图形的任何部分 - 我想将图形理想地切成两半(分而治之的策略,可以递归地重新应用,直到图表会很小,可以在FaaS实例中在几秒钟内处理,这有时间限制。)

这意味着,我正在寻找切割,这将产生两个不相交的二分图,每个图可能具有相同数量的顶点(或至少相似)。

这是最稀疏的问题,即NP难,但有O(sqrt(logN))近似算法,也有利于减少切边。

目前,这确实看起来像我的问题的解决方案,但我希望听到任何建议,改进和其他答案。

使用其他数据模型或算法可能会更好吗?也许我可以用一些定理进一步减少它?也许我可以将它转换为其他(更简单)的问题,或者至少更容易在节点之间划分和分配?

这种想法和分析强烈建议使用图形数据库。