如何使用PHP和带有分段上传的aws-SDK v2将.tar.gz文件上传到Amazon Glacier?

时间:2015-10-20 08:07:50

标签: php amazon-web-services cpanel aws-sdk amazon-glacier

我正在尝试上传使用CPanel备份向导创建的9GB .tar.gz文件。此文件应按原样存储在Amazon Glacier上,但Amazon Glacier的上传限制为4GB。

有没有办法使用PHP,aws-SDK v2和uploadMultipartPart来做到这一点?

这是我到目前为止的代码:

<?php    
require 'aws-autoloader.php';

use Aws\Glacier\GlacierClient;
use Aws\Glacier\Model\MultipartUpload\UploadPartGenerator;

//#####################################################################
//SET AMAZON GLACIER VARIBALES
//#####################################################################
$key = 'XXXXXXXXXXXXXXXXX';
$secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$region = 'us-west-2';
$accountId = 'XXXXXXXXXXXX';
$vaultName = 'XXXXXXXXXXXX';
$partSize = 4 * 1024 * 1024;
$fileLocation = 'path/to/.tar.gz file/';

//#####################################################################
//DECLARE THE AMAZON CLIENT
//#####################################################################
$client = GlacierClient::factory(array(
    'key'    => $key,
    'secret' => $secret,
    'region' => $region,
));

//#####################################################################
//GET ALL FILES INTO AN ARRAY
//#####################################################################
$files = scandir($fileLocation);
$filename = $files[2];

//#####################################################################
// USE HELPERS IN THE SDK TO GET INFORMATION ABOUT EACH OF THE PARTS
//#####################################################################
$archiveData = fopen($fileLocation.$filename, 'r');
$parts = UploadPartGenerator::factory($archiveData, $partSize);

//#####################################################################
// INITIATE THE UPLOAD AND GET THE UPLOAD ID
//#####################################################################
$result = $client->initiateMultipartUpload(array(
    'vaultName' =>$vaultName,
    'partSize'  => $partSize,
));
$uploadId = $result->get('uploadId');

//#####################################################################
// UPLOAD EACH PART INDIVIDUALLY USING DATA FROM THE PART GENERATOR
//#####################################################################
$archiveData = fopen($fileLocation.$filename, 'r');
foreach ($parts as $part) {
    set_time_limit (120);
    fseek($archiveData, $part->getOffset());
    $client->uploadMultipartPart(array(
        'vaultName'     => $vaultName,
        'uploadId'      => $uploadId,
        'body'          => fread($archiveData, $part->getSize()),
        'range'         => $part->getFormattedRange(),
        'checksum'      => $part->getChecksum(),
        'ContentSHA256' => $part->getContentHash(),
    ));
}

//#####################################################################
// COMPLETE THE UPLOAD BY USING DATA AGGREGATED BY THE PART GENERATOR
//#####################################################################
$result = $client->completeMultipartUpload(array(
    'vaultName'   => $vaultName,
    'uploadId'    => $uploadId,
    'archiveSize' => $parts->getArchiveSize(),
    'checksum'    => $parts->getRootChecksum(),
));
$archiveId = $result->get('archiveId');

fclose($archiveData);
?>

1 个答案:

答案 0 :(得分:0)

注意partSize需要为n * 1024 * 1024,其中n是2的幂。您使用的是104857600 = 100 * 1024 * 1024.您的n是偶数,而不是2的幂。 http://docs.aws.amazon.com/amazonglacier/latest/dev/api-multipart-initiate-upload.html

我没有完整的答案,但你可以指定你得到的错误。

同样来自文档:“最小允许部件大小为1 MB,最大为4 GB(4096 MB)。”换句话说,n> = 1,n <= 4096,并且n是2的幂。那么使用什么是好的数字?我认为如果遇到问题,这个想法是使用更小的n,受这些限制:

  • 您支付的费用:美国东部地区每1,000个请求的费用为0.050美元。

  • 最大部件数量:10,000。对于9 GB上传,如果使用最大部件数,则部件尺寸为966367~0.9 MB。所以0.9 MB是9 GB的最小部件尺寸。您希望使用大于1 MB的较大部件,以便在极限范围内舒适地使用。

  • 有理由不使用过大的零件尺寸。它与内存,CPU和饱和互联网连接有关。我真正可以说的是我使用的软件默认为16 MB。以下讨论其问题跟踪器的权衡:https://github.com/vsespb/mt-aws-glacier/issues/55