I have 2 years of combined data of size around 300GB in my local disk which i have extracted from teradata. I have to load the same data to both google cloud storage and BigQuery table.
The final data in google cloud storage should be day wise segregated in compressed format(each day file should be a single file in gz format). I also have to load the data in BigQuery in a day wise partitioned table i.e. each day's data should be stored in one partition.
I loaded the combined data of 2 years to google storage first. Then tried using google dataflow to day wise segregate data by using the concept of partitioning in dataflow and load it to google cloud storage (FYI dataflow partitioning is different from bigquery partitioning). But dataflow did not allow to create 730 partitions(for 2 years) as it hit the 413 Request Entity Too Large (The size of serialized JSON representation of the pipeline exceeds the allowable limit").
So I ran the dataflow job twice which filtered data for each year. It filtered each one year's data and wrote it into separate files in google cloud storage but it could not compress it as dataflow currently cannot write to compressed files.
Seeing the first approach fail, I thought of filtering 1 the one year's data from the combined data using partioning in dataflow as explained above and writing it directly to BigQuery and then exporting it to google storage in compressed format. This process would have been repeated twice. But in this approach i could not write more than 45 days data at once as I repeatedly hit java.lang.OutOfMemoryError: Java heap space issue. So this startegy also failed
Any help in figuring out a strategy for date wise segregated migration to google storage in compressed format and BigQuery would be of great help?
Let's see if this will help?
Steps + pseudo code
1 - Upload combined data (300GB) to BigQuery to CombinedData table
2 - Split Years (Cost 1x2x300GB = 600GB)
3 - Split to 6 months (Cost 2x2x150GB = 600GB)
4 - Split to 3 months (Cost 4x2x75GB = 600GB)
5 - Split each quarter into 1 and 2 months (Cost 8x2x37.5GB = 600GB)
Same for rest of Y(1/2)Q(1-4) tables
6 - Split all double months tables into separate month table (Cost 8x2x25GB = 400GB)
Same for the rest of Y(1/2)M(XX-YY) tables
7 - Finally you have 24 monthly tables and now I hope limitations you are facing will be gone so you can proceed with your plan – second approach let’s say - to further split on daily tables
I think, cost wise this is most optimal approach and final querying cost is
(assuming billing tier 1)
Of course don’t forget delete intermediate tables
Note: I am not happy with this plan - but if splitting your original file to daily chunks outside of BigQuery is not an option - this can help
Currently, partitioning the results is the best way to produce multiple output files/tables. What you're likely running into is the fact that each write allocates a buffer for the uploads, so if you have a partition followed by N writes, there are N buffers.
There are two strategies for making this work.
uploadBufferSizeBytes
option in GcsOptions. Note that this may slow down the uploads since the buffers will need to be flushed more frequently.Reshuffle
operation to eachPCollection
after the partition. This will limit the number of concurrent BigQuery sinks running simultaneously, so fewer buffers will be allocated.For example, you could do something like:
That makes use of these two helper PTransforms: