クラウドインフラ構築記

現在AWSの構築支援に携わっております。今注視しているのは、GKE、BigQuery、Google Dataflowなどサービスを展開しているGoolge Cloud Platformです。

MultipartUpload を試してみました。


Amazon S3にAWS SDK for PHP 2からMultipartUploadを試してみました。以下例は、5M単位で分割して送信を行うようになっています。回線負荷も分散が可能になります。createMultipartUpload → uploadParts → completeMultipartUploadで処理が行われます。uploadPartsは分割分処理が走ります。(Amazon S3はメディアファイルの配信には最適。)


require_once("AWSSDKforPHP/aws.phar");

use Aws\Common\Aws;
use Aws\Common\Enum\Region;
use Aws\S3\Enum\CannedAcl;
use Aws\S3\Exception\S3Exception;
use Guzzle\Http\EntityBody;
use Aws\Common\Exception\MultipartUploadException;
use Aws\S3\Model\MultipartUpload\UploadBuilder;

$access_key = 'access key';
$secret_key = 'secret key';
$region = Region::AP_NORTHEAST_1; // Region::AP_NORTHEAST_1 = Tokyo Region
$end_point_url = 'http://str.cloudn-service.com';
$bucket = 'xxxx';

try {
 // S3
 $s3 = Aws::factory(array(
 'key' => $access_key,
 'secret' => $secret_key,
 'region' => $region,
// 'base_url' => $end_point_url,
 ))->get('s3');

 $info = new FInfo(FILEINFO_MIME_TYPE);

// Upload File
 $filename = "sample.mp4";
 $body = EntityBody::factory(fopen($filename, 'r'));
 $filetype = $info->file($filename);
 $key = "test" . time();

$response = $s3->createMultipartUpload(array(
 'Bucket' => $bucket,
 'Key' => $key
));

$uploadId = $response['UploadId'];
echo('createMultipartUpload: Finished with id: ' . $uploadId);

$chunkSize = 5242880;
 $start = 0;
 $part = 0;
 $length = $body->getSize();
 while($start < $length) {
 $end = $start + $chunkSize;
 if($end > $length)
 $end = $length;

 $body->seek($start);
 $body->setSize($end);
 $real_chunk_size = $end - $start;
 var_dump('Sending part #'. $part . ' containing '.$start.' through '. $end . ' of ' . $length);
 $response = $s3->uploadPart(array(
 'Bucket' => $bucket,
 'Key' => $key,
 'Body' => $body->read($real_chunk_size),
 'PartNumber' => (string)$part+1,
 'UploadId' => $uploadId,
 'ContentMD5' => hash_file('md5', $filename)
 ));
 $etag = $response->getPath('ETag');
 $requestId = $response->getPath('RequestId');
 var_dump('Part Received with Etag: '.$etag.' and RequestId: ' .$requestId);
 $part++;
 $start += $chunkSize;
 }

 $parts = $s3->listParts(array(
 'Bucket' => $bucket,
 'Key' => $key,
 'UploadId' => $uploadId,
 ));

 $s3->completeMultipartUpload(array(
 'Bucket' => $bucket,
 'Key' => $key,
 'UploadId' => $uploadId,
 'Parts' => $parts['Parts']
 ));

 var_dump('Done');

} catch (S3Exception $e) {

$s3->abortMultipartUpload(array(
 'Bucket' => $bucket,
 'Key' => $key,
 'UploadId' => $uploadId
 ));

S3互換を歌っているCloudnのObjectStorageへのMultipartUploadを試しているのだが、completeMultipartUploadで例外が発生。

putObjectでは問題なくアップロードが完了するので、MultipartUploadの設定ではと考えれる。

あとは、Browser Based Uploaded Using POST が実現できれば。

コメントは受け付けていません。