在Google的BigQuery中对数据集运行相对简单的UDF时,我遇到了以下错误:
查询执行期间超出资源:UDF内存不足。
在单行或甚至3行上运行UDF,该功能正常工作,并输出大约。每个UDF 150,000行运行到一个单独的表。运行2行并生成输出的示例有job-ID broad-cga-het:bquijob_48bd79dc_155ffe83f48。但是,在5行以上运行UDF时,该函数将失败。在这种情况下,udf失败的示例有job-ID broad-cga-het:bquijob_1248b517_155ffeb2a10。输入表中的所有行都是相同的,因此与我测试的行相比,问题不能是异常大的输入行大小。我在一个10,000行总大小约300 MB的数据集上运行udf,所以ca.每排30Kb。
以下文章解决了这个问题,
BigQuery UDF memory exceeded error on multiple rows but works fine on single row
然而,我尝试实现这里发布的一些可能的解决方案(基于SELECT输入查询中udf的行号对所有变量运行GROUP EACH BY,但这没有帮助),我无法找到在其他地方明确解决这个问题。
我认为垃圾收集在javascript运行的环境中可能无法正常工作,但我不确定如何检查这个问题(bigquery udfs在任何地方都可以创建日志文件吗?)
这是我正在运行的bigquery udf:
bigquery.defineFunction(
'permute',
['obj_nums','num_obj_per_indiv','row_number'], // Names of input columns
[{name: 'obj_pair', type: 'string'}, {name: 'perm_run_id', type: 'integer'}], // Output schema
permute
);
function permute(row, emit) {
var obj_ids = row['obj_nums'].split(",").map(function (x) {
return parseInt(x, 10);
});
var num_obj_per_indiv = row['num_obj_per_indiv'].split(",").map(function (x) {
return parseInt(x, 10);
});
var row_number = row['row_number']
// randomly shuffle objs using Durstenfeld shuffle algorithm
obj_ids = shuffle_objs(obj_ids);
// use fixed number of objs per indiv and draw from shuffled objs
var obj_pair_total_perm_coocur = {};
var perm_cooccur_dict = {};
//num_obj_per_indiv = num_obj_per_indiv.slice(0,3);
for(var index in num_obj_per_indiv) {
var obj_count = num_obj_per_indiv[index]
var perm_run_objs = [];
for(var j = 0; j < obj_count; j++) {
perm_run_objs.push(obj_ids.pop());
}
perm_run_objs = new Set(perm_run_objs);
perm_run_objs = Array.from(perm_run_objs)
while(perm_run_objs.length > 1) {
current_obj = perm_run_objs.pop()
for(var pair_obj_ind in perm_run_objs) {
var pair_obj = perm_run_objs[pair_obj_ind]
// console.log({"obj_pair":[current_obj,pair_obj].sort().join("_"),"perm_run_id":row_number})
emit({"obj_pair":[current_obj,pair_obj].sort().join("_"),"perm_run_id":row_number});
}
}
}
}
/**
* Randomize array element order in-place.
* Using Durstenfeld shuffle algorithm.
*/
function shuffle_objs(obj_array) {
for (var i = obj_array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = obj_array[i];
obj_array[i] = obj_array[j];
obj_array[j] = temp;
}
return obj_array;
}
对这个问题的任何帮助都是巨大的!谢谢。