1

mongodb を使用して php で Web アプリケーションをコーディングしていますが、非常に大きなファイル (1gb) を gridfs で保存したいと考えています。

2 つの問題があります。最初にタイムアウトが発生し、MongoGridFS クラスのカーソル タイムアウトを設定する方法がわかりません。

  <?php
  //[...]
  $con = new Mongo();
  $db = $con->selectDB($conf['base']);
  $grid = $db->getGridFS();

  $file_id = $grid->storeFile($_POST['projectfile'], 
                  array('metadata' => array('type' => 'release', 
                  'version' => $query['files'][$time]['version'], 
                  'mime' => mime_content_type($_POST['projectfile']),
                  'filename' => file_name($projectname).'-'.file_name($query['files'][$time]['version']).'.'
                  .getvalue(pathinfo($_POST['projectfile']), 'extension'))), array( 'safe' => false ));
  //[...]
  ?>

次に、リクエストをバックグラウンドで実行できたのでしょうか。このクエリでファイルを保存すると、実行がブロックされ、タイムアウトによりエラー 500 が発生します

PHP 致命的なエラー:「ファイルを保存できませんでした: カーソルがタイムアウトしました (タイムアウト: 30000、残り時間: 0:0、ステータス: 0)」というメッセージを含む例外「MongoGridFSException」がキャッチされませんでした

4

2 に答える 2

0

Gridfsクエリは、デフォルトでは「安全」ではありませんが、ドライバー内の単一のクエリではありません。この関数は、ドライバー内で複数のクエリを実行する必要があります(1つは行を格納し、fs.filesもう1つはを分割しますfs.chunks)。これは、タイムアウトが情報のさらなるバッチを処理するために必要なときに発生する可能性が最も高いことを意味します。タイムアウトはfind、MongoDBではなくPHPのタイムアウトに関連している可能性があります。

これをバックグラウンドで使用する最も簡単な方法は、cronjobを呼び出すか、別のサービスへのメッセージキューを使用して「ジョブ」を作成することです。

タイムアウトについては、残念ながら、(あなたの側の)gridfs関数は、使用されているカーソルに直接アクセスできません(安全に設定する以外)。接続にタイムアウトを設定できますが、これは賢明な考えではないと思います。

ただし、カーソルがタイムアウトしている場合は、findクエリに時間がかかりすぎる可能性があることを意味します。その場合、MongoDBログを監視して、タイムアウトしているものを確認する必要があります。これは、より適切なものが必要な単純なケースである可能性があります。インデックスまたはよりパフォーマンスの高いセットアップ。

@Antonが言ったように、MongoDBの外部に大きなファイルを格納することも検討できますが、必須ではありません。

于 2012-11-01T11:53:09.393 に答える
0

ファイルをいくつかのディレクトリに保存し、そのファイルの場所のみをデータベースに配置する方がよいでしょうか? かなり速くなります。

于 2012-11-01T11:11:05.560 に答える