2016-04-07 24 views
0

私は100万行の配列を持つcsv配列を解析するスクリプトを持っています。バッチ処理ループ

これをクロノスでバッチしたいと思います。たとえば、100.000行ごとにスクリプトを一時停止し、メモリリークなどを防ぐためにもう一度やり直したい。

私のスクリプトは今のようになります: これは関係ないcronjobのバッチ?

5分ごとにこのスクリプトを呼び出すクローンを作成し、foreachループが一時停止されている場所を記憶できますか?いくつかの並べ替えのないポインタが保持されませんので、スクリプトは常に、最初から処理する指定されたコードで

$csv = file_get_contents(CSV); 
$array = array_map("str_getcsv", explode("\n", $csv)); 

$headers = $array[0]; 
$number_of_records = count($array); 
    for ($i = 1; $i < $number_of_records; $i++) { 
     $params['body'][] = [ 
     'index' => [ 
      '_index' => INDEX, 
      '_type' => TYPE, 
      '_id' => $i 
     ] 
     ]; 

     // Set the right keys 
     foreach ($array[$i] as $key => $value) { 
     $array[$i][$headers[$key]] = $value; 
     unset($array[$i][$key]); 
     } 

     // Loop fields 
     $params['body'][] = [ 
     'Inrijdtijd' => $array[$i]['Inrijdtijd'], 
     'Uitrijdtijd' => $array[$i]['Uitrijdtijd'], 
     'Parkeerduur' => $array[$i]['Parkeerduur'], 
     'Betaald' => $array[$i]['Betaald'], 
     'bedrag' => $array[$i]['bedrag'] 
     ]; 

     // Every 1000 documents stop and send the bulk request 
     if ($i % 100000 == 0) { 
     $responses = $client->bulk($params); 

     // erase the old bulk request 
     $params = ['body' => []]; 

     // unset the bulk response when you are done to save memory 
     unset($responses); 
     } 

     // Send the last batch if it exists 
     if (!empty($params['body'])) { 
     $responses = $client->bulk($params); 
     } 
    } 
+0

は '$ array'から来るのでしょうか?もう一度どこかに救われますか?スクリプトを実行できるかどうかの疑問に答える(再開を前提とした場合)ことは、このような要因に大きく依存します。 –

+0

メモリリークを防ぐため、100.000行ごとに停止しないでください。代わりにストリームを利用する必要があります。また、 '$ respond'を使わないでください。あなたは決してそれを使用せず、あなたはそれを割り当てて、それを設定解除します。 – Dencker

答えて

1

私の提案は、CSVファイルを分割し、別のスクリプトが1つずつ(つまり5分ごとに)解析するようにすることです。 (そしてその後にファイルを削除してください)。

$fp = fopen(CSV, 'r'); 

$head = fgets($fp); 

$output = [$head]; 
while (!feof($fp)) { 
    $output[] = fgets($fp); 

    if (count($output) == 10000) { 
     file_put_contents('batches/batch-' . $count . '.csv', implode("\n", $output)); 
     $count++; 

     $output = [$head]; 
    } 
} 

if (count($output) > 1) { 
    file_put_contents('batches/batch-' . $count . '.csv', implode("\n", $output)); 
} 

今、元のスクリプトは、毎回ファイルを処理することができます

$files = array_diff(scandir('batches/'), ['.', '..']); 

if (count($files) > 0) { 
    $file = 'batches/' . $files[0]; 

    // PROCESS FILE 

    unlink($file); 
}