質問編集履歴

1 アドバイスをもとに子プロセスでDB接続

noripi

noripi score 28

2016/11/02 13:11  投稿

CakePHPでマルチプロセスがうまく動きません。
CakePHPのコンポーネントで時間のかかる処理をマルチプロセスにしたいのですが、一番最初のfor文のループが2回目になると下記エラーとなってしまいます。
マルチプロセスの処理を入れないと正常に動作します。
また、my.cnfのクエリの最大サイズやタイムアウトなどを変更してみましたがダメでした。
あまりサーバーサイドは得意ではないのでアドバイスお願いします。
《エラー》
```error
Warning Error: Error while sending QUERY packet. PID=27017 in [/home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php, line 468]
Error: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
#0 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php(468): PDOStatement->execute(Array)
#1 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php(434): DboSource->_execute('SELECT `Crawlin...', Array)
#2 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php(671): DboSource->execute('SELECT `Crawlin...', Array, Array)
#3 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php(1120): DboSource->fetchAll('SELECT `Crawlin...', false)
#4 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Model.php(3038): DboSource->read(Object(CrawlingContent), Array)
#5 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Model.php(3010): Model->_readDataSource('all', Array)
#6 /home/scraper/public_html/ec_scraper/Controller/Component/ScrapingComponent.php(1414): Model->find('all', Array)
#7 /home/scraper/public_html/ec_scraper/Controller/Component/ScrapingComponent.php(36): ScrapingComponent->crawler_index_multi()
#8 /home/scraper/public_html/ec_scraper/Console/Command/ScraperShell.php(65): ScrapingComponent->test()
#9 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Console/Shell.php(458): ScraperShell->test()
#10 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Console/ShellDispatcher.php(212): Shell->runCommand('test', Array)
#11 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Console/ShellDispatcher.php(66): ShellDispatcher->dispatch()
#12 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Console/cake.php(54): ShellDispatcher::run(Array)
#13 {main}
```
エラー部分のコード
```php
       //データを分割取得
       for ($page=1; $page <= $totalPage; $page++) {
               $result = $CrawlingContent->find('all', array(
                   'conditions' => $conditions,
                   'recursive' => -1,
                   'limit' => $limit,
                   'page' => $page,
               ));
           if ($limit > ($count - $totalAccess)) {
               $limit = $count - $totalAccess;
           }
           //初期化
           $mkp = $pcount;
           //取得データ
           for ($access=0; $access < $limit;) {
               if ($mkp > ($limit - $access)) {
                   $mkp = $limit - $access;
               }
               for ($i=0; $i < $mkp; $i++) {
                   $pid = pcntl_fork();
                   if( $pid === -1 ) {
                       debug('マルチプロセスのforkに失敗');
                       exit;
                   }elseif($pid === 0){
                       //子プロセス
                       debug($result[$i]['CrawlingContent']['url']);
                       exit;
                   }
                   // 親プロセスの処理
                   $processes[] = $pid;
               }
               foreach($processes as $process) {
                   pcntl_waitpid($process, $status);
               }
               $access = $access + $i;
               $totalAccess = $totalAccess + $i;
           }
}
```  
 
子プロセスでのDB接続を試してみましたがダメでした。  
```php  
       for ($i=0; $i < $pcount; $i++) {  
           $pid = pcntl_fork();  
           if( $pid === -1 ) {  
               debug('マルチプロセスのforkに失敗');  
               exit;  
           }elseif($pid === 0){  
               //子プロセス  
               if ($i===($pcount-1)) {  
                   $endPage = ($endPage - $processPage) + $lastProcessPage;  
               }  
                 
               $page = $startPage;  
 
               for ($page; $page <= $endPage; $page++) {  
                     
                   $result = $CrawlingContent->find('all', array(  
                           'conditions' => $conditions,  
                           'recursive' => -1,  
                           'limit' => $limit,  
                           'page' => $page,  
                       ));  
                   foreach ($result as $resultValue) {  
                       debug($resultValue['CrawlingContent']['url']);  
                   }  
 
               }  
               exit;  
           }  
           // 親プロセスの処理  
           $processes[] = $pid;  
           $startPage = $startPage + $processPage;  
           $endPage = $endPage + $processPage;  
       }  
 
       foreach($processes as $process) {  
           pcntl_waitpid($process, $status);  
       }  
```  
エラーコード  
```ここに言語を入力  
Warning Error: Packets out of order. Expected 1 received 3. Packet size=262144 in [/home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php, line 468]  
 
Warning Error: Packets out of order. Expected 4 received 97. Packet size=7496534 in [/home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php, line 468]  
 
Warning Error: Packets out of order. Expected 1 received 99. Packet size=6621798 in [/home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php, line 468]  
 
Warning Error: PDOStatement::execute(): MySQL server has gone away in [/home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php, line 468]  
 
Warning Error: PDOStatement::execute(): MySQL server has gone away in [/home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php, line 468]  
 
Warning Error: PDOStatement::execute(): MySQL server has gone away in [/home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php, line 468]  
 
Warning Error: PDOStatement::execute(): Error reading result set's header in [/home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php, line 468]  
 
Warning Error: PDOStatement::execute(): Error reading result set's header in [/home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php, line 468]  
 
Error: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away  
#0 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php(468): PDOStatement->execute(Array)  
#1 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php(434): DboSource->_execute('SELECT `Crawlin...', Array)  
#2 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php(671): DboSource->execute('SELECT `Crawlin...', Array, Array)  
#3 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Datasource/DboSource.php(1120): DboSource->fetchAll('SELECT `Crawlin...', false)  
#4 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Model.php(3038): DboSource->read(Object(CrawlingContent), Array)  
#5 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Model/Model.php(3010): Model->_readDataSource('all', Array)  
#6 /home/scraper/public_html/ec_scraper/Controller/Component/ScrapingComponent.php(1434): Model->find('all', Array)  
#7 /home/scraper/public_html/ec_scraper/Controller/Component/ScrapingComponent.php(36): ScrapingComponent->crawler_index_multi()  
#8 /home/scraper/public_html/ec_scraper/Console/Command/ScraperShell.php(65): ScrapingComponent->test()  
#9 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Console/Shell.php(458): ScraperShell->test()  
#10 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Console/ShellDispatcher.php(212): Shell->runCommand('test', Array)  
#11 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Console/ShellDispatcher.php(66): ShellDispatcher->dispatch()  
#12 /home/scraper/public_html/ec_scraper/Vendor/cakephp/cakephp/lib/Cake/Console/cake.php(54): ShellDispatcher::run(Array)  
#13 {main}  
 
```
  • PHP

    26591 questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    7819 questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • CakePHP

    2659 questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る