5

Amazon AWSSDKforPHP が遅すぎる

やあ、

Web アプリケーションを S3 に接続するために Amazon AWSSDKforPHP を使用しています。ただし、プロセスまたはサービスへの要求に問題があり、これが遅すぎます。

たとえば、次のコードがあります。

// Iterate an array of user images
foreach($images as $image){
    // Return the Bucket URL for this image
    $urls[] = $s3->get_object_url($bucket, 'users/'.trim($image).'.jpg', '5 minutes');
}

$images がユーザーの写真の配列であると仮定すると、これは (彼の名前が示すように) 5 分間の資格情報を含む写真の URL を持つ $urls という配列を返します。このリクエストは、35 個の画像で少なくとも 6 秒かかりますが、問題ありません。しかし....バケットに写真が存在しない場合、「images/noimage.png」のようなデフォルトの画像をユーザーに割り当てたいと思います。コードは次のとおりです。

// Iterate an array of user images
foreach($images as $image){

    // Check if the object exists in the Bucket
    if($s3->if_object_exists($bucket, 'users/'.trim($image).'.jpg')){
        // Return the Bucket URL for this image
        $urls[] = $s3->get_object_url($bucket, 'users/'.trim($image).'.jpg', '5 minutes');
    } else { 

        // Return the default image
        $urls[] = 'http://www.example.com/images/noimage.png';
    }

}

そして、条件は機能しますが、SLOOOOOW. 「$s3->if_object_exists()」という条件を使用すると、スクリプトは 35 枚の画像で少なくとも 40 秒かかります!

スクリプトを変更し、cURL を使用してリクエストを作成しました。

// Iterate an array of user images
foreach($images as $image){

    // Setup cURL
    $ch = curl_init($s3->get_object_url($bucket, 'users/'.trim($image).'.jpg', '1 minutes') );
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    // Get Just the HTTP response code
    $res = curl_getinfo($ch,CURLINFO_HTTP_CODE);

    if($res == 200){ //the image exists
        $urls[] = $s3->get_object_url($bucket, 'users/'.trim($image).'.jpg', '5 minutes');
    }else{ // The response is 403
        $urls[] = 'http://www.example.com/images/noimage.png';
    }
}

そして、この修正されたスクリプトには 16 ~ 18 秒かかります。これは大きな違いですが、それでもまだ時間がかかります :(.

どうぞ、どんな助けでも大歓迎です。

ありがとうございました。

4

3 に答える 3

1

ループを介してすべての反復で呼び出しif_object_exists()、AWS へのネットワーク リクエストを開始するため、処理が遅くなります。

ユーザー「thatidiotguy」は次のように述べています。

S3 API についてはわかりませんが、バケット内のファイルのリストを要求して、スクリプト内で自分で文字列の照合/検索を行ってもらえますか? PHP スクリプトで、34 個の文字列一致テストにこれほど長くかかる方法はありません。

彼は正しい。

. if_object_exists()_ get_object_list()_ in_array()_

約 10 億パーセントのスピードアップが見られるはずです。ただし、それについて私を引用しないでください。;)

于 2012-10-05T07:19:48.670 に答える
1

チェックの方法を変えてみませんか。画像の場所/バケットをデータベースにローカルに保存すると、このチェックについて心配する必要がなくなりますか?

このようにして、実行している API 呼び出しの数を最小限に抑えます。これは、現在の場合は 35 ですが、時間の経過とともに指数関数的に大きくなる可能性があります。そして、画像ごとに 1 つの呼び出しを行うだけでなく、ほとんどの場合、画像ごとに 2 つの呼び出しを行っています。これは非常に非効率的であり、かなり高速なネットワーク接続に依存しています。

位置データを移動し、画像がローカルに存在するかどうかにかかわらず、この領域でのパフォーマンスの点ではるかに優れた選択肢です。また、このチェックは、事前に結果を保存する場合は、1 回だけ実行する必要があります。

于 2012-09-17T19:37:05.400 に答える
1

S3 からディレクトリ タイプの情報を読み取れるようにしたい場合は、s3fs などを使用してバケットをシステム ドライブとしてマウントするのが最適であると思います。s3fs は、高速化するためにローカル キャッシュを使用して構成することもできます (EC2 を使用している場合は、高速な一時ストレージにキャッシュします)。

これにより、通常の PHP ディレクトリ処理 (DirectoryIterator など) を簡単に行うことができます。

これをいじりたくない場合は、少なくともファイル名データをデータベースに保存し、ファイルが適切な S3 の場所にあることを期待するか、個々の API チェックの結果を何らかの方法でローカルにキャッシュして、作成する必要がないようにします。同様のリクエストごとに API 呼び出し。

于 2012-09-17T20:29:12.497 に答える