2018年5月2日 星期三

用node js與amazon S3同步資料

前言:

最近專案上有需求,需要把專案資料夾底下的某個資料夾與amazon S3的某個資料夾同步,一開始看到有人使用go寫了相關功能,小編就想說javascript都快一統天下了,沒理由辦不到啊!!所以去載了s3的node js sdk來看,發現密密麻麻的......
於是開始尋求比較簡單的做法,無意中發現了s3-sync-aws這個套件最接近我想要的功能,但唯一缺點是無法指定我要cpoy到哪個資料夾下面,所以小編fork了這個專案,再稍微改編一下成了jac-s3-sync-aws,多了一個dest參數可以塞,已達到小編要的效果。

效果:

以下這範例程式碼,可以把專案中./resource/資料夾下的所有資料直接同步到aws bucket/resource/上面(這裡指的同步,其實是增量提交,如果有刪除的檔案,s3上面還會依舊保存,所以如果有大量異動檔案,請記得定時清理s3)

另外如果aws會自動備份,分裂,等動作,同步就會被判斷為不同檔案,所以會全部掃描一次(但只會掃描,不會真的上傳),小編實際上測試用程式同步會比cyberduck速度快上將近一倍,當然實際情況因人因機器而異啦,那廢話不多說,我們就來看程式吧。

var path = require('path')
, level = require('level')
, s3sync = require('jac-s3-sync-aws')
, readdirp = require('readdirp')
require('dotenv').config()

var db = level(path.join(__dirname, '../dist', 'cache'))

var files = readdirp({
root: './resource', // 要上傳的資料夾
directoryFilter: ['!.git', '!cache'] // 忽略的資料夾
})

var bucket = 'bucket',
index = 0

var uploader = s3sync(db, {
key: process.env.AWS_ACCESS_KEY,
secret: process.env.AWS_SECRET_KEY,
bucket: bucket, // bucket
dest: 'resource', // 只掉的資料夾
concurrency: 100 // 同時上除檔案數
}).on('data', function (file) {
if (file.fresh) { // 資料比對有異動才執行
console.log(`${file.fullPath}\n->${file.url}\nindex:${index++}\n`)
}
})

files.pipe(uploader)