From 629ba4f692ac39aeeb760ce279a74bf8838c83dd Mon Sep 17 00:00:00 2001 From: Davide Ricci Date: Wed, 8 Apr 2020 10:08:05 +0200 Subject: [PATCH] add onDemand capacity to backup and restore functions dynamo-backup: add another property to use `onDemandReadCapacity`, the default value is 25, user need to update it when using function. If table is onDemand will se the new onDemandReadCapacity value (instead of 0) dynamo-restore: when creating the new table user can specify via `onDemandTable` to use onDemand (pay_per_request) mode --- lib/dynamo-backup.js | 35 +++++++++++++++++++---------------- lib/dynamo-restore.js | 16 +++++++++++----- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/lib/dynamo-backup.js b/lib/dynamo-backup.js index a81e469..dbb81ea 100644 --- a/lib/dynamo-backup.js +++ b/lib/dynamo-backup.js @@ -26,6 +26,7 @@ function DynamoBackup(options) { this.awsSecretKey = options.awsSecretKey; this.awsRegion = options.awsRegion; this.debug = Boolean(options.debug); + this.onDemandReadCapacity = options.onDemandReadCapacity || 25; if (this.awsRegion) { params.region = this.awsRegion; @@ -54,21 +55,21 @@ DynamoBackup.prototype.backupTable = function (tableName, backupPath, callback) backupPath = self._getBackupPath(); } - var params = {}; - if (self.awsRegion) { - params.region = self.awsRegion; - } - if (self.awsAccessKey && self.awsSecretKey) { + var params = {}; + if (self.awsRegion) { + params.region = self.awsRegion; + } + if (self.awsAccessKey && self.awsSecretKey) { params.accessKey = self.awsAccessKey; params.secretKey = self.awsSecretKey; } - params.bucket = self.bucket; - params.objectName = path.join(backupPath, tableName + '.json'); - params.stream = stream; - params.debug = self.debug; + params.bucket = self.bucket; + params.objectName = path.join(backupPath, tableName + '.json'); + params.stream = stream; + params.debug = self.debug; - var upload = new Uploader(params); + var upload = new Uploader(params); var startTime = moment.utc(); self.emit('start-backup', tableName, startTime); @@ -87,7 +88,7 @@ DynamoBackup.prototype.backupTable = function (tableName, backupPath, callback) self._copyTable( tableName, - function (items) { + function (items) { //itemsReceived items.forEach(function (item) { if (self.base64Binary) { _.each(item, function (value, key) { @@ -114,7 +115,7 @@ DynamoBackup.prototype.backupTable = function (tableName, backupPath, callback) }); } } - ); + ); }; DynamoBackup.prototype.backupAllTables = function (callback) { @@ -141,7 +142,7 @@ DynamoBackup.prototype.backupAllTables = function (callback) { }) }, callback - ); + ); }); }; @@ -161,7 +162,9 @@ DynamoBackup.prototype._copyTable = function (tableName, itemsReceived, callback var readPercentage = self.readPercentage; var limit = Math.max((data.Table.ProvisionedThroughput.ReadCapacityUnits * readPercentage) | 0, 1); - + if (data.Table.BillingModeSummary.BillingMode === 'PAY_PER_REQUEST') { + limit = self.onDemandReadCapacity; + } self._streamItems(tableName, null, limit, itemsReceived, callback); }); }; @@ -229,8 +232,8 @@ DynamoBackup.prototype._formatForDataPipeline = function (item) { value[dataPipelineValueKey] = v; value[k] = undefined; // for MAps and Lists, recurse until the elements are created with the correct case - if(k === 'M' || k === 'L') { - self._formatForDataPipeline(v); + if (k === 'M' || k === 'L') { + self._formatForDataPipeline(v); } }); }); diff --git a/lib/dynamo-restore.js b/lib/dynamo-restore.js index b341fb8..94bec4c 100755 --- a/lib/dynamo-restore.js +++ b/lib/dynamo-restore.js @@ -24,6 +24,7 @@ function DynamoRestore(options) { options.awsKey = options.awsKey || process.env.AWS_ACCESS_KEY_ID; options.awsSecret = options.awsSecret || process.env.AWS_SECRET_ACCESS_KEY; options.awsRegion = options.awsRegion || process.env.AWS_DEFAULT_REGION || 'ap-southeast-2'; + options.onDemandTable = options.onDemandTable || false; AWS.config.update({ accessKeyId: options.awsKey, @@ -244,12 +245,17 @@ DynamoRestore.prototype._createTable = function(callback) { KeySchema: [{ AttributeName: options.partitionkey, KeyType: 'HASH' - }], - ProvisionedThroughput: { + }], + }; + if (options.onDemandTable) { + params['BillingMode'] = 'PAY_PER_REQUEST'; + } else { + params['ProvisionedThroughput'] = { ReadCapacityUnits: options.readcapacity, WriteCapacityUnits: options.concurrency // Need this high for pumping data, but will reduce it later. } - }; + } + if (options.sortkey) { params.AttributeDefinitions.push({ AttributeName: options.sortkey, @@ -291,8 +297,8 @@ DynamoRestore.prototype._sendBatch = function() { // Prepare var params = { RequestItems: {} }, dynamo = this.dynamodb, - options = this.options; - batch = this.batches.shift(); + options = this.options, + batch = this.batches.shift(); params.RequestItems[options.table] = batch.items; // Send