DynamoDB Capacity Manager (DCM)
What is it?
DCM is a library for automatically managing the capacity of your DynamoDB tables.
It can be run as a script from your workstation, a server, or as a Lambda function.
We recommend running it as a Lambda function on a scheduled basis - typically
every minute.
What does it do?
The basic flow of execution is:
- List the resources (tables and indexes) that it needs to operate on. This list might be all the tables (and their associated indexes):
- in a CloudFormation stack, or
- in your account, or
- a specific list of tables and indexes that you determine and give it
- Find out what the currently-provisioned capacity for these resources is
- Retrieve CloudWatch statistics on the recent consumed capacity and throttle events for these resources
- Then apply a series of rules to take the recent consumption and throttle data to determine if an update should be made
- These rules include running a linear regression on the trajectory of your recent consumption
- Then applying your configuration of minimums, maximums, and other inputs for the rules to create a new target capacity
- Then, if updates are needed, apply those updates
Each rule (including the forecasting) has a number of configuration parameters
that you can provide it to determine how it works. A generic set of base
configuration can be provided, as well as specific configuration for each table
and index, and separate configuration for read capacity vs. write capacity.
In future releases, the library will allow greater configuration of which rules
run, in what order, and allow you to easily add custom rules and forecasters
(other than linear regression).
How do I use it?
Here's an example of how you can write a script that uses this library:
'use strict';
var DCM = require('@silvermine/dynamodb-capacity-manager'),
builder = new DCM.Builder(),
dcm;
builder.findResourcesWith(new DCM.CloudFormationStackResourceLister('your-stack-name'));
builder.excludeTable('SomeTable');
builder.excludeIndex('SomeTable', 'IndexName');
builder.excludeTable('AnotherTable', null, true);
builder.excludeTable('PRD-*');
builder.excludeIndex('SomeTable', '*-Subset');
builder.excludeIndex('*', 'AnotherIndex');
builder.handleReads();
builder.defaultRuleConfig({
AbsoluteMinimumProvisioned: 2,
AbsoluteMaximumProvisioned: 50,
MinimumMinutesBetweenIncreases: 3,
});
builder.defaultRuleConfig(DCM.WRITE, {
AbsoluteMinimumProvisioned: 1,
AbsoluteMaximumProvisioned: 20,
MinimumMinutesBetweenIncreases: 3,
});
builder.ruleConfigForTable('MyMuchBusierThanAverageTable', DCM.READ, {
AbsoluteMaximumProvisioned: 1500,
MinimumMinutesBetweenIncreases: 3,
MinimumDecreaseAmount: [
{ IfGreaterThan: 10, IfLessThanOrEqual: 1000, Percentage: 20 },
],
});
builder.ruleConfigForTable('MyMuchBusierThanAverageTable', DCM.WRITE, {
AbsoluteMaximumProvisioned: 200,
MinimumMinutesBetweenIncreases: 3,
});
builder.ruleConfigForIndex('MyMuchBusierThanAverageTable', 'SomeIndex', DCM.READ, {
AbsoluteMaximumProvisioned: 500,
});
builder.ruleConfigForIndex('MyMuchBusierThanAverageTable', 'SomeIndex', DCM.WRITE, {
AbsoluteMaximumProvisioned: 100,
});
builder.ruleConfigForTable('dev-*', DCM.WRITE, {
AbsoluteMinimumProvisioned: 1,
AbsoluteMaximumProvisioned: 10,
});
builder.ruleConfigForIndex('dev-*', '*', DCM.WRITE, {
AbsoluteMinimumProvisioned: 1,
AbsoluteMaximumProvisioned: 10,
});
dcm = builder.build();
dcm.previewChanges()
.then(function(changes) {
console.log(changes);
})
.done();
How do I configure it?
See src/index.js for the default configuration, and tune those
settings to your liking. You can look in src/boss/rules to see
how the configuration variables are used. In future releases, the documentation
for configuration and usage will be improved. Pull requests welcome!
How do I contribute?
We genuinely appreciate external contributions. See our extensive
documentation on
how to contribute.
NOTE: in the 0.9.0 release, there are a lot of places still missing automated testing,
but these will be getting fixed in subsequent releases. Our goal is 100% unit test
coverage, with good and effective tests (it's easy to hit 100% coverage with junk
tests, so we differentiate). We will not accept pull requests for new features that do
not include unit tests. If you are submitting a pull request to fix a bug, we may accept
it without unit tests (we will certainly write our own for that bug), but we strongly
encourage you to write a unit test exhibiting the bug, commit that, and then commit a fix
in a separate commit. This greatly increases the likelihood that we will accept your pull
request and the speed with which we can process it.
License
This software is released under the MIT license. See the license file for more details.