2015-10-20 1 views
2

J'essaie de télécharger un fichier .tar.gz de 9 Go que j'ai créé à l'aide de l'assistant CPanel Backup. Ce fichier doit être stocké tel quel sur Amazon Glacier mais Amazon Glacier a une limite de téléchargement de 4 Go.Comment télécharger un fichier .tar.gz dans Amazon Glacier en utilisant PHP et aws-SDK v2 avec le téléchargement en plusieurs parties?

Existe-t-il un moyen de faire cela en utilisant PHP, aws-SDK v2 et uploadMultipartPart?

Ceci est le code que je suis arrivé à ce jour:

<?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); 
?> 
+0

Geez, pourquoi n'y a-t-il aucun exemple de ceci n'importe où? –

Répondre

0

Remarque partSize a besoin d'être n * 1024 * 1024, où n est une puissance de 2. Vous utilisez 104.857.600 = 100 * 1024 * 1024 Votre n est un nombre pair, pas une puissance de deux. http://docs.aws.amazon.com/amazonglacier/latest/dev/api-multipart-initiate-upload.html

Je n'ai pas de réponse complète, mais vous pouvez spécifier quelle erreur vous obtenez. Également d'après les docs: "La taille minimale autorisée est de 1 Mo, et le maximum est de 4 Go (4096 Mo)." En d'autres termes, n> = 1, n < = 4096, et n est une puissance de 2. Alors, quel est le bon numéro à utiliser? Je pense que l'idée est d'utiliser un plus petit n si vous avez des problèmes, sous réserve de ces contraintes:

  • Vous payez par pièce: 0,050 $ par 1000 demandes en US-Est.

  • Le nombre maximal de pièces est de 10 000. Pour votre téléchargement de 9 Go, cela correspond à une taille de pièce de 966367 ~ 0,9 Mo si vous utilisez le nombre maximum de pièces. Donc, 0,9 Mo est la taille de la partie min pour 9 Go. Vous avez raison de vouloir utiliser une taille de pièce plus grande que 1 Mo pour être confortablement dans les limites.

  • Il existe une raison pour ne pas utiliser des tailles de pièces trop grandes. Il a quelque chose à voir avec la mémoire, le processeur et la saturation de votre connexion Internet. Tout ce que je peux vraiment dire, c'est que le logiciel que j'utilise par défaut est de 16 Mo. Voici une discussion des compromis sur ses questions tracker: https://github.com/vsespb/mt-aws-glacier/issues/55

+1

merci de m'avoir fait remarquer que ma taille de pièce était incorrecte. cela semble avoir été le problème. J'ai changé la taille de la pièce à 4 Mo pour réduire la tension qu'elle impose au serveur. J'ai également ajouté un temps d'attente pour chaque partie qui est en train d'être téléchargée en utilisant ceci: set_time_limit (120); mis à jour mon exemple ci-dessus. – w3shivers