2014-10-10 2 views
0

Я пытаюсь повысить производительность моей программы (и загрузить) до ее пределов. Я получаю около 1000 Мбит при загрузке 256 МБ файлов с использованием интерфейса командной строки aws. Но я застревают около 600 Мбит загрузить со следующей программойAWS S3 производительность с использованием Node.js SDK

if (process.argv.length < 7) { 
    console.log ("usage: " + process.argv [0] + " " + process.argv[1] + " <config> <region> <bucket> <key> <file>") 
    return -1 
} 

var config = process.argv[2] 
var region = process.argv[3] 
var bucketName = process.argv[4] 
var key = process.argv[5] 
var file = process.argv[6] 

var multipartMap = { Parts: [] } 
var uploadStartTime // = new Date() 
var partSize = 1024 * 1024 * 8   // at least 5MB, specified by amazon 
var partNum 
var multipartParams = { 
    Bucket: bucketName, 
    Key: key, 
    ContentType: "binary", 
    StorageClass: "REDUCED_REDUNDANCY", 
} 
var part = 0 
var maxRetry = 3 

var fs = require ('fs') 
var aws = require ('aws-sdk') 

function upload (bucket, multipart, partParams, trial) { 
    var trial = trial || 1; 
    bucket.uploadPart (partParams, function (err, data) { 
     if (err) { 
      console.log ("failed: ", err) 
      if (trial < maxRetry) { 
       console.log ("retrying part: ", partParams.PartNumber) 
       upload (bucket, multipart, partParams, trial + 1) 
      } else { 
       console.log ("failed: ", err, " unable to upload part: ", partParams.PartNumber) 
      } 
      return; 
     } 
     multipartMap.Parts[this.request.params.PartNumber - 1] = { 
      ETag: data.ETag, 
      PartNumber: Number (this.request.params.PartNumber) 
     } 

     if (--partNum > 0) return; 

     var doneParams = { 
      Bucket: bucketName, 
      Key: key, 
      MultipartUpload: multipartMap, 
      UploadId: multipart.UploadId 
     } 

     console.log ("success") 
     bucket.completeMultipartUpload (doneParams, function (err, data){ 
      if (err) { 
       console.log("An error occurred while completing the multipart upload"); 
       console.log(err); 
      } else { 
       var delta = (new Date() - uploadStartTime)/1000; 
       console.log('Completed upload in', delta, 'seconds'); 
       console.log('Final upload data:', data); 
      } 
     }) 
    }) 
} 

var kickoffTime = new Date() 
aws.config.loadFromPath (config) 
aws.config.region = region 

var bucket = new aws.S3 ({params: {Bucket: bucketName}}) 

console.log ("filename: ", file) 
buffer = fs.readFileSync (file) 
partNum = Math.ceil (buffer.length/partSize) // number of parts 
var totalPart = partNum 

uploadStartTime = new Date() 
bucket.createMultipartUpload (multipartParams, function (err, multipart) { 
    if (err) { 
     console.log ("cannot create multipart upload: ", err) 
     return -1 
    } 

    for (var i = 0; i < buffer.length; i += partSize) { 
     ++part 
     var end = Math.min (i + partSize, buffer.length) 
     var body = buffer.slice (i, end) 
     var partParams = { 
      Body: body, 
      Bucket: bucketName, 
      Key: key, 
      PartNumber: String (part), 
      UploadId: multipart.UploadId, 
      ContentLength: end - i 
     } 

     upload (bucket, multipart, partParams); 
    } 
}) 
var kickoffTimeDelta = (new Date() - kickoffTime)/1000 
console.log ("Kickoff time: ", kickoffTimeDelta) 

Эта программа не будет работать для пустых файлов, но не обращайте внимания на этот случай. Вышеупомянутая программа кодируется со ссылкой на this. Что касается загрузки, скорость также застревает около 600 Мбит/с, вот код if (process.argv.length < 7) { console.log ("usage:" + process.argv [0] + "" + process .argv 1 + "«) возвращение -1 }

var config = process.argv[2] 
var region = process.argv[3] 
var bucketName = process.argv[4] 
var key = process.argv[5] 
var file = process.argv[6] 

var fs = require ('fs') 
var aws = require ('aws-sdk') 
fs.readFile (config, "utf8", function (err, configFile) { 
    if (err) { 
     console.log ("Config file cannot be read: ", err) 
     return -1 
    } 
    aws.config = JSON.parse (configFile) 
    aws.config.region = region 

    var bucket = new aws.S3 ({params: {Bucket: bucketName}}) 

    bucket.createBucket (function() { 
     var data = {Key: key} 
     bucket.getObject (data, function (err, fileData) { 
      if (err) { 
       console.log ("Error downloading data: ", err) 
      } else { 
       fs.writeFile (file, fileData.Body, function (err) { 
        if (err) { 
         console.log ("Error writing data: ", err) 
        } else { 
         console.log ("Successfully downloaded!") 
        } 
       }) 
      } 
     }) 
    }) 
}) 

Я новичок в Node.js и AWS SDK, есть все, что не хватает, чтобы достичь лучшего throughtput? Спасибо

ответ

0

Хмм ... имел уточняющий вопрос, но у меня нет репутации для публикации как таковой.

Сколько запросов в секунду вы видите на обоих концах? Если вы регулярно нажимаете S3 с более чем 100 запросами в секунду, вы получите лучшую производительность, рандомизируя начало вашего имени ключа.

Смотрите эту статью для объяснения и некоторые предложений: http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html

В принципе, если у вас есть куча файлов с ключом (подкаталогом), который начинается с теми же символами, вы можете перегрузить раздел индекса ... поэтому для работы с большим объемом чтения/записи случайные ключевые слова ускоряют производительность.

+0

спасибо, это будет полезный ресурс, но в настоящий момент меня очень беспокоит способ поместить небольшое количество файлов одновременно на S3 для лучшей производительности. В конце концов, это может быть немного бессмысленно, так как система будет масштабировать и вмещать большое количество запросов –