Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up read/write auto scaling for mobile-save-for-later-*-articles #96

Merged
merged 5 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 216 additions & 12 deletions cdk/lib/__snapshots__/mobile-save-for-later.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ Object {
"Mappings": Object {
"StageVariables": Object {
"CODE": Object {
"TableReadCapacity": 1,
"TableWriteCapacity": 1,
"TableReadMaxCapacity": 10,
"TableReadMinCapacity": 1,
"TableWriteMaxCapacity": 10,
"TableWriteMinCapacity": 1,
},
"PROD": Object {
"TableReadCapacity": 200,
"TableWriteCapacity": 125,
"TableReadMaxCapacity": 400,
"TableReadMinCapacity": 50,
"TableWriteMaxCapacity": 400,
"TableWriteMinCapacity": 50,
},
},
},
Expand Down Expand Up @@ -572,7 +576,7 @@ Object {
Object {
"Ref": "Stage",
},
"TableReadCapacity",
"TableReadMinCapacity",
],
},
"WriteCapacityUnits": Object {
Expand All @@ -581,7 +585,7 @@ Object {
Object {
"Ref": "Stage",
},
"TableWriteCapacity",
"TableWriteMinCapacity",
],
},
},
Expand Down Expand Up @@ -609,6 +613,104 @@ Object {
},
"Type": "AWS::DynamoDB::Table",
},
"SaveForLaterReadsScalableTarget": Object {
"Properties": Object {
"MaxCapacity": Object {
"Fn::FindInMap": Array [
"StageVariables",
Object {
"Ref": "Stage",
},
"TableReadMaxCapacity",
],
},
"MinCapacity": Object {
"Fn::FindInMap": Array [
"StageVariables",
Object {
"Ref": "Stage",
},
"TableReadMinCapacity",
],
},
"ResourceId": Object {
"Fn::Sub": "table/\${App}-\${Stage}-articles",
},
"RoleARN": Object {
"Fn::Sub": "arn:aws:iam::\${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable",
},
"ScalableDimension": "dynamodb:table:ReadCapacityUnits",
"ServiceNamespace": "dynamodb",
},
"Type": "AWS::ApplicationAutoScaling::ScalableTarget",
},
"SaveForLaterReadsScalingPolicy": Object {
"Properties": Object {
"PolicyName": "SaveForLaterReadsScalingPolicy",
"PolicyType": "TargetTrackingScaling",
"ScalingTargetId": Object {
"Ref": "SaveForLaterReadsScalableTarget",
},
"TargetTrackingScalingPolicyConfiguration": Object {
"PredefinedMetricSpecification": Object {
"PredefinedMetricType": "DynamoDBReadCapacityUtilization",
},
"ScaleInCooldown": 60,
"ScaleOutCooldown": 10,
"TargetValue": 70,
},
},
"Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
},
"SaveForLaterWritesScalableTarget": Object {
"Properties": Object {
"MaxCapacity": Object {
"Fn::FindInMap": Array [
"StageVariables",
Object {
"Ref": "Stage",
},
"TableWriteMaxCapacity",
],
},
"MinCapacity": Object {
"Fn::FindInMap": Array [
"StageVariables",
Object {
"Ref": "Stage",
},
"TableWriteMinCapacity",
],
},
"ResourceId": Object {
"Fn::Sub": "table/\${App}-\${Stage}-articles",
},
"RoleARN": Object {
"Fn::Sub": "arn:aws:iam::\${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable",
},
"ScalableDimension": "dynamodb:table:WriteCapacityUnits",
"ServiceNamespace": "dynamodb",
},
"Type": "AWS::ApplicationAutoScaling::ScalableTarget",
},
"SaveForLaterWritesScalingPolicy": Object {
"Properties": Object {
"PolicyName": "SaveForLaterWritesScalingPolicy",
"PolicyType": "TargetTrackingScaling",
"ScalingTargetId": Object {
"Ref": "SaveForLaterWritesScalableTarget",
},
"TargetTrackingScalingPolicyConfiguration": Object {
"PredefinedMetricSpecification": Object {
"PredefinedMetricType": "DynamoDBWriteCapacityUtilization",
},
"ScaleInCooldown": 60,
"ScaleOutCooldown": 10,
"TargetValue": 70,
},
},
"Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
},
"fetcharticleslambda4E2BF026": Object {
"DependsOn": Array [
"fetcharticleslambdaServiceRoleDefaultPolicy4A85964A",
Expand Down Expand Up @@ -1079,12 +1181,16 @@ Object {
"Mappings": Object {
"StageVariables": Object {
"CODE": Object {
"TableReadCapacity": 1,
"TableWriteCapacity": 1,
"TableReadMaxCapacity": 10,
"TableReadMinCapacity": 1,
"TableWriteMaxCapacity": 10,
"TableWriteMinCapacity": 1,
},
"PROD": Object {
"TableReadCapacity": 200,
"TableWriteCapacity": 125,
"TableReadMaxCapacity": 400,
"TableReadMinCapacity": 50,
"TableWriteMaxCapacity": 400,
"TableWriteMinCapacity": 50,
},
},
},
Expand Down Expand Up @@ -1718,7 +1824,7 @@ Object {
Object {
"Ref": "Stage",
},
"TableReadCapacity",
"TableReadMinCapacity",
],
},
"WriteCapacityUnits": Object {
Expand All @@ -1727,7 +1833,7 @@ Object {
Object {
"Ref": "Stage",
},
"TableWriteCapacity",
"TableWriteMinCapacity",
],
},
},
Expand Down Expand Up @@ -1755,6 +1861,104 @@ Object {
},
"Type": "AWS::DynamoDB::Table",
},
"SaveForLaterReadsScalableTarget": Object {
"Properties": Object {
"MaxCapacity": Object {
"Fn::FindInMap": Array [
"StageVariables",
Object {
"Ref": "Stage",
},
"TableReadMaxCapacity",
],
},
"MinCapacity": Object {
"Fn::FindInMap": Array [
"StageVariables",
Object {
"Ref": "Stage",
},
"TableReadMinCapacity",
],
},
"ResourceId": Object {
"Fn::Sub": "table/\${App}-\${Stage}-articles",
},
"RoleARN": Object {
"Fn::Sub": "arn:aws:iam::\${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable",
},
"ScalableDimension": "dynamodb:table:ReadCapacityUnits",
"ServiceNamespace": "dynamodb",
},
"Type": "AWS::ApplicationAutoScaling::ScalableTarget",
},
"SaveForLaterReadsScalingPolicy": Object {
"Properties": Object {
"PolicyName": "SaveForLaterReadsScalingPolicy",
"PolicyType": "TargetTrackingScaling",
"ScalingTargetId": Object {
"Ref": "SaveForLaterReadsScalableTarget",
},
"TargetTrackingScalingPolicyConfiguration": Object {
"PredefinedMetricSpecification": Object {
"PredefinedMetricType": "DynamoDBReadCapacityUtilization",
},
"ScaleInCooldown": 60,
"ScaleOutCooldown": 10,
"TargetValue": 70,
},
},
"Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
},
"SaveForLaterWritesScalableTarget": Object {
"Properties": Object {
"MaxCapacity": Object {
"Fn::FindInMap": Array [
"StageVariables",
Object {
"Ref": "Stage",
},
"TableWriteMaxCapacity",
],
},
"MinCapacity": Object {
"Fn::FindInMap": Array [
"StageVariables",
Object {
"Ref": "Stage",
},
"TableWriteMinCapacity",
],
},
"ResourceId": Object {
"Fn::Sub": "table/\${App}-\${Stage}-articles",
},
"RoleARN": Object {
"Fn::Sub": "arn:aws:iam::\${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable",
},
"ScalableDimension": "dynamodb:table:WriteCapacityUnits",
"ServiceNamespace": "dynamodb",
},
"Type": "AWS::ApplicationAutoScaling::ScalableTarget",
},
"SaveForLaterWritesScalingPolicy": Object {
"Properties": Object {
"PolicyName": "SaveForLaterWritesScalingPolicy",
"PolicyType": "TargetTrackingScaling",
"ScalingTargetId": Object {
"Ref": "SaveForLaterWritesScalableTarget",
},
"TargetTrackingScalingPolicyConfiguration": Object {
"PredefinedMetricSpecification": Object {
"PredefinedMetricType": "DynamoDBWriteCapacityUtilization",
},
"ScaleInCooldown": 60,
"ScaleOutCooldown": 10,
"TargetValue": 70,
},
},
"Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
},
"fetcharticleslambda4E2BF026": Object {
"DependsOn": Array [
"fetcharticleslambdaServiceRoleDefaultPolicy4A85964A",
Expand Down
96 changes: 71 additions & 25 deletions mobile-save-for-later/conf/cfn.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,3 @@
Resources:
SaveForLaterDynamoTable:
DeletionPolicy: Retain
Type: 'AWS::DynamoDB::Table'
Properties:
KeySchema:
- KeyType: HASH
AttributeName: userId
TableName: !Sub '${App}-${Stage}-articles'
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
ProvisionedThroughput:
WriteCapacityUnits: !FindInMap
- StageVariables
- !Ref Stage
- TableWriteCapacity
ReadCapacityUnits: !FindInMap
- StageVariables
- !Ref Stage
- TableReadCapacity
Description: Implements save for later for mobile
Parameters:
DynamoNotificationTopic:
Expand All @@ -34,11 +13,78 @@ Parameters:
AllowedValues:
- CODE
- PROD

Mappings:
StageVariables:
CODE:
TableReadCapacity: 1
TableWriteCapacity: 1
TableReadMinCapacity: 1
TableReadMaxCapacity: 10
TableWriteMinCapacity: 1
TableWriteMaxCapacity: 10
PROD:
TableReadCapacity: 200
TableWriteCapacity: 125
TableReadMinCapacity: 50
TableReadMaxCapacity: 400
TableWriteMinCapacity: 50
TableWriteMaxCapacity: 400

Resources:
SaveForLaterDynamoTable:
DeletionPolicy: Retain
Type: 'AWS::DynamoDB::Table'
Properties:
KeySchema:
- KeyType: HASH
AttributeName: userId
TableName: !Sub '${App}-${Stage}-articles'
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
ProvisionedThroughput:
WriteCapacityUnits: !FindInMap [ StageVariables, !Ref Stage, TableWriteMinCapacity ] # Initial value, autoscaled with below resources
ReadCapacityUnits: !FindInMap [ StageVariables, !Ref Stage, TableReadMinCapacity ] # Initial value, autoscaled with below resources

SaveForLaterWritesScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: !FindInMap [StageVariables, !Ref Stage, TableWriteMaxCapacity]
MinCapacity: !FindInMap [StageVariables, !Ref Stage, TableWriteMinCapacity]
ResourceId: !Sub "table/${App}-${Stage}-articles"
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable
ScalableDimension: dynamodb:table:WriteCapacityUnits
ServiceNamespace: dynamodb

SaveForLaterWritesScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: SaveForLaterWritesScalingPolicy
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref SaveForLaterWritesScalableTarget
TargetTrackingScalingPolicyConfiguration:
TargetValue: 70.0
ScaleInCooldown: 60
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might we want a larger target value for the writes compared to the reads? I may be wrong, but I think this one is has a higher usage than reads

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see this is a percentage rather than capacity units

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that this percentage represents the threshold at which AWS will start to scale out the read/write capacity if this percentage utilisation is breached. The minimum/maximum capacity values are those set at the top of the file. Whilst the read/write demands are indeed slightly different, the historical peaks seem to be for reads rather than writes, whereas the daily demand is for higher read capacity. I'm satisfied that using the same min/max values is a good enough starting point.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah makes sense

ScaleOutCooldown: 10
PredefinedMetricSpecification:
PredefinedMetricType: DynamoDBWriteCapacityUtilization
mbd0910 marked this conversation as resolved.
Show resolved Hide resolved

SaveForLaterReadsScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: !FindInMap [StageVariables, !Ref Stage, TableReadMaxCapacity]
MinCapacity: !FindInMap [StageVariables, !Ref Stage, TableReadMinCapacity]
ResourceId: !Sub "table/${App}-${Stage}-articles"
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable
ScalableDimension: dynamodb:table:ReadCapacityUnits
ServiceNamespace: dynamodb

SaveForLaterReadsScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: SaveForLaterReadsScalingPolicy
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref SaveForLaterReadsScalableTarget
TargetTrackingScalingPolicyConfiguration:
TargetValue: 70.0
ScaleInCooldown: 60
ScaleOutCooldown: 10
PredefinedMetricSpecification:
PredefinedMetricType: DynamoDBReadCapacityUtilization
Loading