如何自动扩展Amazon DynamoDB吞吐量?

时间:2014-10-14 07:02:46

标签: amazon-web-services amazon-dynamodb

Amazon DynamoDB不提供内置功能,可根据动态负载自动调整吞吐量。 它提供API来增加或减少吞吐量。客户按小时计算配置的读取和放大费用。写吞吐量。

有哪些不同的方法可以改变dynamodb的吞吐量并实现成本节约的好处?

11 个答案:

答案 0 :(得分:24)

克里斯的答案是准确的答案。只是添加使用DynamoDB之前的经验中的几点......

DynamoDB的情况与EC2不同。弹性计算服务具有Amazon直接支持的Web服务API,允许您根据需求存在多少逻辑来编程如何扩展或缩小。您可以通过定义监视阈值并自动触发组中实例的创建或删除来对此进行编程。

数据服务器与触发器调整容量的方式不同。但是,DynamoDB的容量非常灵活,可以像Chris指出的那样进行控制。提供此功能的API足以完成一次性更改。或者从控制台进行等效的手动更改。

使用DynamoDB对程序创建和更新操作的不同语言绑定就在这里......

http://docs.aws.amazon.com/cli/latest/reference/dynamodb/index.html

修改容量的重要操作是......

http://docs.aws.amazon.com/cli/latest/reference/dynamodb/update-table.html

因此,这使您能够增加或减少ProvisionedThroughput的ReadCapacityUnits或WriteCapacityUnits。

对于预测或一次性更改,这是好的。但这与允许您自动触发更改的灵活性工具不​​同。

以编程方式,您最可能想要做的是调整容量以响应前一时间间隔内的利用率变化。特别是,您可能需要通过定义适当的时隙以及触发的下限和上限阈值来快速扩展以响应需求激增。

此处描述了实现此目标的更完整的解决方案......

https://aws.amazon.com/blogs/aws/auto-scale-dynamodb-with-dynamic-dynamodb/

解决方案由Sebastian Dahlgren维护,可以在......的所有说明中找到。

https://github.com/sebdah/dynamic-dynamodb

我看到当前版本是1.18.5,这比我上次使用它时更新。

从早期版本判断,通过dynamodb.conf属性样式文件进行配置很简单...

提供凭据和区域后,最关键的设置是

  • check-interval - 以秒为单位测试吞吐量
  • min-provisioned-reads, max-provisioned-reads; reads-upper-threshold, reads-lower-threshold; increase-reads-with, decrease-reads-with - 这些都是百分比
  • min-provisioned-writes, max-provisioned-writes; writes-upper-threshold, writes-lower-threshold; increase-writes-with, decrease-writes-with - 这些都是百分比

这些信息是最新的吗?

如果你看一下http://aws.amazon.com/new/,你会看到影响DynamoDB的最近一个新的更改会影响存储的文件。 Dynamic DynamoDB的条目是最后一个处理扩展操作的已发布条目。所以这是目前维护最好的DynamoDB自动扩展功能。

答案 1 :(得分:14)

亚马逊刚为dynamodb添加了自动缩放功能,请参阅详细信息here

答案 2 :(得分:13)

我刚刚发现这个项目会自动调整您的Dynamodb,并且看起来比Dynamic Dynamo更好,因为它使用Lambda函数而不是EC2实例:

https://github.com/channl/dynamodb-lambda-autoscale

  • 5分钟设置过程
  • 无服务器设计
  • 灵活的代码配置风格
  • 自动缩放表和全局二级索引
  • 自动缩放多个表格
  • 按固定设置自动缩放
  • 按预配置容量利用率自动缩放
  • 按限制事件指标自动缩放
  • 通过合并受限制的事件指标,针对大量使用和热键问题进行了优化
  • 使用并发查询优化性能
  • AWS强加的RateLimitedDecrement
  • 通过'测量'统计
  • 通过'dotenv'
  • 配置AWS凭证
  • 通过'webpack'优化lambda包
  • ES7代码
  • 100%Flow静态类型检查范围

答案 3 :(得分:8)

您可以通过updateTable API以编程方式管理吞吐量,也可以通过控制台手动管理吞吐量。

还有像Dynamic DynamoDB这样的工具,虽然您也可以推出自己的版本:您将使用updateTable API并运行一些后台进程来检测这些情况并根据需要调用updateTable。

更改DynamoDB的比例时要注意的一些事项:

  1. 无论您是否真正使用它,都需要为分配的吞吐量付费。
  2. Wen你扩展,Dynamo可能会为你分配新的分区 - 但它在缩小时不会删除它们。这会导致意外hot hash key问题,因为您有很多分区,但每个分区的吞吐量都非常低。

答案 4 :(得分:4)

Jeff Bar最近在AWS官方博客上撰写了一篇博客:"使用Dynamic DynamoDB自动扩展DynamoDB":

https://aws.amazon.com/blogs/aws/auto-scale-dynamodb-with-dynamic-dynamodb/

他介绍了Dynamic DynamoDB,这是一个由独立开发人员构建的开源工具,可以使用CloudFormation模板自动处理。

答案 5 :(得分:4)

我认为其他答案做得很好但我通过利用CloudWatch警报和DynamoDB的UpdateTable操作来改变预配置容量,以事件驱动的方式对自动缩放DynamoDB采用不同的方法。以下方法不仅有助于降低成本,还可以扩大意外负载的容量。

<强>要点:

在DynamoDB指标上配置CloudWatch警报,以根据阈值提醒您,并通过SNS主题将警报推送到SQS队列。轮询SQS队列的守护进程可以使用DynamoDB的UpdateTable操作处理这些警报并更改表配置容量,并更新CloudWatch警报阈值。

详细版本:

请注意,此方法需要1.了解CloudWatch,SNS,SQS等AWS服务2.以您喜欢的编程语言实施的大量时间3.维护守护进程处理SQS消息并更改预配置容量

一次性设置:

  1. 在DynamoDB表的ConsumedWriteCapacityUnitsConsumedReadCapacityUnits指标上创建CloudWatch警报。您可以使用此documentation
  2. 配置CloudWatch警报to alert a SNS主题。创建AWS SQS队列并订阅队列以接收来自SNS主题的警报。
  3. 以任何编程语言编写守护程序以轮询SQS队列并处理所有警报。 AWS拥​​有多种语言的SDKs,因此选择任何一种语言都可以避免编写大量代码与AWS服务进行通信。
  4. 守护程序算法:

    1. 对于它收到的每条SQS消息,计算要使用的新配置容量,并使用新值发出UpdateTable操作。
    2. 如果需要,使用新阈值更新CloudWatch警报。
    3. 您可以使用上述方法向上或向下扩展。例如,将CloudWatch警报阈值维持在ProvisionedWriteCapacityUnits的80%,并且每次使用率超过80%时,增加容量并将警报阈值设置为新值的80%。同样,当消费量低于x%时,您可以缩小规模。

      虽然这是关键所在,但在生产质量解决方案中需要考虑很多要点。

      1. 了解DynamoDB分区和热键问题。
      2. 请注意所有DynamoDB limits
      3. 每UTC时间缩减比例的限制。
      4. 批量处理多个UpdateTable操作。
      5. 最后,Neptune.io通过使用此架构为自动缩放DynamoDB提供了打包的SaaS解决方案。有关阅读的详细信息,请参阅http://blog.neptune.io/one-click-autoscaling-of-dynamodb/http://blog.neptune.io/dos-and-donts-of-dynamodb-autoscaling/

        P.S:我为海王星工作。而且,如果您需要更多实施细节,我可以帮助您。

答案 6 :(得分:3)

我向Rockeee Dynamic DynamoDB Lambda添加了新功能。你可以看到这个项目:

https://github.com/touchvie/dynamic-dynamodb-lambda

  • 全球二级索引支持
  • 在config json文件中启用/禁用读/写自动缩放
  • CloudWatch支持中的节流事件
  • 启用/禁用config json文件中的throttle-read / throttle-write检查
  • 为lambda添加测试

我希望它可以帮助你。

答案 7 :(得分:2)

DynamoDB Auto Scaling脚本指南:

客户按小时收费,按规定付费阅读&amp;写吞吐量。以下是欧盟(爱尔兰地区)的Amazon Dynamo DB定价。

•写入吞吐量:每10个写入容量单位每小时0.00735美元 •读取吞吐量:每50个读取容量单位每小时0.00735美元

Amazon Dynamo DB不提供内置功能,可根据动态负载自动调整吞吐量。它提供API来增加或减少吞吐量,但有一些限制,例如吞吐量可以在一天内减少两次,并在一天中的任何时间增加。

固定读取容量2,000读/秒和2000写/秒24小时的生产表每月费用是多少?

计算:$ 0.00735 X 24小时X 200 X 30天{写月费} + $ 0.00735X 24小时X 40 X 30天{读取月费} = 1058.4 + 211.68 =固定1270 $ /月。

编写实用程序{亚马逊支持的编程语言}的指南,用于调整表的吞吐量并减少每月帐单。

(A)初始值:基本上,在这里你必须观察和决定阅读&amp;在分析考虑15天或1个月负载的平均使用量后,将表的吞吐量写为初始化值,并为读取添加X%额外值,并在顶部写入额外的Y%以承受意外负载。 初始读/写吞吐量=根据平均使用量计算读取吞吐量+ X {读取}%或Y {写入}% X&amp;根据观察,Y可以是10%到30%之间的任何值。

(B)峰值负载整形:可以将表上的警报设置为当负载达到预配置吞吐量的50%到60%时,可以采取必要的操作,如调用吞吐量增量API以将吞吐量增加到30%到50%之间提供吞吐量。*

(C)手动成型:对于已知的重负荷,如批量装载/节日季节,应手动设置吞吐量至正常日常操作的200% - 300%,直至装载完成* *一旦业务工作时间或负载结束。吞吐量应降低到初始值。

注意:读者可以计算每月节省,考虑1,000读/写16小时。 + 2,000读/写8小时,提供实用程序。

答案 8 :(得分:2)

现在AWS已宣布计划执行lambda服务,这些似乎非常适合进行基于时间的自动扩展。我写了example of how to use this on mediumExample code在github上。

答案 9 :(得分:2)

AWS于2017年6月为DynamoDB添加了原生自动缩放支持。请参阅公告here

您可以使用代码(Java SDK example)对其进行配置,但如果只有几个表,则可以使用Management Console。点击表格配置,然后选择容量标签。下图显示了您的选择:

auto scaling configuration

答案 10 :(得分:0)

AWS于2017年6月为DynamoDB添加了本机自动扩展支持。以下代码(source)提供了如何使用Java SDK配置自动扩展的示例:

package com.amazonaws.codesamples.autoscaling;

import com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScalingClient;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsResult;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesResult;
import com.amazonaws.services.applicationautoscaling.model.MetricType;
import com.amazonaws.services.applicationautoscaling.model.PolicyType;
import com.amazonaws.services.applicationautoscaling.model.PredefinedMetricSpecification;
import com.amazonaws.services.applicationautoscaling.model.PutScalingPolicyRequest;
import com.amazonaws.services.applicationautoscaling.model.RegisterScalableTargetRequest;
import com.amazonaws.services.applicationautoscaling.model.ScalableDimension;
import com.amazonaws.services.applicationautoscaling.model.ServiceNamespace;
import com.amazonaws.services.applicationautoscaling.model.TargetTrackingScalingPolicyConfiguration;

public class EnableDynamoDBAutoscaling {

    static AWSApplicationAutoScalingClient aaClient = new AWSApplicationAutoScalingClient();

    public static void main(String args[]) {

        ServiceNamespace ns = ServiceNamespace.Dynamodb;
        ScalableDimension tableWCUs = ScalableDimension.DynamodbTableWriteCapacityUnits;
        String resourceID = "table/TestTable";

        // Define the scalable target
        RegisterScalableTargetRequest rstRequest = new RegisterScalableTargetRequest()
            .withServiceNamespace(ns)
            .withResourceId(resourceID)
            .withScalableDimension(tableWCUs)
            .withMinCapacity(5)
            .withMaxCapacity(10)
            .withRoleARN("SERVICE_ROLE_ARN_GOES_HERE");

        try {
            aaClient.registerScalableTarget(rstRequest);
        } catch (Exception e) {
            System.err.println("Unable to register scalable target: ");
            System.err.println(e.getMessage());
        }

        // Verify that the target was created
        DescribeScalableTargetsRequest dscRequest = new DescribeScalableTargetsRequest()
            .withServiceNamespace(ns)
            .withScalableDimension(tableWCUs)
            .withResourceIds(resourceID);

        try {
            DescribeScalableTargetsResult dsaResult = aaClient.describeScalableTargets(dscRequest);
            System.out.println("DescribeScalableTargets result: ");
            System.out.println(dsaResult);
            System.out.println();
        } catch (Exception e) {
            System.err.println("Unable to describe scalable target: ");
            System.err.println(e.getMessage());
        }

        System.out.println();

        // Configure a scaling policy
        TargetTrackingScalingPolicyConfiguration targetTrackingScalingPolicyConfiguration = 
            new TargetTrackingScalingPolicyConfiguration()
            .withPredefinedMetricSpecification(
                new PredefinedMetricSpecification()
                .withPredefinedMetricType(MetricType. DynamoDBWriteCapacityUtilization))
            .withTargetValue(50.0)
            .withScaleInCooldown(60)
            .withScaleOutCooldown(60);

        // Create the scaling policy, based on your configuration
        PutScalingPolicyRequest pspRequest = new PutScalingPolicyRequest()
            .withServiceNamespace(ns)
            .withScalableDimension(tableWCUs)
            .withResourceId(resourceID)
            .withPolicyName("MyScalingPolicy")
            .withPolicyType(PolicyType.TargetTrackingScaling)
            .withTargetTrackingScalingPolicyConfiguration(targetTrackingScalingPolicyConfiguration);

        try {
            aaClient.putScalingPolicy(pspRequest);
        } catch (Exception e) {
            System.err.println("Unable to put scaling policy: ");
            System.err.println(e.getMessage());
        }

        // Verify that the scaling policy was created
        DescribeScalingPoliciesRequest dspRequest = new DescribeScalingPoliciesRequest()
            .withServiceNamespace(ns)
            .withScalableDimension(tableWCUs)
            .withResourceId(resourceID);

        try {
            DescribeScalingPoliciesResult dspResult = aaClient.describeScalingPolicies(dspRequest);
            System.out.println("DescribeScalingPolicies result: ");
            System.out.println(dspResult);
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("Unable to describe scaling policy: ");
            System.err.println(e.getMessage());
        }            
    }
}

此代码要求您为有效的Application Auto Scaling服务角色提供ARN。将SERVICE_ROLE_ARN_GOES_HERE替换为实际的ARN。