[英]Strategy for loading data into BigQuery and Google cloud Storage from local disk
我在本地磁盤中有2年大小約為300GB的組合數據,這是我從teradata中提取的。 我必須將相同的數據加載到谷歌雲存儲和BigQuery表。
谷歌雲存儲中的最終數據應該以壓縮格式進行日間隔離(每天文件應該是gz格式的單個文件)。 我還必須在日常分區表中加載BigQuery中的數據,即每天的數據應存儲在一個分區中。
我首先將2年的組合數據加載到谷歌存儲。 然后嘗試使用谷歌數據流,通過使用數據流中的分區概念並將其加載到谷歌雲存儲(日常數據流分區與大查詢分區不同)來明智地隔離數據。 但是數據流不允許創建730個分區(2年),因為它達到413請求實體太大 (管道的序列化JSON表示的大小超過允許限制“)。
所以我運行了兩次數據流作業,每年過濾數據。 它過濾了每一年的數據並將其寫入谷歌雲存儲中的單獨文件中,但由於數據流當前無法寫入壓縮文件,因此無法壓縮它。
看到第一種方法失敗,我想到如上所述使用數據流中的分區來過濾1合並數據中的一年數據,並將其直接寫入BigQuery,然后以壓縮格式將其導出到谷歌存儲。 這個過程將重復兩次。 但是在這種方法中,我不能一次寫入超過45天的數據,因為我反復命中java.lang.OutOfMemoryError:Java堆空間問題 。 所以這個開始也失敗了
任何有助於制定日期明智的隔離遷移到壓縮格式的谷歌存儲和BigQuery的策略的幫助會有很大的幫助嗎?
目前,對結果進行分區是生成多個輸出文件/表的最佳方法。 您可能遇到的是每個寫入為上載分配緩沖區的事實,因此如果您有一個分區后跟N個寫入,則有N個緩沖區。
有兩種策略可以完成這項工作。
uploadBufferSizeBytes
在選項GcsOptions 。 請注意,這可能會降低上傳速度,因為需要更頻繁地刷新緩沖區。 PCollection
應用Reshuffle
操作。 這將限制同時運行的並發BigQuery接收器的數量,因此將分配更少的緩沖區。 例如,您可以執行以下操作:
PCollection<Data> allData = ...;
PCollectionList<Data> partitions = allData.apply(Partition.of(...));
// Assuming the partitioning function has produced numDays partitions,
// and those can be mapped back to the day in some meaningful way:
for (int i = 0; i < numDays; i++) {
String outputName = nameFor(i); // compute the output name
partitions.get(i)
.apply("Write_" + outputName, ReshuffleAndWrite(outputName));
}
這使用了這兩個輔助PTransforms:
private static class Reshuffle<T>
extends PTransform<PCollection<T>, PCollection<T>> {
@Override
public PCollection<T> apply(PCollection<T> in) {
return in
.apply("Random Key", WithKeys.of(
new SerializableFunction<T, Integer>() {
@Override
public Integer apply(Data value) {
return ThreadLocalRandom.current().nextInt();
}
}))
.apply("Shuffle", GroupByKey.<Integer, T>create())
.apply("Remove Key", Values.create());
}
}
private static class ReshuffleAndWrite
extends PTransform<PCollection<Data>, PDone> {
private final String outputName;
public ReshuffleAndWrite(String outputName) {
this.outputName = outputName;
}
@Override
public PDone apply(PCollection<Data> in) {
return in
.apply("Reshuffle", new Reshuffle<Data>())
.apply("Write", BigQueryIO.Write.to(tableNameFor(outputName)
.withSchema(schema)
.withWriteDisposition(WriteDisposition.WRITE_TRUNCATE));
}
}
讓我們看看這是否有幫助?
步驟+偽代碼
1 - 將組合數據(300GB)上傳到BigQuery到CombinedData表
2 - 拆分年份(費用1x2x300GB = 600GB)
SELECT * FROM CombinedData WHERE year = year1 -> write to DataY1 table
SELECT * FROM CombinedData WHERE year = year2 -> write to DataY2 table
3 - 拆分為6個月(費用2x2x150GB = 600GB)
SELECT * FROM DataY1 WHERE month in (1,2,3,4,5,6) -> write to DataY1H1 table
SELECT * FROM DataY1 WHERE month in (7,8,9,10,11,12) -> write to DataY1H2 table
SELECT * FROM DataY2 WHERE month in (1,2,3,4,5,6) -> write to DataY2H1 table
SELECT * FROM DataY2 WHERE month in (7,8,9,10,11,12) -> write to DataY2H2 table
4 - 拆分為3個月(費用4x2x75GB = 600GB)
SELECT * FROM DataY1H1 WHERE month in (1,2,3) -> write to DataY1Q1 table
SELECT * FROM DataY1H1 WHERE month in (4,5,6) -> write to DataY1Q2 table
SELECT * FROM DataY1H2 WHERE month in (7,8,9) -> write to DataY1Q3 table
SELECT * FROM DataY1H2 WHERE month in (10,11,12) -> write to DataY1Q4 table
SELECT * FROM DataY2H1 WHERE month in (1,2,3) -> write to DataY2Q1 table
SELECT * FROM DataY2H1 WHERE month in (4,5,6) -> write to DataY2Q2 table
SELECT * FROM DataY2H2 WHERE month in (7,8,9) -> write to DataY2Q3 table
SELECT * FROM DataY2H2 WHERE month in (10,11,12) -> write to DataY2Q4 table
5 - 每個季度拆分為1個月和2個月(成本8x2x37.5GB = 600GB)
SELECT * FROM DataY1Q1 WHERE month = 1 -> write to DataY1M01 table
SELECT * FROM DataY1Q1 WHERE month in (2,3) -> write to DataY1M02-03 table
SELECT * FROM DataY1Q2 WHERE month = 4 -> write to DataY1M04 table
SELECT * FROM DataY1Q2 WHERE month in (5,6) -> write to DataY1M05-06 table
對於剩余的Y(1/2)Q(1-4)表也是如此
6 - 將所有雙月表拆分為單獨的月表(成本8x2x25GB = 400GB)
SELECT * FROM DataY1M002-03 WHERE month = 2 -> write to DataY1M02 table
SELECT * FROM DataY1M002-03 WHERE month = 3 -> write to DataY1M03 table
SELECT * FROM DataY1M005-06 WHERE month = 5 -> write to DataY1M05 table
SELECT * FROM DataY1M005-06 WHERE month = 6 -> write to DataY1M06 table
Y(1/2)M(XX-YY)表的其余部分也是如此
7 - 最后你有24個月度表,現在我希望你面臨的限制將會消失,所以你可以繼續你的計划 - 第二種方法讓我們說 - 進一步拆分日常表
我認為,成本方面這是最優化的方法,最終的查詢成本是
(假設計費等級1)
4x600GB + 400GB = 2800GB = $14
當然不要忘記刪除中間表
注意:我對此計划不滿意 - 但如果將原始文件拆分為BigQuery之外的每日塊不是一個選項 - 這可以幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.