Google bigquery 运行BigQuery udf时出现通信通道错误

Google bigquery 运行BigQuery udf时出现通信通道错误,google-bigquery,user-defined-functions,Google Bigquery,User Defined Functions,我最近在stack overflow上发布了一个关于在单个表上运行多个UDF()时发生OOM错误的消息。这个错误似乎已经部分修复,但是,在10000行表上运行udf时,我遇到了一个新错误。以下是错误消息: 错误:与子进程通信时出错。消息:“4命令期间通信通道错误”沙盒\u进程\u错误{} 错误位置:用户定义的函数 作业ID:广义cga het:bquijob_32bc01d_1569f11b8a2 删除udf中的emit语句时不会发生错误,因此当udf尝试写回其他表时,必须发生错误 以下是udf

我最近在stack overflow上发布了一个关于在单个表上运行多个UDF()时发生OOM错误的消息。这个错误似乎已经部分修复,但是,在10000行表上运行udf时,我遇到了一个新错误。以下是错误消息:

错误:与子进程通信时出错。消息:“4命令期间通信通道错误”沙盒\u进程\u错误{}

错误位置:用户定义的函数

作业ID:广义cga het:bquijob_32bc01d_1569f11b8a2

删除udf中的emit语句时不会发生错误,因此当udf尝试写回其他表时,必须发生错误

以下是udf本身的副本:

bigquery.defineFunction(
  'permute',
  ['obj_nums','num_obj_per_indiv','row_number'], // Names of input columns
  [{"name": "num_cooccurrences_list","type": "string","mode":"nullable"}], // 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);
  // form dictionary of obj_pairs from obj_ids
  var perm_run_obj_set = new Set(obj_ids);
  var perm_run_obj_unique = Array.from(perm_run_obj_set);
  perm_run_obj_unique.sort();
  var perm_run_obj_pairs_dict = {};
  output = {}
  for (var i = 0; i < perm_run_obj_unique.length - 1; i++) {
    for (var j = i + 1; j < perm_run_obj_unique.length; j++) {
      var obj_pair = [perm_run_obj_unique[i],perm_run_obj_unique[j]].sort().join("_")
      perm_run_obj_pairs_dict[obj_pair] = 0
    }
  }

  // use fixed number of objs per indiv and draw from shuffled objs
  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]
                                  var sorted_pair = [current_obj,pair_obj].sort().join("_")
                                  perm_run_obj_pairs_dict[sorted_pair] += 1
                                  // 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});
                          }
                 }
        }
        // emit({"obj_pair":[current_obj,pair_obj].sort().join("_"),"perm_run_id":row_number});
  // form output dictionary
  num_cooccur_output = ""
  for (var obj_pair in perm_run_obj_pairs_dict) {
    //emit({"obj_pair":obj_pair,"num_cooccur":perm_run_obj_pairs_dict[obj_pair]});
      num_cooccur_output += String(perm_run_obj_pairs_dict[obj_pair])
      num_cooccur_output += ","
  }
  num_cooccur_output = num_cooccur_output.substring(0, num_cooccur_output.length - 1);
  emit({"num_cooccurrences_list":num_cooccur_output});
}

/**
 * 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;
}
bigquery.defineffunction(
“排列”,
['obj_nums','num_obj_per_indiv','row_number'],//输入列的名称
[{“name”:“num\u cooccurrences\u list”,“type”:“string”,“mode”:“nullable”}],//输出模式
排列
);
函数置换(行,发射){
var obj_id=row['obj_nums'].split(“,”).map(函数(x){
返回parseInt(x,10);
});
var num_obj_per_indiv=行['num_obj_per_indiv'].split(“,”).map(函数(x){
返回parseInt(x,10);
});
变量行数=行[“行数”]
//使用Durstenfeld随机洗牌算法随机洗牌OBJ
obj_id=洗牌_objs(obj_id);
//从obj_ID生成obj_对的形式字典
var perm_run_obj_集合=新集合(obj_ID);
var perm_run_obj_unique=Array.from(perm_run_obj_set);
perm_run_obj_unique.sort();
var perm_run_obj_pairs_dict={};
输出={}
对于(变量i=0;i1){
current_obj=perm_run_objs.pop()
用于(永久运行对象中的var对对象索引){
var pair_obj=perm_run_objs[pair_obj_ind]
var sorted_pair=[current_obj,pair_obj].sort().join(“\uj”)
perm\u run\u obj\u pairs\u dict[排序的\u pair]+=1
//console.log({“对象对”:[当前对象对,对象对].sort().join(“,”),“perm\u run\u id”:行号})
//emit({“对象对”:[current_obj,pair_obj].sort().join(“”),“perm_run_id”:行号});
}
}
}
//emit({“对象对”:[current_obj,pair_obj].sort().join(“”),“perm_run_id”:行号});
//表单输出字典
num_cooccur_output=“”
for(perm\U run\U obj\U PAIRES\U dict中的var obj\U对){
//emit({“obj_对”:obj_对,“num_cooccur”:perm_run_obj_对\u dict[obj_对]});
num_cooccur_output+=字符串(perm_run_obj_pairs_dict[obj_pair])
num_cooccur_输出+=“,”
}
num_cooccur_output=num_cooccur_output.substring(0,num_cooccur_output.length-1);
emit({“num_cooccurrences_list”:num_cooccur_output});
}
/**
*随机化数组元素顺序。
*使用Durstenfeld洗牌算法。
*/
函数shuffle_objs(obj_数组){
对于(var i=obj_array.length-1;i>0;i--){
var j=Math.floor(Math.random()*(i+1));
var-temp=obj_数组[i];
obj_数组[i]=obj_数组[j];
obj_阵列[j]=温度;
}
返回obj_数组;
}
任何帮助都将不胜感激

谢谢,,
丹尼尔

这并不是直接回答了你最初的问题,但我不认为你需要一个UDF来进行这种类型的转换。例如,使用(取消选中“显示选项”下的“使用旧SQL”)可以执行数组转换,例如:

WITH T AS (SELECT [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] AS arr)
SELECT
  x,
  new_x
FROM T,
  UNNEST(
    ARRAY(SELECT AS STRUCT
            x,
            arr[OFFSET(CAST(RAND() * (off + 1) AS INT64))] AS new_x
          FROM UNNEST(arr) AS x WITH OFFSET off));
+---+-------+
| x | new_x |
+---+-------+
| 0 | 1     |
| 1 | 2     |
| 2 | 0     |
| 3 | 2     |
| 4 | 4     |
| 5 | 0     |
| 6 | 5     |
| 7 | 4     |
| 8 | 8     |
| 9 | 3     |
+---+-------+
如果有帮助的话,我可以解释更多,但是查询的要点是它使用上面的UDF中的公式将
arr
中的元素随机化。T中的
,UNNEST(…
展开数组中的元素以使它们更易于查看,但我也可以这样做:

WITH T AS (SELECT [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] AS arr)
SELECT
  ARRAY(SELECT AS STRUCT
          x,
          arr[OFFSET(CAST(RAND() * (off + 1) AS INT64))] AS new_x
        FROM UNNEST(arr) AS x WITH OFFSET off)
FROM T;

这将提供一个结构数组作为输出,其中每个
x
都与
new_x

相关联。嗨,Elliot,这是一个很好的建议,我正计划这样做,在查询中执行相同的操作,而不是在udf中。感谢您帮助我开始:)我确实认为这个问题仍然突出了BigQuery udf功能的一个局限性,如果udf也有一个可能的修复方案,那就太好了,但同时我很乐意编写一个查询来做与udf基本相同的事情。嗨,这个问题有什么更新吗?我们正在经历同样的事情;此外,重试也无济于事。我们正在做一系列类似的工作,其中有一半失败了。这些作业总是相同的,因此,整个任务当前被阻止。可能一周前就开始了,代码没有任何变化。(例如,job_8eQwaFaMZyYp6B7lIifBBAOijnQ)。