2015-09-04 43 views
0

在谷歌,计算器和Bing许多搜索我已经做的,但我没有答案找到我的问题。在node.js中的AWS S3 writen备份脚本,使同步备份数百万个文件

如何让我的备份脚本运行同步。我遇到文件夹和子文件夹中的文件太多的问题,因为打开的文件过多(fs.createReadStream)而导致脚本停止。

我希望有人能帮助我。 谢谢。 问候斯文

var AWS = require('aws-sdk') 
     , s3 = new AWS.S3() 
     , fs = require('fs') 
     , wrench = require('wrench') 
     , util = require('util') 

     var smadir = "/Users/myuser/myfolder" 
      , smafiles = wrench.readdirSyncRecursive(smadir) 

      smafiles.forEach (function (file) { 
      var params = {Bucket: 'mybucked', Key: file, Body: fs.createReadStream(smadir + '/' + file)}; 
      var options = {partSize: 10 * 1024 * 1024, queueSize: 1}; 
      s3.upload(params, options, function(err, data) { 
       console.log(err, data); 
      }) 
      }) 
+0

[async.eachSeries(https://github.com/caolan/async) – wayne

回答

1

您可以手动编写用于控制有多少人同时上传这样的代码:

var AWS = require('aws-sdk') 
    , s3 = new AWS.S3() 
    , fs = require('fs') 
    , wrench = require('wrench') 
    , util = require('util') 

var smadir = "/Users/myuser/myfolder" 
    , smafiles = wrench.readdirSyncRecursive(smadir); 

var index = 0, maxAtOnce = 10; 

function uploadNext() { 
    if (index >= smafiles.length) return; 
    var file = smafiles[index++]; 
    var params = {Bucket: 'mybucked', Key: file, Body: fs.createReadStream(smadir + '/' + file)}; 
    var options = {partSize: 10 * 1024 * 1024, queueSize: 1}; 
    s3.upload(params, options, function(err, data) { 
     console.log(err, data); 
     // need to decide what to do here if an error occurred 

     // since one just finished, launch another one 
     uploadNext(); 
    }); 
} 

// now launch the initial set 
for (var i = 0; i < maxAtOnce; i++) { 
    uploadNext(); 
} 

或者,您可以像使用异步或蓝鸟库,具有以下功能:管理同时在飞行中的最大并行操作数。

对于异步库,您可以使用.eachLimit()方法迭代数组,但限制同时在飞行中的最大操作数。

对于蓝鸟承诺函数库,您可以使用Promise.map()并指定并发选项来同时控制最大飞行中操作数。

+0

感谢您的例子。当我的脚本运行在有很多文件的目录中时,出现以下错误: myfile.js events.js:85 throw er; //未处理“错误”事件 ^ 错误:EISDIR,在错误(原生)处读取 我该如何解决这个问题? –

+0

@sm_a - 请参阅http://stackoverflow.com/questions/20417118/using-node-js-i-get-error-eisdir-read。这听起来像是你试图打开一个目录来阅读 - 可能是在扳手代码。 – jfriend00

+0

@sm_a - 在查看扳手代码时,它看起来像'readdirSyncRecursive()'也返回子目录名称,所以您可能在子上调用'fs.createReadStream(smadir +'/'+ file)'' - 将返回EISDIR的目录。在尝试阅读它之前,你必须检查它是否是一个目录。这看起来像是在扳手库中的混乱,因为递归列表的通常点是获取所有文件并且不必检查每个文件以查看它是否是目录。 – jfriend00

0

我已经完成解决方案。在这里我的代码。问候斯文

var AWS = require('aws-sdk') 
    , s3 = new AWS.S3() 
    , fs = require('fs') 
    , wrench = require('wrench') 
    , util = require('util') 

var smadir = "/home/user/folder" 
    , smas3rootdir = "destination_folder" 
    , smafiles = wrench.readdirSyncRecursive(smadir) 

var index = 0, maxAtOnce = 1; 

function uploadNext() { 
    if (index >= smafiles.length) return; 
    var file = smafiles[index++]; 
    var smafoldertocheck = smadir + '/' + file 
    var smaprepare = fs.statSync(smafoldertocheck).isDirectory() 

    if (!smaprepare) { 
     var params = {Bucket: 'mybucked', Key: smas3rootdir + '/' + file, Body: fs.createReadStream(smadir + '/' + file)}; 
     var options = {partSize: 10 * 1024 * 1024, queueSize: 1}; 
     s3.upload(params, options, function(err, data) { 
      console.log(err, data); 
      // need to decide what to do here if an error occurred 

      // since one just finished, launch another one 
      uploadNext(); 
     }) 
    } else { 
     uploadNext(); 
    } 
} 

// now launch the initial set 
for (var i = 0; i < maxAtOnce; i++) { 
    uploadNext(); 
}