【问题标题】:How to avoid "ALREADY EXISTS" Mutation while writing Mutation to Spanner Table?如何在将突变写入 Spanner 表时避免“已经存在”突变?
【发布时间】:2020-05-23 07:57:50
【问题描述】:

我有一个特定的用例,我试图在 Spanner 中写入 TB 的数据。我们正在从 DynamoDb 中提取该数据,并将该数据以 bzip2 格式导出到 Google Cloud Storage 中。所以基本上我们在 Spanner 中有主 ID,我们必须忽略 Spanner 中已经存在的行。所以我写了下面的代码来实现同样的效果。

    Mutation.WriteBuilder mutation = Mutation.newInsertBuilder(spannerTable.get());

我已经编写了插入生成器,因为我不想更新 Spanner 中的现有行。使用以下代码通过设置 FailureMode 将行写入 Spanner。

results2.apply("Write Mutations to Spanner",SpannerIO.write()
                .withInstanceId(spannerInstanceId)
                .withDatabaseId(spannerDatabaseId)
                //.withBatchSizeBytes(2000000)
                //.withMaxNumMutations(maxNumMutations)
                .withFailureMode(FailureMode.REPORT_FAILURES)
                ); 

但代码的问题是,由于“已经存在”突变,Dataflow 代码正在重试整个批次。我不能使用 FailureMode.FAST_FAIL,因为它会停止整个管道。我还尝试设置最小 MaxNumMutation 以减小 batch_size(基本上是为了降低 Mutation 批处理中“已经存在”记录的概率),但整体性能受到了阻碍。那么有什么办法可以停止“已经存在”突变记录的重试机制?

【问题讨论】:

    标签: google-cloud-platform amazon-dynamodb google-cloud-dataflow apache-beam google-cloud-spanner


    【解决方案1】:

    您应该使用InsertOrUpdate 突变而不是InsertMutation。在这种情况下,这将完全符合您的期望;如果该行不存在,则插入该行,否则更新它。在您的情况下,更新不会做任何有用的事情,因为没有值应该更改,但它会阻止您的管道中断。

    例子:

        Mutation mutation = Mutation.newInsertOrUpdateBuilder("FOO")
            .set("ID")
            .to(1)
            .set("BAR")
            .to("BAZ")
            .build();
    

    你也可以在Spanner Official Documentation看到前面的。

    【讨论】:

    • 这是我已经指定的,我不想更新现有记录。希望你明白我的意思。
    • @miles212 抱歉,我错过了那个。我以为您遇到了这个问题,因为您的插入正在重试,但如果我理解正确,您的表中存在导入未插入的现有数据,并且您不希望导入更新。那会很棘手。根据数据量,最好先导入到单独的空表,然后再根据过滤掉现有行的查询进行实际导入。
    • 基本上 Spanner 会自动检测是否存在突变,我只是在寻找一种解决方案来避免重试部分以提高写入吞吐量。
    • 尚未实现在 Spanner 中更改数据而不更新现有数据的功能。但是,有一个功能请求可以满足与实现 ifexist 方法相关的用例,可以帮助解决此问题。找到了feature request here
    猜你喜欢
    • 2012-02-21
    • 2012-04-26
    • 2015-08-20
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    相关资源
    最近更新 更多