2017-01-11 26 views
0

aws-sdkのノードバージョンのmultipartupload機能を使用して600mbの.zipファイルを氷河にアップロードしようとしています。私はバッファとしてファイルを読み込み、awsのドキュメントからスクリプトを使ってアップロードを開始する方法を考え出しました。AWS氷河へのzipファイルのマルチパートアップロードが途中でフリー

スクリプトはファイルの各部分に対してアップロードを開始しますが、それぞれが400エラーで失敗します。以下は

Uploading part 0 = bytes 0-2097151/* 
Uploading part 2097152 = bytes 2097152-4194303/* 
Uploading part 4194304 = bytes 4194304-6291455/* 
Uploading part 6291456 = bytes 6291456-8388607/* 
.... 
Uploading part 591396864 = bytes 591396864-591798963/* 
//stops logging, then a couple seconds later, it starts returning an error message like this for each upload part: 

{ [UnknownError: 400] 
    message: '400', 
    code: 'UnknownError', 
    statusCode: 400, 
    time: Tue Jan 10 2017 20:54:29 GMT-0500 (EST), 
    requestId: 'F16FEDE011D3039A', 
    retryable: false, 
    retryDelay: 91.54012566432357 } 

私は400エラーがどこから来ている上の任意の考えをいただければ幸いです

var AWS = require('aws-sdk'); 
var creds = <path to creds> 
var fs = require('fs'); 
var filePath = <path to file>; 
var encoding = "utf8"; 

var myConfig = new AWS.Config({ 
    accessKeyId: creds.AccessKeyID, 
    secretAccessKey: creds.SecretAccessKey, 
    region: 'us-west-1' 
}); 

var glacier = new AWS.Glacier(myConfig) 

var buffer = fs.readFileSync(filePath); 
// var buffer = new Buffer(2.5 * 1024 * 1024); // 2.5MB buffer 
var partSize = 1024 * 1024; // 1MB chunks, 
var numPartsLeft = Math.ceil(buffer.length/partSize); 
var startTime = new Date(); 

var params = { 
    accountId: '-', 
    vaultName: <vault name> 
    archiveDescription: '100media', 
    partSize: partSize.toString(), 
}; 

// Compute the complete SHA-256 tree hash so we can pass it 
// to completeMultipartUpload request at the end 
var treeHash = glacier.computeChecksums(buffer).treeHash; 

// Initiate the multipart upload 
console.log('Initiating upload to', params.vaultName); 
glacier.initiateMultipartUpload(params, function (mpErr, multipart) { 
    if (mpErr) { console.log('Error!', mpErr.stack); return; } 
    console.log("Got upload ID", multipart.uploadId); 

    // Grab each partSize chunk and upload it as a part 
    for (var i = 0; i < buffer.length; i += partSize) { 
     var end = Math.min(i + partSize, buffer.length), 
      partParams = { 
       vaultName: params.vaultName, 
       uploadId: multipart.uploadId, 
       range: 'bytes ' + i + '-' + (end-1) + '/*', 
       body: buffer.slice(i, end) 
      }; 

     // Send a single part 
     console.log('Uploading part', i, '=', partParams.range); 
     glacier.uploadMultipartPart(partParams, function(multiErr, mData) { 
      if (multiErr) return; 
      console.log("Completed part", this.request.params.range); 
      if (--numPartsLeft > 0) return; // complete only when all parts uploaded 

      var doneParams = { 
       vaultName: params.vaultName, 
       uploadId: multipart.uploadId, 
       archiveSize: buffer.length.toString(), 
       checksum: treeHash // the computed tree hash 
      }; 

      console.log("Completing upload..."); 
      glacier.completeMultipartUpload(doneParams, function(err, data) { 
       if (err) { 
        console.log("An error occurred while uploading the archive"); 
        console.log(err); 
       } else { 
        var delta = (new Date() - startTime)/1000; 
        console.log('Completed upload in', delta, 'seconds'); 
        console.log('Archive ID:', data.archiveId); 
        console.log('Checksum: ', data.checksum); 
       } 
      }); 
     }); 
    } 
}); 

を使用していアップロードスクリプトです!私はバッファやバイナリのデータで作業していないので、私はこれのフォーマットを乱すかもしれません。他の容疑者は、私が氷河の要求やparamsを間違ってフォーマットしているだけです。

+0

私はJSの達人ではありませんが、あなたは 'for'ループでこれらの部分をすべて非同期で開始しているように見え、すぐにアップロードを完了しようとしています。最後の部分は完了です...しかし、他の部分が実際に終了しているという保証はありません。また、少なくとも600 MBのバッファが割り当てられ、300の並列HTTPリクエストが実行されていることを意味します。エラーが発生しましたが、これは少し不安定なようです。最初は小さいファイルですか? –

+0

多くの意味があります。私はそれを再考させてください – Andrew

答えて

0

ここでは、一度に複数のアップロードを試みるスクリプトを作成しました。

var minm = require('minimist'); 

var argv = require('minimist')(process.argv.slice(2)); 
var AWS = require('aws-sdk'); 
var creds = <path to local json creds> 
var fs = require('fs'); 
var encoding = "utf8"; 
var partSize = 1024 * 1024; // 1MB chunks, 
var startTime = new Date(); 
var byteIncrementer = 0; 
var MBcounter = 0; 
var multipart; 

//move these out to args 
var filePath = argv.filepath; 
var vaultName = argv.vaultname 
var archiveDescription = argv.description 

if (!filePath) { 
    throw "ERROR: must pass file path via --filepath <filepath>" 
} 

if (!archiveDescription) { 
    throw "ERROR: must pass description path via --description <description>" 
} 

var myConfig = new AWS.Config({ 
    accessKeyId: creds.AccessKeyID, 
    secretAccessKey: creds.SecretAccessKey, 
    region: <region> 
}); 
var params = { 
    accountId: '-', 
    vaultName: vaultName, 
    archiveDescription: archiveDescription, 
    partSize: partSize.toString(), 
}; 

var buffer = fs.readFileSync(filePath); 
var numPartsLeft = Math.ceil(buffer.length/partSize); 
var glacier = new AWS.Glacier(myConfig) 
var treeHash = glacier.computeChecksums(buffer).treeHash; 

new Promise(function (resolve, reject) { 
    glacier.initiateMultipartUpload(params, function (mpErr, multi) { 
     if (mpErr) { console.log('Error!', mpErr.stack); return; } 
     console.log("Got upload ID", multi.uploadId); 
     multipart = multi 
     resolve(); 
    }); 
}).then(function() { 
    console.log("total upload size: ", buffer.length); 
    recursivelyUploadPart(byteIncrementer) 
}).catch(function (err) {console.log(err)}); 

function recursivelyUploadPart() { 
    var end = Math.min(byteIncrementer + partSize, buffer.length); 

    var partParams = { 
     accountId: '-', 
     uploadId: multipart.uploadId, 
     vaultName: params.vaultName, 
     range: 'bytes ' + byteIncrementer + '-' + (end-1) + '/*', 
     body: buffer.slice(byteIncrementer, end) 
    }; 

    console.log('Uploading part', byteIncrementer, '=', partParams.range); 
    glacier.uploadMultipartPart(partParams, function(multiErr, mData) { 
     if (multiErr) { 
      console.log('part upload error: ', multiErr) 
      console.log('retrying') 
      return recursivelyUploadPart(byteIncrementer) 
     } else { 
      console.log("Completed part", this.request.params.range); 

      if (--numPartsLeft > 0) { 
       MBcounter++; 
       console.log("MB Uploaded: ", MBcounter); 
       byteIncrementer += partSize; 
       console.log('recursing'); 
       return recursivelyUploadPart(byteIncrementer); 
      } else { 
       var doneParams = { 
        vaultName: params.vaultName, 
        uploadId: multipart.uploadId, 
        archiveSize: buffer.length.toString(), 
        checksum: treeHash // the computed tree hash 
       }; 
       console.log("Completing upload..."); 
       glacier.completeMultipartUpload(doneParams, function(err, data) { 
        if (err) { 
         console.log("An error occurred while uploading the archive: ", err); 
        } else { 
         var delta = (new Date() - startTime)/1000; 
         console.log('Completed upload in', delta, 'seconds'); 
         console.log('Archive ID:', data.archiveId); 
         console.log('Checksum: ', data.checksum); 
         console.log("=============================="); 
         console.log('COMPLETED'); 
         console.log("=============================="); 
        } 
       }); 
      } 
     } 
    }); 
}; 

をコメントで述べたように、私はHTTP接続のトンを開放して行うようにしようとしていたように、それが見えます:「アップロードが失敗した場合、同時であることを再加工することを試みるが、それはそのまま動作しますが、再試行でしたすべては同時に動作しません。

関連する問題