【发布时间】:2017-12-31 11:04:00
【问题描述】:
我的函数每小时调用 15 次(每 4 分钟一次),并通过 startQuery 运行查询。大约 30 分钟后随机发生“无效凭据”错误。它发生得越来越频繁,直到所有调用都失败。
此查询从数据集中的表中读取数据,并通过选项destination 和writeDisposition=WRITE_TRUNCATE 将结果保存到位于另一个数据集中的表中。
这两个数据集位于欧盟。
重新部署函数可以暂时消除问题。
对gcloud beta functions describe my-function 的调用表明它使用App Engine 默认服务帐户:my-project-id@appspot.gserviceaccount.com。
以下是错误详情:
ApiError: Invalid Credentials
at Object.parseHttpRespBody (/user_code/node_modules/@google-cloud/bigquery/node_modules/@google-cloud/common/src/util.js:192:30)
at Object.handleResp (/user_code/node_modules/@google-cloud/bigquery/node_modules/@google-cloud/common/src/util.js:132:18)
at /user_code/node_modules/@google-cloud/bigquery/node_modules/@google-cloud/common/src/util.js:465:12
at Request.onResponse [as _callback] (/user_code/node_modules/@google-cloud/bigquery/node_modules/retry-request/index.js:160:7)
at Request.self.callback (/user_code/node_modules/@google-cloud/bigquery/node_modules/request/request.js:188:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/user_code/node_modules/@google-cloud/bigquery/node_modules/request/request.js:1171:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
编辑
代码,剥离:
const bigquery = require('@google-cloud/bigquery')();
const destinationDataset = bigquery.dataset('destinationDataset');
const destinationTable = dataset.table('destinationTable');
exports.aggregate = function aggregate (event) {
const message = event.data;
const attributes = message.attributes;
let job;
let destinationTable;
return Promise.resolve()
.then(() => {
if (attributes.partition == null) {
throw new Error('Partition time not provided. Make sure you have a "partitionTime" attribute in your message');
}
const query = 'SELECT ... FROM sourceTable WHERE _PARTITIONTIME = TIMESTAMP(@partitionTime)'; // The dataset is specified in the job options below
// Query options list: https://cloud.google.com/bigquery/docs/reference/v2/jobs/query
// and: https://googlecloudplatform.github.io/google-cloud-node/#/docs/bigquery/0.9.6/bigquery?method=startQuery
const options = {
destination: destinationTable,
writeDisposition: 'WRITE_TRUNCATE',
query: query,
defaultDataset: { datasetId: 'sourceDataset' },
timeoutMs: 540000, // 9 minutes, same timeout as the Cloud Function
useLegacySql: false,
parameterMode: 'NAMED',
queryParameters: [{
name: 'partitionTime',
parameterType: { type: 'STRING' },
parameterValue: { value: attributes.partition }
}]
};
return bigquery.startQuery(options);
})
.then((results) => {
job = results[0];
console.log(`BigQuery job ${job.id} started, generating data in ${destinationTable.dataset.id}.${destinationTable.id}.`);
return job.promise();
})
.then((results) => {
// Get the job's status
return job.getMetadata();
})
.then((metadata) => {
// Check the job's status for errors
const errors = metadata[0].status.errors;
if (errors && errors.length > 0) {
throw errors;
}
})
// Only if a destination table is given
.then(() => {
console.log(`BigQuery job ${job.id} completed, data generated in ${destinationTable.dataset.id}.${destinationTable.id}.`);
})
.catch((err) => {
console.log(`Job failed for ${inspect(attributes)}: ${inspect(err)}`);
return Promise.reject(err);
});
};
您会注意到在初始化 bigquery 对象时我没有提供任何选项:require('@google-cloud/bigquery')()。
我是否应该创建一个角色为 BigQuery 作业用户 和use the RuntimeConfig API 的服务帐户,以避免将凭据推送到 git 源?
问题仍然是为什么我随机收到此错误。现在查看函数日志,在 CEST 午夜到凌晨 4 点之间的每个调用中都发生了错误,然后在凌晨 5:36 之前的三分之一调用中发生了错误。从那时起(4 小时前)它就没有发生过一次。
编辑 2
这显示了失败调用与成功调用相比的频率。所有错误(绿色)都是“Invalid Credentials”错误。在这 7 天里,绝对没有任何事情发生:没有部署,没有更改配置,没有在 BigQuery 中摆弄。
【问题讨论】:
-
你能给我们看看你的代码示例吗?
-
完成。添加了一个编辑部分。
-
遇到同样的问题;我有一个云函数,它从新的云存储上传(每 1 分钟发生一次)得到通知,并且该函数每 1 分钟调用一次,它只是调用 bigquery 将其加载到表中,这个函数是在两周前运行的直到今天都没有问题 ApiError 在几分钟内随机发生,并非总是如此;这一定是谷歌方面的操作问题
标签: google-bigquery google-cloud-functions google-api-nodejs-client