2016-08-18 2 views
2

단일 테이블에서 여러 udfs를 실행하는 중에 OOM 오류에 대한 스택 오버플로가 최근에 게시되었습니다 (bigquery udf out of memory issues). 이 오류는 부분적으로 수정 된 것으로 보이지만 10,000 행 테이블에서 udf를 실행할 때 새로운 오류가 발생합니다. 다음은 오류 메시지입니다.BigQuery udf를 실행할 때 통신 채널 오류가 발생했습니다.

오류 : 하위 프로세스와 통신하는 동안 오류가 발생했습니다. 메시지 : "4 명령 중 통신 채널 오류"sandbox_process_error {}

오류 위치 : 사용자 정의 함수

작업 ID : 광범위한 CGA-HET : bquijob_32bc01d_1569f11b8a2 오류하지 않는

udf에서 emit 문을 제거 할 때 발생하므로 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; 
} 

: 여기

는 UDF 자신의 복사본입니다!

는 다니엘이 직접 원래의 질문에 대답하지 않는 것이

+0

안녕하세요,이 호에 대한 업데이트는 있습니까? 우리는 같은 것을 경험하고 있습니다. 또한 재 시도가 도움이되지 않습니다. 우리는 비슷한 일자리를 찾고 있으며 그 중 절반은 실패합니다. 이들은 항상 동일한 작업이며 그 결과로 전체 작업이 현재 차단됩니다. 일주일 전에 우리 코드를 수정하지 않고 시작했습니다. (예 : job_8eQwaFaMZyYp6B7lIifBBAOijnQ). –

답변

0

을 주셔서 감사합니다,하지만 난 당신이 변환의 유형에 대한 UDF가 필요하다는 확신 아니에요. 예를 들어, standard SQL를 사용하여 당신과 같은 배열의 변환을 수행 할 수 있습니다 ("를 사용하여 기존 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의 요소를 무작위 화합니다. FROM T, UNNEST(... 그들을 쉽게 볼 수 있도록 배열의 요소를 언 롤링,하지만 난 양자 택일 할 수 있었다 : 이것은 각 xnew_x와 관련된 출력과 같은 구조체의 배열을 제공

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; 

.

+0

Hi Elliot, 이것은 훌륭한 제안이며 udf 대신 쿼리에서 동일한 작업을 수행하기 위해 정확히 계획하고있었습니다. 저와 함께 시작해 주셔서 감사합니다. 이 문제는 여전히 BigQuery udf 기능의 한계점을 강조한 것으로 보입니다. udf에 대한 가능한 수정 사항이 있으면 좋겠지 만 기본적으로 udf와 동일한 작업을 수행하는 쿼리를 작성하게되어 기쁩니다. –

관련 문제