我将数据作为带有JSON模式的csv格式上传到大查询。我所看到的是加载大查询的时间很长。当负载为DONE时,我从pollJob.getStatistics()获取开始和结束加载时间,并将增量时间计算为(startTime - endTime)/ 1000。然后我看一下加载的字节数。数据来自存储在谷歌云存储中的文件,我在应用引擎中重新处理以进行一些重新格式化。我将字符串转换为字节流,然后加载为负载的内容,如下所示:
public static void uploadFileToBigQuerry(TableSchema tableSchema,String tableData,String datasetId,String tableId,boolean formatIsJson,int waitSeconds,String[] fileIdElements) {
/* Init diagnostic */
String projectId = getProjectId();
if (ReadAndroidRawFile.testMode) {
String s = String.format("My project ID at start of upload to BQ:%s datasetID:%s tableID:%s json:%b \nschema:%s tableData:\n%s\n",
projectId,datasetId,tableId,formatIsJson,tableSchema.toString(),tableData);
log.info(s);
}
else {
String s = String.format("Upload to BQ tableID:%s tableFirst60Char:%s\n",
tableId,tableData.substring(0,60));
log.info(s);
}
/* Setup the data each time */
Dataset dataset = new Dataset();
DatasetReference datasetRef = new DatasetReference();
datasetRef.setProjectId(projectId);
datasetRef.setDatasetId(datasetId);
dataset.setDatasetReference(datasetRef);
try {
bigquery.datasets().insert(projectId, dataset).execute();
} catch (IOException e) {
if (ReadAndroidRawFile.testMode) {
String se = String.format("Exception creating datasetId:%s",e);
log.info(se);
}
}
/* Set destination table */
TableReference destinationTable = new TableReference();
destinationTable.setProjectId(projectId);
destinationTable.setDatasetId(datasetId);
destinationTable.setTableId(tableId);
/* Common setup line */
JobConfigurationLoad jobLoad = new JobConfigurationLoad();
/* Handle input format */
if (formatIsJson) {
jobLoad.setSchema(tableSchema);
jobLoad.setSourceFormat("NEWLINE_DELIMITED_JSON");
jobLoad.setDestinationTable(destinationTable);
jobLoad.setCreateDisposition("CREATE_IF_NEEDED");
jobLoad.setWriteDisposition("WRITE_APPEND");
jobLoad.set("Content-Type", "application/octet-stream");
}
else {
jobLoad.setSchema(tableSchema);
jobLoad.setSourceFormat("CSV");
jobLoad.setDestinationTable(destinationTable);
jobLoad.setCreateDisposition("CREATE_IF_NEEDED");
jobLoad.setWriteDisposition("WRITE_APPEND");
jobLoad.set("Content-Type", "application/octet-stream");
}
/* Setup the job config */
JobConfiguration jobConfig = new JobConfiguration();
jobConfig.setLoad(jobLoad);
JobReference jobRef = new JobReference();
jobRef.setProjectId(projectId);
Job outputJob = new Job();
outputJob.setConfiguration(jobConfig);
outputJob.setJobReference(jobRef);
/* Convert input string into byte stream */
ByteArrayContent contents = new ByteArrayContent("application/octet-stream",tableData.getBytes());
int timesToSleep = 0;
try {
Job job = bigquery.jobs().insert(projectId,outputJob,contents).execute();
if (job == null) {
log.info("Job is null...");
throw new Exception("Job is null");
}
String jobIdNew = job.getId();
//log.info("Job is NOT null...id:");
//s = String.format("job ID:%s jobRefId:%s",jobIdNew,job.getJobReference());
//log.info(s);
while (true) {
try{
Job pollJob = bigquery.jobs().get(jobRef.getProjectId(), job.getJobReference().getJobId()).execute();
String status = pollJob.getStatus().getState();
String errors = "";
String workingDataString = "";
if ((timesToSleep % 10) == 0) {
String statusString = String.format("Job status (%dsec) JobId:%s status:%s\n", timesToSleep, job.getJobReference().getJobId(), status);
log.info(statusString);
}
if (pollJob.getStatus().getState().equals("DONE")) {
status = String.format("Job done, processed %s bytes\n", pollJob.getStatistics().toString()); // getTotalBytesProcessed());
log.info(status); // compute load stats with this string
if ((pollJob.getStatus().getErrors() != null)) {
errors = pollJob.getStatus().getErrors(). toString();
log.info(errors);
}
我得到的表现如下:BYTES /(deltaTime)的中值上传是17 BYTES /秒!是的,字节,而不是千克或大...
更糟糕的是,有时只有几百个字节,只有一行,最多需要5分钟。我通常没有错误,但我认为有了这个性能,我将无法在更多数据到达之前上传每个应用程序。我正在使用后端实例中的任务队列进行处理。经过大约一个小时的处理后,此任务队列会超时。
由于内容方法,这是否表现不佳?
答案 0 :(得分:1)
有几件事:
如果要加载少量数据,最好使用TableData.insertAll()而不是加载作业,这样可以发布数据并立即使用。
加载作业是面向批处理的作业。也就是说,您可以根据需要插入(或多或少)多个,并在有资源时进行处理。有时您创建一个作业,而工作池正在调整大小,因此您必须等待。有时工人池已满。
如果您提供项目&我们可以通过工作ID了解各个工作的表现,看看这些工作花了这么长时间。
并行加载作业流程;也就是说,一旦他们开始执行,他们应该很快,但是开始执行的时间可能需要很长时间。
作业统计信息中有三个时间字段。 createTime,startTime和endTime。
我希望大部分时间都花在创建和开始之间。如果小型工作不是这种情况,那么这意味着某些事情很奇怪,而且工作ID可以帮助诊断问题。