Google Pub / Sub to Dataflow,避免重复记录ID

时间:2017-02-01 16:29:20

标签: google-bigquery google-cloud-platform google-cloud-dataflow google-cloud-pubsub spotify-scio

我正在尝试构建一个Streaming Dataflow Job,它从Pub / Sub读取事件并将它们写入BigQuery。

根据文档,如果使用记录ID,Dataflow可以检测重复的邮件传递(请参阅:https://cloud.google.com/dataflow/model/pubsub-io#using-record-ids

但即使使用此记录ID,我仍然有一些重复 (约0.0002%)。

我错过了什么吗?

编辑:

我使用Spotify Async PubSub Client使用以下snipplet发布消息:

Message
      .builder()
      .data(new String(Base64.encodeBase64(json.getBytes())))
      .attributes("myid", id, "mytimestamp", timestamp.toString)
      .build()

然后我使用Spotify scio从pub / sub读取消息并将其保存到DataFlow:

val input = sc.withName("ReadFromSubscription")
              .pubsubSubscription(subscriptionName, "myid", "mytimestamp")
input
    .withName("FixedWindow")
    .withFixedWindows(windowSize)  // apply windowing logic
    .toWindowed  // convert to WindowedSCollection
    //
    .withName("ParseJson")
    .map { wv =>
      wv.copy(value = TableRow(
        "message_id" -> (Json.parse(wv.value) \ "id").as[String],
        "message" -> wv.value)
      )
    }
    //
    .toSCollection  // convert back to normal SCollection
    //
    .withName("SaveToBigQuery")
    .saveAsBigQuery(bigQueryTable(opts), BQ_SCHEMA, WriteDisposition.WRITE_APPEND)

窗口大小为1分钟。

在注入消息后仅几秒钟我就已经在BigQuery中重复了。

我使用此查询来计算重复项:

SELECT 
   COUNT(message_id) AS TOTAL, 
   COUNT(DISTINCT message_id) AS DISTINCT_TOTAL 
FROM my_dataset.my_table

//returning 273666  273564

这个看着他们:

SELECT *
FROM my_dataset.my_table
WHERE message_id IN (
  SELECT message_id
  FROM my_dataset.my_table
  GROUP BY message_id
  HAVING COUNT(*) > 1
) ORDER BY message_id

//returning for instance:
row|id                                    | processed_at           | processed_at_epoch    
1   00166a5c-9143-3b9e-92c6-aab52601b0be    2017-02-02 14:06:50 UTC 1486044410367   { ...json1... }  
2   00166a5c-9143-3b9e-92c6-aab52601b0be    2017-02-02 14:06:50 UTC 1486044410368   { ...json1... }  
3   00354cc4-4794-3878-8762-f8784187c843    2017-02-02 13:59:33 UTC 1486043973907   { ...json2... }  
4   00354cc4-4794-3878-8762-f8784187c843    2017-02-02 13:59:33 UTC 1486043973741   { ...json2... } 
5   0047284e-0e89-3d57-b04d-ebe4c673cc1a    2017-02-02 14:09:10 UTC 1486044550489   { ...json3... } 
6   0047284e-0e89-3d57-b04d-ebe4c673cc1a    2017-02-02 14:08:52 UTC 1486044532680   { ...json3... }

1 个答案:

答案 0 :(得分:1)

BigQuery documentation states可能会出现重复的罕见情况:

  1. " BigQuery会记住此ID至少一分钟" - 如果Dataflow在重试插入之前需要超过一分钟,则BigQuery可能允许重复插入。您可以查看管道中的日志以确定是否属于这种情况。
  2. "在极少数情况下Google数据中心意外失去连接,可能无法实现自动重复数据删除。"
  3. 您可能需要尝试manually removing duplicates的说明。这也将允许您查看每行使用的insertID以确定问题是在Dataflow端(为同一记录生成不同的insertID)还是在BigQuery端(失败)根据{{​​1}})对行进行重复数据删除。