私のアプリケーションには、ユーザーが要求するたびに膨大な量のデータを処理する必要があります。スクリプトはもともとforeachループで編成されていましたが、そのためPHPは毎回タイムアウトしました。私はRedisのキューを使用して移動しましたが、その後私はメモリの問題を抱えていました。スクリプト/キューのメモリが不足しています
mmap() failed: [12] Cannot allocate memory
と
PHP Fatal error: Out of memory (allocated 79691776) (tried to allocate 134217728 bytes)
今、私は一つのプロセスだけを持つようにキューを設定しました。それはうまくいくが、しばらく後に私は再びメモリエラーを取得し始めます。これは私がテストしているところです。ユーザーがそれを使い始めたら、それはちょうど転倒します。
スクリプトを1024MBに割り当てるのは、1回だけ使用しないとメモリが不足するためです。私は、スクリプトを実行してメモリを解放するたびに何かできることがあるかどうか疑問に思っています。変数を設定しないようにしますか?私はこれがどのように役立つかを見ることができません。スクリプトが終了し、キューの作業者によって最初から再び実行されるのを見ています。
私が2GB RAM
で浮浪者のマシン(ホームステッド)を使用していUPDATE:
バックテストでは、我々は、ディスパッチャを実行したときに始まり、10回のリーグと10年を介して実行されます。
public function init($authUserId, $systemId, $token, $league, $year)
{
// ini_set('memory_limit', -1);
ini_set('max_execution_time', 300); //300 seconds = 5 minutes
ini_set('memory_limit', '1024M'); // or you could use 1G
$this->authUserId = $authUserId;
$this->systemId = $systemId;
$this->token = $token;
include(storage_path("app/matches/{$league->key}/{$year}.php"));
$this->leagueResults[$league->key][$year] = collect($this->leagueResults[$league->key][$year]);
//Loops through the data - saves to new array
fwrite($file, serialize($backtest));
:それは非常に多くのことを行いますので、
以下
class BacktestJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $token;
private $league;
private $year;
private $authUserId;
private $systemId;
public $timeout = 10000;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($authUserId, $systemId, $token, $league, $year)
{
$this->token = $token;
$this->league = $league;
$this->year = $year;
$this->authUserId = $authUserId;
$this->systemId = $systemId;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$backtest = new Backtest;
$backtest->init($this->authUserId, $this->systemId, $this->token, $this->league, $this->year);
}
}
は、メインスクリプトのストリップダウンバージョンです:
ディスパッチャクラス:
class Dispatcher
{
use Attributes;
use DataRetriever;
public function runBacktest($token)
{
$authUserId = Auth::user()->id;
$system = System::where('token', $token)->first();
$this->getSystem($authUserId, $system->id);
foreach ($this->leagues as $league) {
foreach ($this->years as $year) {
BacktestJob::dispatch($authUserId, $system->id, $token, $league, $year);
}
}
}
}
ディスパッチャはジョブを実行します
元々、データは50MBのjsonファイルから取得されました。 jsonファイルをハードコードされたPHP配列(ファイルサイズ100MB)に置き換えました。私は新しいファイルが大きいことを知っていますが、json_decodeが処理を高速化しますが、私は行っていないと仮定しました。
私もスクリプトの最後にdb insertを削除しましたが、私の人生を楽にしてくれるので、私はそれを保持することをお勧めします。
PHPスクリプトが終了すると、メモリーは自動的に割り当てが解除されます。 – bassxzero
ここでは、1024MBではなく128MBの制限(134217728バイト)を示しています。どのようなコードを提示することなく、私はどのように助けることができるのか分かりません。 – Devon
ありがとう@bassxzero – user1894292