PHP + Elasticsearch 2 + прокрутка - проблема с памятью - PullRequest
0 голосов
/ 15 ноября 2018

Может ли кто-нибудь помочь мне решить проблему с ошибкой в ​​нехватке памяти при вызове API-интерфейса прокрутки Elasticsearch? Версия Elastic - 2, версия I PHP - 7.1, и я использую библиотеку Rufflin / Elastica в PHP. Примерно через 15 мил. Сервер элементов умер из-за недостатка памяти. Я не уверен, что такие параметры, как scroll, size и search_type имеют правильные значения. Я сделал это в соответствии с этим руководство для ES2 Сценарий довольно прост:

<?php

error_reporting( E_ALL );
ini_set( 'memory_limit', -1 );
ini_set( 'max_execution_time', -1 );

/** @var \Nette\DI\Container $container */
$container = require( __DIR__ . '/../app/bootstrap.php' );

/** @var MongoConnect $mongo */
$mongo = $container->getService( 'mongo' );
/** @var \MongoDB\Collection $eventsCollection */
$eventsCollection = $mongo->selectCollection( 'WebApp', 'Events' );

/** @var Elastica\Client $elastic */
$elastic = new Elastica\Client();
/** @var Elastica\Index $elasticIndex */
$elasticScrollData = $elastic->getIndex( 'event' )->request( '_search?scroll=7s&amp;search_type=scan', 'POST', ['size' => 1000, 'sort' => '_doc'] )->getData();
$countAll = $elasticScrollData['hits']['total'];

$offset = 0;
saveToMongo( $elasticScrollData, $countAll, $offset, $elastic, $eventsCollection );


function saveToMongo( $scrollData, $countAll, $offset, \Elastica\Client $elastic, \MongoDB\Collection $mongoCollection )
{
    $documents = [];
    foreach ( $scrollData['hits']['hits'] as $item )
    {
        $doc = [];
        foreach ( $item['_source'] as $key => $val )
        {
            if( in_array( $key, ['publishDate', 'generateDate', 'eventDate'] ) )
            {
                $date = stringToDate( $val );
                $doc[$key] = new \MongoDB\BSON\UTCDateTime( $date->format('U') * 1000 );
            }
            else $doc[$key] = $val;
        }

        if( isset( $item['_type'] ) ) $doc['type'] = $item['_type'];
        $doc['oldEsId'] = $item['_id'];

        $documents[] = $doc;

        $offset++;
    }

    try
    {
        $mongoCollection->insertMany( $documents, ['ordered' => FALSE] );
        echo '--- offest ' . ( $offset ) . ' OK' . "\n";
    }
    catch( \Exception $e )
    {
        echo '+++ insert exception: ' . $e->getMessage() . "\n";
    }


    if( $offset < $countAll )
    {
        $scrollData = $elastic->request( '_search/scroll', 'POST', ['scroll' => '7s', 'scroll_id' => $scrollData['_scroll_id']] )->getData();
        saveToMongo( $scrollData, $countAll, $offset, $elastic, $mongoCollection );
    }
}

function stringToDate( $string )
{
    if( preg_match( '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+\+[\d:]+$/', $string ) ) $format = 'Y-m-d\TH:i:s.uT';
    elseif( preg_match( '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+$/', $string ) ) $format = 'Y-m-d\TH:i:s.u';
    elseif ( preg_match( '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+[\d:]+$/',$string ) ) $format = 'Y-m-d\TH:i:sT';
     elseif ( preg_match( '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/', $string ) ) $format = 'Y-m-d\TH:i:s';
    elseif ( preg_match( '/^\d{4}-\d{2}-\d{2}\+[\d:]+$/', $string ) ) $format = 'Y-m-dT';
    elseif ( preg_match( '/^\d{4}-\d{2}-\d{2}$/', $string ) ) $format = 'Y-m-d';

    return DateTime::createFromFormat( $format, $string );
}

Код выдает ошибку VirtualAlloc () не выполнен: [0x000005af] Файл подкачки слишком мал для выполнения этой операции . Я действительно не знаю, что не так ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...