배치 API는 내부적으로 어떻게 작동합니까?


19

다른 날 마이그레이션을 사용하여 시간 초과 문제가 발생하여 Batch API 가 내부적으로 어떻게 작동 하는지 궁금해지기 시작했습니다 .

내가 이해하는 방법은 가장 간단한 형태로 값 배열 (예 : nids)과 해당 값에서 작동하는 함수를 전달한다는 것입니다. 그런 다음 배치 API는 완료 될 때까지 각 요청마다 고정 된 수의 해당 값을 처리합니다.

배치가 실행 중일 때 페이지에서 Ajax 요청을 사용하여 배치 작업 진행률 (% 완료 및 메시지)을 표시하는 것 같습니다. 요청이 진행 상황 업데이트를 마칠 때까지 기다렸다가 바로 다음 요청을 시작한다고 가정합니까?

일괄 요청이있는 페이지가 닫히면 일괄 처리가 중지됩니까? 동일한 URL을 다시 열면 다시 시작됩니까? 마이그레이션 모듈이 계속 진행되지만 대기열을 사용하고 있습니까?

답변:


40

이것은 배치가 작동하는 방식입니다 (내 이해에 따라)

1. 초기화

  1. 일괄 처리를 초기화하십시오. JavaScript 사용 가능 여부에 대한 클라이언트 (브라우저) 구성을 기반으로합니다.
  2. JavaScript 가능 클라이언트는 drupal.js에 설정된 'has_js'쿠키로 식별됩니다. 현재 사용자의 브라우저 세션 중에 JavaScript 사용 가능 페이지를 방문하지 않은 경우 비 JavaScript 버전이 리턴됩니다.
  3. 경우 자바 스크립트가 활성화 일괄 사용 아약스 (가) 요청에 걸쳐 살아 연결을 계속 요청합니다.
  4. JavaScript가 활성화되지 않은 경우 Batch는 HTML에서 메타 태그 를 설정 하여 요청 전체에 걸쳐 연결을 유지 하기 위해 정기적으로 새로 고침 간격 을 설정합니다.

(이것은 작업 완료의 진행 상황에서 진행률 표시 줄이 업데이트되는 방식입니다.)

배치 프로세스

  1. 프로세스를 시작하기 위해 Batch는 대기열을 생성 하고 배치 배열에서 정의한 모든 작업 (함수 및 인수) 을 다음과 같이 추가합니다.

    $batch = array (
    'operations' => array(
      array('batch_example_process', array($options1, $options2)),
      array('batch_example_process', array($options3, $options4)),
      ),
    'finished' => 'batch_example_finished',
    'title' => t('Processing Example Batch'),
    'init_message' => t('Example Batch is starting.'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('Example Batch has encountered an error.'),
    'file' => drupal_get_path('module', 'batch_example') . '/batch_example.inc',
    );

    또한 배치 전체에서 고유 한 배치 ID를 할당합니다.

  2. 이제 Batch는 Queue 항목을 하나씩 요청하고 여기에 정의 된 인수로 정의 된 함수를 실행합니다.

  3. 이것은 중요한 부분입니다. 배치 작업을 구현하는 함수 (Operation)는 데이터를 청크하고 PHP의 메모리 한계 인 Time out 을 염두에두고 데이터를 매우 효율적으로 처리해야 합니다 . 그렇게하지 않으면 문제가 생길 수 있습니다.

다른 날 마이그레이션을 사용하여 시간 초과 문제가 발생하여 배치 API가 내부적으로 어떻게 작동하는지 궁금해지기 시작했습니다.

배치 기능

Batch를 구현하는 함수는 다음 사항을 매우 신중하게 취해야합니다.

  • 다음과 같이 처리 할 작업 내 항목 수

    if (!isset($context['sandbox']['progress'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['current_node'] = 0;
    $context['sandbox']['max'] = db_result(db_query('SELECT COUNT(DISTINCT nid) FROM {node}'));
    }
  • 한도 설정과 같이 한 번의 함수 호출에서 처리 할 항목 수 제한

    // For this example, we decide that we can safely process 5 nodes at a time without a timeout.
    $limit = 5;
  • 다음과 같이 사후 처리로 프로세스 업데이트

    // Update our progress information.
        $context['sandbox']['progress']++;
        $context['sandbox']['current_node'] = $node->nid;
        $context['message'] = t('Now processing %node', array('%node' => $node->title));
  • 배치 엔진에 배치 완료 여부를 알리기

    // Inform the batch engine that we are not finished,
    // and provide an estimation of the completion level we reached.
    if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
      $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
     }

위의 포인트의 대부분은 구현 기능에서 누락 된 Drupal의 코어 배치 작업을 처리합니다. 그러나 항상 구현 기능을 정의하는 것이 가장 좋습니다.

배치 완료 콜백

  • 이것은 배치 배열에 정의 될 때 마지막으로 호출 된 콜백입니다.

대답

일괄 요청이있는 페이지가 닫히면 일괄 처리가 중지됩니까? 동일한 URL을 다시 열면 다시 시작됩니까? 마이그레이션 모듈이 계속 진행되지만 대기열을 사용하고 있습니까?

예, 이상적으로 배치를 다시 시작해야하며 위에서 말했듯이 구현 한 기능을 기반으로합니다.

PHP Time out 문제해결 하려면 마이그레이션 모듈에서 제공되는 Drush 배치를 사용하십시오. 그러나 먼저 마이그레이션의 배치 기능을 파고 처리 데이터를 청크하십시오.


1
대단한 연습. 또한 적어도 사용자에게 "초기화"인 것처럼 배치가 처리를 시작한다고 지적하고 싶습니다. 화면. 즉, 설정하는 데 4 초가 걸리고 첫 번째 배치 항목을 처리하는 데 10 초가 걸리면 "초기화"프로세스가 표시됩니다. 이 예에서는 14 초 동안 이것은 초기화되지 않은 첫 번째 화면 메시지가 "n complete"이므로 일부는 처리 된 후에 만 ​​작동하기 때문에 의미가 있습니다. 이것이 틀렸다면, 정정하십시오!
texas-bronius

또한 내 경험에서. 페이지를 떠나도 처리중인 일괄 작업 / 청크는 완료 될 때까지 여전히 리소스를 소비합니다. 더 이상 배치 작업을 시작하지 않지만 현재 작업을 완료합니다.
Elijah Lynn

10

일괄 요청이있는 페이지가 닫히면 일괄 처리가 중지됩니까?

예, 중지됩니다.

동일한 URL을 다시 열면 다시 시작됩니까? 마이그레이션 모듈이 계속 진행되지만 대기열을 사용하고 있습니까?

Dinesh가 말했듯이 구현에 달려 있습니다.

drush를 사용하여 마이그레이션을 실행해야합니다.

Drush는 커맨드 라인에서 실행되며 시간 제한이 없습니다 (특히 PHP의 max_execution_time은 적용되지 않습니다). 따라서 drush를 통해 실행되는 마이그레이션 프로세스를 시작하면 시작되고 완료 될 때까지 계속 실행됩니다.

웹 인터페이스를 통해 프로세스를 실행할 때 PHP max_execution_time (일반적으로 30 초 이상)가 적용됩니다. 따라서 장기 실행 프로세스의 경우 여러 요청에서 프로세스를 분리하는 Batch API를 사용해야합니다. 따라서 마이그레이션 프로세스가 시작되고 25 초 정도 실행 된 후 Batch API가 중지하고 마이그레이션 프로세스가 다시 시작되는 새로운 페이지 요청을 실행하도록합니다 (인피니티).

그렇다면 Drush가 더 나은 이유는 무엇입니까?

더 빠릅니다

Batch API는 페이지 요청을 종료하고 다시 호출하고 마이그레이션 프로세스가 필요한 모든 생성자를 다시 실행해야하며 데이터베이스 연결을 다시 설정하고 쿼리를 다시 실행하는 등 많은 오버 헤드를 발생시킵니다. 그리고 부분 가져 오기의 경우 선택해야합니다. 처음 500 개의 소스 레코드를 가져온 경우 501 번째 레코드를 찾아야합니다. 소스 형식과 그 구성 방식에 따라 확장 가능하거나 확장되지 않을 수 있습니다. SQL 소스와 함께 최고 사용 표시 점을 사용하는 경우 쿼리 자체가 이전 레코드를 제거하고 중단 한 지점에서 바로 시작할 수 있습니다. 그렇지 않은 경우 마이그레이션은 소스 데이터를 스크롤하여 가져 오지 않은 첫 번째 레코드를 찾습니다. 예를 들어 큰 XML 파일을 소스로 사용하면

더 안정적입니다

브라우저를 통해 마이그레이션을 실행하면 데스크탑 및 로컬 인터넷 연결이 실패 지점으로 추가됩니다. Batch API가 다음 페이지 요청으로 이동할 때 네트워크 결함, 브라우저 충돌, 실수로 잘못된 탭 또는 창을 닫으면 마이그레이션이 중단 될 수 있습니다. 돌진 상태에서 실행하면 움직이는 부품이 줄어 듭니다. 데스크탑과 로컬 인터넷 연결을 제거합니다.

더 도움이됩니다

Drush에서 실행할 때 문제가 발생하면 유용한 오류 메시지가 표시됩니다. Batch API를 사용하는 데 실패하는 경우가 많으며 "AJAX HTTP 요청이 비정상적으로 종료되었습니다. 디버깅 정보는 다음과 같습니다. 경로 : / batch? id = 901 & op = do StatusText : ResponseText : ReadyState : 4"입니다.

이에 대한 자세한 내용은 여기를 참조하십시오 .

브라우저 창을 닫아도 배치를 실행하려면 백그라운드 프로세스 모듈을 고려하십시오 . 트릭을 수행 하는 하위 모듈 백그라운드 배치 가 있습니다.

이 모듈은 기존 Batch API를 대신하여 백그라운드 프로세스에서 배치 작업을 실행합니다. 즉, 배치 페이지를 떠나도 작업이 계속되고 나중에 진행률 표시기로 돌아갈 수 있습니다.


와우, 마이그레이션을 위해 마이그레이션을 사용하면 크게 향상되었습니다. 라이브 사이트로 마이그레이션해야하며 시스템에 훨씬 적은 부하를줍니다! 고맙습니다!
uwe

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.