有人可以澄清ReafFromPubSub transform中id_label
的目的是什么吗?
我正在使用BigQuery接收器,据我了解,它的作用类似于BQ Streaming API的insertId
Tabledata: insertAll
每行的唯一ID。 BigQuery使用此属性来尽最大努力检测重复的插入请求。有关更多信息,请参见数据一致性。
但是我没有看到这种预期的行为。
我正在将消息发布到Pub / Sub,每个消息具有相同的属性message_id
值(这是为了测试管道/ BQ重复数据删除行为)
我的管道从酒吧读取如下
beam.io.gcp.pubsub.ReadFromPubSub(topic=TOPIC,
subscription=None,
id_label='message_id'
)
但仍在查询BQ,将插入所有消息。我希望,因为发布的每个消息都具有相同的message_id值,所以BQ应该已经推导了这些消息。
有人可以澄清一下吗? 预先感谢!
此外,我注意到DirectRunner
在使用此属性时会不断抛出错误
NotImplementedError:DirectRunner:PubSub读取不支持id_label
我必须使用DataflowRunner
...这也是预期的吗?
干杯!
UPDATE 1 :移至DataflowRunner,并且管道在ReadFromPubSub()期间似乎遵循id_label
参数。 但是,重复的消息确实会继续偶尔散发到管道中。
我的发布者应用程序每15秒以以下格式(the publisher app code is here)发布消息:
cid = 141&message_id = 2&evt_time = {{DATE_TIME_AT_RUNTIME}}
注意,我也在消息的属性中传递了相同的message_id
值(=“ 2”)(这是为了尝试,通过测试来推断行为)。
message_id
的多条消息被读入管道并发送到接收器。当我停止/重新启动发布者应用程序时,通常会发生这种情况。
cid=141&message_id=2&evt_time=2019-03-17T09:31:15.792653Z
cid=141&message_id=2&evt_time=2019-03-17T09:30:00.767878Z
cid=141&message_id=2&evt_time=2019-03-17T09:28:30.747951Z
cid=141&message_id=2&evt_time=2019-03-17T09:22:30.668764Z
cid=141&message_id=2&evt_time=2019-03-17T09:21:00.646867Z
cid=141&message_id=2&evt_time=2019-03-17T09:19:45.630280Z
cid=141&message_id=2&evt_time=2019-03-17T09:12:05.466953Z
cid=141&message_id=2&evt_time=2019-03-17T09:10:42.956195Z
cid=141&message_id=2&evt_time=2019-03-17T09:01:42.816151Z
答案 0 :(得分:1)
这些是不同的ID。如here所述,发布到某个主题的每条消息都有一个名为messageId
的字段,该字段在该主题内是唯一的。发布/订阅保证at-least-once delivery,因此订阅可以重复(即消息具有相同的messageId
)。数据流具有exactly-once processing语义,因为数据流在从订阅中读取时使用该字段对消息进行重复数据删除。这与接收器无关,接收器不需要是BigQuery。
使用id_label
(或Java SDK中的.withIdAttribute()
),我们可以根据不同的唯一字段(例如订单ID,客户ID等)强制将消息视为重复消息。 。输入源只会读取重复的消息一次,您不会看到它们增加管道中输入元素的数量。请记住,直接运行程序仅用于testing,在检查点,重复数据删除等方面不能提供相同的保证。例如,请参考this comment。这就是为什么您在管道中看到它们的最可能原因,同时也考虑了NotImplementedError
消息,因此建议您转到Dataflow Runner。
另一方面,在best-effort的基础上使用insertId
来避免在BigQuery中重试流插入时出现重复的行。使用BigQueryIO
会创建under the hood,无法手动指定。在您的情况下,如果您的N条消息进入管道,并且N条被写入BigQuery,则它按预期运行。如果必须重试,则该行具有相同的insertId
,因此被丢弃。