使用Google.Cloud.BigQuery.V2对BigQuery加载作业的幂等性

时间:2018-05-14 10:07:29

标签: c# google-bigquery google-cloud-storage

您可以使用具有CreateLoadJob方法的Google.Cloud.BigQuery.V2中的BigQueryClient,创建csv加载作业,以便从Google云端存储中的csv文件加载数据。

如何保证使用此API的幂等性,以确保在获得响应之前说网络已经丢失并且您开始重试,您不会最终将相同的数据多次加载到BigQuery中?

API使用示例

    private void LoadCsv(string sourceUri, string tableId, string timePartitionField)
    {
        var tableReference = new TableReference()
        {
            DatasetId = _dataSetId,
            ProjectId = _projectId,
            TableId = tableId
        };

        var options = new CreateLoadJobOptions
        {
            WriteDisposition = WriteDisposition.WriteAppend,
            CreateDisposition = CreateDisposition.CreateNever,
            SkipLeadingRows = 1,
            SourceFormat = FileFormat.Csv,
            TimePartitioning = new TimePartitioning
            {
                Type = _partitionByDayType,
                Field = timePartitionField
            }
        };

        BigQueryJob loadJob = _bigQueryClient.CreateLoadJob(sourceUri: sourceUri,
                                                            destination: tableReference,
                                                            schema: null,
                                                            options: options);

        loadJob.PollUntilCompletedAsync().Wait();
        if (loadJob.Status.Errors == null || !loadJob.Status.Errors.Any())
        {
            //Log success
            return;
        }
        //Log error
    }

2 个答案:

答案 0 :(得分:3)

有两个地方你最终可能会失去回应:

  • 创建作业时
  • 轮询完成时

第一个在没有工作ID的情况下恢复相对棘手;你可以列出项目中的所有工作,并尝试找到一个看起来像你要创建的工作。

但是,C#客户端库会生成作业ID,以便 it 可以重试,或者您可以通过CreateLoadJobOptions指定自己的作业ID。

第二个失败时间要简单得多:保留返回的BigQueryJob,以便在失败时重试轮询。 (例如,您可以存储作业名称,以便即使您的进程在等待它完成时死亡也可以恢复。)

答案 1 :(得分:3)

您可以通过基于例如生成自己的jobid来实现幂等性。您加载的文件位置和目标表。

job_id = 'my_load_job_{}'.format(hashlib.md5(sourceUri+_projectId+_datasetId+tableId).hexdigest())
var options = new CreateLoadJobOptions
        {
            WriteDisposition = WriteDisposition.WriteAppend,
            CreateDisposition = CreateDisposition.CreateNever,
            SkipLeadingRows = 1,
            JobId = job_id, #add this
            SourceFormat = FileFormat.Csv,
            TimePartitioning = new TimePartitioning
            {
                Type = _partitionByDayType,
                Field = timePartitionField
            }
        };

在这种情况下,如果您尝试重新插入相同的job_id,则会出现错误。 如果池化失败,您也可以轻松生成此job_id以进行检查。