我在使用新的Google雲存儲庫(appengine-gcs-client)在AppEngine上導出到CSV作業時遇到以下錯誤。我每晚需要輸出約30mb的數據。偶爾,我需要重建整個表格。今天,我不得不重建所有東西(總共約800MB),而我實際上只推出了300MB左右。我查了日誌,發現此異常:谷歌雲存儲(gcs)非最終塊上的錯誤200
/任務/ BigQuery資料/ ExportVisitListByDayTask 了java.lang.RuntimeException:意外的響應代碼200非最終塊:要求:PUT https://storage.googleapis.com/moose-sku-data/visit_day_1372392000000_1372898225040.csv?upload_id=AEnB2UrQ1cw0-Jbt7Kr-S4FD2fA3LkpYoUWrD3ZBkKdTjMq3ICGP4ajvDlo9V-PaKmdTym-zOKVrtVVTrFWp9np4Z7jrFbM-gQ X-goog-API版本:2 內容範圍:字節4718592-4980735/*
262144字節的內容
響應:200 0字節內容 的ETag的: 「f87dbbaf3f7ac56c8b96088e4c1747f6」 的x goog代:1372898591905000 的x goog-metageneration:1 的x goog哈希:CRC32C = 72jksw == 的x goog哈希:MD5 = + H27rz96xWyLlgiOTBdH9g == 有所不同:原產 日期:星期四,2013年7月4日0點43分17秒GMT 服務器:HTTP上傳服務器建立於2013年6月28日13:27:54(1372451274) 內容長度:0 內容類型:text/html;字符集= UTF-8 X-谷歌-緩存控制:遠程取 途經:HTTP/1.1 GWA
at com.google.appengine.tools.cloudstorage.oauth.OauthRawGcsService.put(OauthRawGcsService.java:254)
at com.google.appengine.tools.cloudstorage.oauth.OauthRawGcsService.continueObjectCreation(OauthRawGcsService.java:206)
at com.google.appengine.tools.cloudstorage.GcsOutputChannelImpl$2.run(GcsOutputChannelImpl.java:147)
at com.google.appengine.tools.cloudstorage.GcsOutputChannelImpl$2.run(GcsOutputChannelImpl.java:144)
at com.google.appengine.tools.cloudstorage.RetryHelper.doRetry(RetryHelper.java:78)
at com.google.appengine.tools.cloudstorage.RetryHelper.runWithRetries(RetryHelper.java:123)
at com.google.appengine.tools.cloudstorage.GcsOutputChannelImpl.writeOut(GcsOutputChannelImpl.java:144)
at com.google.appengine.tools.cloudstorage.GcsOutputChannelImpl.waitForOutstandingWrites(GcsOutputChannelImpl.java:186)
at com.moose.task.bigquery.ExportVisitListByDayTask.doPost(ExportVisitListByDayTask.java:196)
的任務是非常簡單的,但我想知道,如果有什麼錯我使用waitForOutstandingWrites()的方式,或者我爲下一個任務運行序列化outputChannel的方式。需要注意的一件事是,每項任務都被分解爲每日組,每組輸出他們自己的個人文件。日間任務計劃同時運行10分鐘以推出所有60天。
在任務中,我創建了一個PrintWriter,如下所示: OutputStream outputStream = Channels.newOutputStream(outputChannel); PrintWriter printWriter = new PrintWriter(outputStream);
然後一次向它寫入數據50行,並調用waitForOutstandingWrites()函數將所有內容推送到GCS。當我達到開放文件限制(〜22秒)時,我將outputChannel放入Memcache中,然後使用數據迭代器的光標重新安排任務。
printWriter.print(outputString.toString());
printWriter.flush();
outputChannel.waitForOutstandingWrites();
這似乎是工作的大部分時間,但我發現這些錯誤,這是建立在GCS〜損壞和不完整的文件。這些電話中有什麼明顯的我做錯了嗎?我每次申請只能有一個頻道向GCS開放嗎?還有其他問題嗎?
欣賞你可以借給你的任何提示!
謝謝!
Evan
啊好吧好極了。我很高興聽到解除限期的問題;但是,可能會有導出任務在10分鐘的請求限制內運行。我應該如何安排這些?什麼是檢查? –
您可以使用Java序列化對寫入器進行序列化,並將其寫入數據存儲區。在後續任務中,您需要確保它是唯一執行的任務。一種方法是更新數據存儲中的一個條目,說明「這個文件正在使用,直到__時間」。如果寫入過程中出現故障,它可以在經過很長時間後再次重試。很顯然,這種方案要求選擇的時間長於在寫入過程中更新條目的頻率。 – tkaitchuck
好的,謝謝,會做。如果我們可以像使用Cursors一樣獲取.toWebSafeString和.fromWebSafeString,那就太棒了,只是爲了簡化開發。 –