我遇到了从Dataflow读取GCP PubSub的问题,当在短时间内发布大量消息时,Dataflow将接收大部分已发送的消息,除了一些消息将丢失,以及其他一些消息会重复。最奇怪的部分是丢失的消息数量与被复制的消息数量完全相同。
在其中一个示例中,我在5秒内发送了4,000条消息,总共收到4,000条消息,但丢失了9条消息,并且正好重复了9条消息。
我确定重复项的方法是通过日志记录。我记录了发布到Pubsub的每条消息以及pubsub生成的消息ID。我也是在Pardo转换中从PubsubIO读取后立即记录消息。
我在Dataflow中从Pubsub读取的方式是使用public interface Options extends GcpOptions, DataflowPipelineOptions {
// PUBSUB URL
@Description("Pubsub URL")
@Default.String("https://pubsub.googleapis.com")
String getPubsubRootUrl();
void setPubsubRootUrl(String value);
// TOPIC
@Description("Topic")
@Default.String("projects/test-project/topics/test_topic")
String getTopic();
void setTopic(String value);
...
}
public static void main(String[] args) {
Options options = PipelineOptionsFactory.fromArgs(args).withValidation().as(Options.class);
options.setStreaming(true);
options.setRunner(DataflowRunner.class);
...
Pipeline pipeline = Pipeline.create(options);
pipeline.apply(PubsubIO
.<String>read()
.topic(options.getTopic())
.withCoder(StringUtf8Coder.of())
)
.apply("Logging data coming out of Pubsub", ParDo
.of(some_logging_transformation)
)
.apply("Saving data into db", ParDo
.of(some_output_transformation)
)
;
pipeline.run().waitUntilFinish();
}
:
message_id
我想知道这是Pubsub或PubsubIO中的已知问题吗?
更新 尝试使用pubsub模拟器进行4000请求,没有丢失数据且没有重复
更新#2:
我进行了一些实验,发现重复的消息正在从遗漏的消息中获取# Custom Exception
class MyError(Exception):
pass
try:
id = int(request.query['id']) #raise ValueError automatically if string cannot be parsed
if id == 'foo': # just to show how to raise a custom Exception
raise MyError
else:
bar()
except ValueError:
exception_message = "Incorrect type of video id was specified."
logger.exception(exception_message)
raven_client.captureException(exception_message)
except MyError:
exception_message = "Incorrect stuff."
logger.exception(exception_message)
raven_client.captureException(exception_message)
。由于问题的方向已经从它的起源转移了很多,我决定发布另一个问题,详细的日志以及我用来发布和接收消息的代码。
链接到新问题:Google Cloud Pubsub Data lost
答案 0 :(得分:1)
我与PubSub团队中的Google人员进行了交谈。它似乎是由Python客户端的线程安全问题引起的。有关Google的回复,请参阅Google Cloud Pubsub Data lost的已接受答案