You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since #22718 our Spotify's Scio based streaming pipelines on Google Cloud Dataflow are failing with the AvroCodec exception while reading data from BigQuery (with TypedRead).
The last released version of Beam that works properly is 2.42.0 and we cannot upgrade some of our pipelines further because of the issue.
We are reading GenericRecords from temporary BigQuery table and apply parseFn function to it to create arbitrary (non-avro) types which is effectively the Case 3 from the table described in the AvroSource.Mode.
it creates its "default" / "backwards compatibility" implementation and uses it in BigQueryIO.read;
this "default" implementation is in fact using the parseFn function (supplied to BigQueryIO.read) to actually return the parsed type from custom DatumReader;
however, it does not (and cannot) propagate the output Coder to the AvroSource used for reading the data;
Dataflow (in the streaming mode) is wrapping the AvroSource in UnboundedReadFromBoundedSource wrapper to use it as UnboundedSource;
on the way it tries to get the output Coder from the underlying AvroSource to use it as CheckpointCoder for checkpointing;
AvroSource does not have a clue about parseFnbeing actually used and it returns the AvroCoder instance which of course cannot encode arbitrary (non-avro) types
The biggest issue I see is that the contract between using parseFn in the process and supplying the output Coderthat AvroSource enforces is broken by moving the responsibility of applying the parseFn into GenericDatumTransformer.
I am thinking about contributing a fix and I am pondering on the following solution:
removal of the BigQueryIO.GenericDatumTransformer
bringing back the parseFn to BigQueryBaseSource hierarchy
simplifying the datumReaderFactory type to AvroSource.DatumReaderFactory<T> and stop applying parseFn in it
adding validation that only one of parseFn or datumReaderFactory is used - I believe that the purpose of custom DatumReader is to actually read SpecificRecords and output them without the need for additional parsing.
What happened?
Since #22718 our Spotify's Scio based streaming pipelines on Google Cloud Dataflow are failing with the
AvroCodecexception while reading data from BigQuery (with TypedRead).The last released version of Beam that works properly is 2.42.0 and we cannot upgrade some of our pipelines further because of the issue.
We are reading
GenericRecordsfrom temporary BigQuery table and applyparseFnfunction to it to create arbitrary (non-avro) types which is effectively the Case 3 from the table described in theAvroSource.Mode.I analysed the issue. It is complex but the gist of it is that:
AvroSource.DatumReaderFactoryimplementation for reading from BigQuery;BigQueryIO.read;parseFnfunction (supplied toBigQueryIO.read) to actually return the parsed type from customDatumReader;Coderto theAvroSourceused for reading the data;AvroSourceinUnboundedReadFromBoundedSourcewrapper to use it asUnboundedSource;Coderfrom the underlyingAvroSourceto use it asCheckpointCoderfor checkpointing;AvroSourcedoes not have a clue aboutparseFnbeing actually used and it returns theAvroCoderinstance which of course cannotencodearbitrary (non-avro) typesThe biggest issue I see is that the contract between using
parseFnin the process and supplying the outputCoderthatAvroSourceenforces is broken by moving the responsibility of applying theparseFnintoGenericDatumTransformer.I am thinking about contributing a fix and I am pondering on the following solution:
BigQueryIO.GenericDatumTransformerparseFntoBigQueryBaseSourcehierarchydatumReaderFactorytype toAvroSource.DatumReaderFactory<T>and stop applyingparseFnin itparseFnordatumReaderFactoryis used - I believe that the purpose of customDatumReaderis to actually readSpecificRecords and output them without the need for additional parsing.AvroSources accordingly to which param was actually provided inBigQuerySourceBase.createSourcesThis will of course add more complexity to the already complex process but will keep the backwards compatibility in more scenarios.
CC: @steveniemitz @kkdoon
Issue Priority
Priority: 1 (data loss / total loss of function)
Issue Components