如何在Google Dataflow中结合两组不同的标识符?

时间:2018-07-26 18:39:31

标签: java etl google-cloud-dataflow apache-beam

我有两套相当大的数据集,每套都是〜600GB。

第一个签名是:

  • KV<String,String>,其中两个String代表来自数据库A 的标识符。它实际上代表了它们之间的关系。
  • KV<String,Long>,其中String数据库A 的标识符,Long数据库B 的标识符。此关系表示如何将数据库A 中的String映射到数据库B 中的Long

我想收到带有签名的结果:KV<Long,Long>KV<String,String>的大小完全相同,但是取自KV<String,Long>的值,该值实际上被视为巨大的{{ 1}}。

我可以想象这是许多ETL中一个非常普遍的问题。有人可以提示我从哪里开始吗?

1 个答案:

答案 0 :(得分:1)

给定的标识符有多少关系?

如果答案不是很多,则可以使用CoGroupByKey https://beam.apache.org/documentation/programming-guide/#core-beam-transforms

https://beam.apache.org/documentation/sdks/javadoc/2.5.0/org/apache/beam/sdk/transforms/join/CoGroupByKey.html

CoGroupByKey进行以下转换:

final List<KV<String, String>> emailsList =
    Arrays.asList(
        KV.of("amy", "amy@example.com"),
        KV.of("carl", "carl@example.com"),
        KV.of("julia", "julia@example.com"),
        KV.of("carl", "carl@email.com"));

final List<KV<String, String>> phonesList =
    Arrays.asList(
        KV.of("amy", "111-222-3333"),
        KV.of("james", "222-333-4444"),
        KV.of("amy", "333-444-5555"),
        KV.of("carl", "444-555-6666"));

对此:

final List<String> formattedResults =
    Arrays.asList(
        "amy; ['amy@example.com']; ['111-222-3333', '333-444-5555']",
        "carl; ['carl@email.com', 'carl@example.com']; ['444-555-6666']",
        "james; []; ['222-333-4444']",
        "julia; ['julia@example.com']; []");

您可以执行两次CoGroupByKey,一次对KV<String,String>中的每个字符串执行一次。两次都将其与KV<String,Long>配对。

但是,如果给定的标识符具有大量关系,则默认的CoGroupByKey可能不是很有效,甚至可能用完内存(因为KV<String,String>数组的匹配数目可能会很大)。

听起来您可能需要编写自己的CoGroupByKey / GroupByKey版本来生成值,而不是在数组中建立它们。

如果您查看源代码,就会发现CoGroupByKeyGroupByKey只是PTransform

https://github.com/apache/beam/blob/master/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/join/CoGroupByKey.java