如何根据数百条规则在Apache Beam /数据流中合并相关记录?

时间:2018-11-04 18:19:38

标签: google-cloud-platform google-cloud-dataflow apache-beam dataflow

我有必须在记录级别加入的数据。例如,有关用户的数据来自不同的源系统,但是没有通用的主键或用户标识符

示例数据

Source System 1:
{userid = 123, first_name="John", last_name="Smith", many other columns...}

Source System 2:
{userid = EFCBA-09DA0, fname="J.", lname="Smith", many other columns...}
  • 我可以使用大约100条规则将一条记录与另一条记录进行比较 查看源系统1中的客户是否与源系统2中的客户相同。
  • 某些规则可能能够推断记录值并将数据添加到有关客户的主记录中。
  • 由于某些规则可能会将数据推断/添加到任何特定记录,因此当记录更改时必须再次重新应用这些规则。
  • 我们每天必须整合数百万条记录

Apache Beam /数据流实现

  • 根据定义,Apache Beam DAG是非循环的,但我可以通过pubsub将数据重新发布到同一DAG,以使其成为循环算法。
  • 我可以创建一个哈希表的PCollection,它连续对所有其他元素进行自联接,但这似乎是一种效率低下的方法
  • 如果我希望在规则进行过程中不断对其进行修改,则PCollection的不可移植性将是一个问题。听起来,使用Flink GellySpark GraphX
  • 会更有效率

您是否可以在数据流中知道有效解决此类问题的任何方式?

其他想法

  • Prolog:我尝试使用一部分规则在这些数据的子集上运行,但是swi-prolog似乎没有可扩展性,而且我不知道如何将结果不断地传递给其他流程。
  • JDrools / Jess / Rete:前向链接对于推理和高效的部分应用程序来说是完美的选择,但是该算法更多地是对单个记录应用许多规则,而不是从可能相关的记录中推断记录信息。
  • 图形数据库:neo4jdatomic之类的东西会很好,因为联接处于记录级别而不是行/列扫描,但是我不知道是否有可能在Beam中做一些事情相似
  • BigQuery或Spanner:蛮力在SQL中强制执行这些规则,并对每条记录进行全表扫描确实很慢。将所有记录的图形保存在内存中并在内存中进行计算将是更可取的。我们也可以尝试合并所有列,并在所有列中运行多个比较和更新

或者也许有一种更标准的方法来解决这类问题。

1 个答案:

答案 0 :(得分:2)

从我到目前为止所读的内容中很难说哪种解决方案最适合您。我将尝试进一步分解问题,并尝试分别解决不同方面。

据我了解,目标是将代表不同来源的同一事物的匹配记录组合在一起:

  • 记录来自许多来源:
    • 逻辑上是相同的数据,但格式不同;
  • 有一些规则可以判断记录是否代表相同的实体:
    • 规则收集是静态的;

因此,逻辑可能大致如下:

  • 阅读记录;
  • 尝试查找现有的匹配记录;
  • 如果找到匹配的记录:
    • 用新数据更新它;
  • 否则保存记录以备将来匹配;
  • 重复;

在我看来,这是一个很高的层次,在这个细节层次上可能没有单一的“正确”解决方案。

我可能会尝试通过首先更详细地了解它(也许您已经这样做)来尝试解决此问题,而对此却有些想法:

  • 数据的属性是什么?
    • 有模式吗?例如。当一个系统发布某些内容时,您是否希望其他系统发布其他内容?
  • 一般要求是什么?
    • 延迟,一致性,可用性等;
  • 如何从源中读取数据?
    • 所有系统都可以将记录分批发布为文件,将其提交到PubSub,您的解决方案是否需要轮询等等?
    • 数据可以并行读取还是单个流?
  • 然后,如何才能有效地匹配记录的主要问题在不同的假设和要求下也可能看起来有所不同。例如,我会考虑:
    • 您是否可以将所有数据放入内存中?
    • 您的规则是动态的。他们会改变吗,当他们改变时会发生什么?
    • 您能否将数据划分为可以分别存储和有效匹配的类别,例如如果您知道您可以尝试通过id字段匹配某些内容,通过某些内容的哈希值匹配其他内容,等等;
    • 您需要匹配所有历史/现有数据吗?
    • 您可以使用一些快速排除逻辑来不进行昂贵的检查吗?
  • 解决方案的输出是什么?输出的要求是什么?