【问题标题】:need to add TTL to a 3bln+ record ddb table需要将 TTL 添加到 3bln+ 记录 ddb 表
【发布时间】:2020-01-29 18:03:50
【问题描述】:

我们需要将 TTL 添加到 3bln+ 记录的 ddb 表中。 这是一个使用非常频繁的活动表,因此我们无法将其关闭,甚至无法将请求重定向到另一个表。 我知道我们需要运行一个脚本来手动向表中添加一个新的 TTL 属性?还有其他方法吗?

知道执行这么多更新需要多长时间来处理 3bln+ 条记录吗? 这是否有额外的财务成本?

谢谢!

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb


    【解决方案1】:

    根据https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughput.html

    UpdateItem - 修改表中的单个项目。 DynamoDB 会考虑更新前后显示的项目大小。消耗的预置吞吐量反映了这些项目大小中的较大者。即使您仅更新项目属性的子集,UpdateItem 仍将消耗全部预置吞吐量(“之前”和“之后”项目大小中的较大者)。

    因此,尽管您的脚本只会为每个项目添加一个小的 TTL 列,但 WCU 中此操作的成本与重写整个数据库的成本相同。如果您使用的是按需计费模式,那么这笔费用可能会很大,您一定要考虑一下。

    但是,如果您使用预置容量计费模式,则成本可能更易于管理:您的运行可能低于容量,因此可以免费添加额外的写入操作。但是,接下来的问题是您有多少额外容量:如果您每秒只有 1,000 个请求的额外容量,那么您将花费整个月的时间来编写 30 亿个项目的 TTL。在任何情况下,如果您使用预置容量,您的脚本将需要仔细进行流量控制:它应该以每秒 N 次更新的速度运行,缓慢增加 N,但一旦出现容量溢出错误,它应该降低 N。如果您不进行此类流量控制,最终可能会扼杀您的实际实时应用程序。

    最后,您需要解决的另一个问题是,您如何知道哪些项目存在,以及如何向它们添加 TTL 字段。如果您对存在哪些键没有一些外部知识,那么不幸的是,您需要“扫描”整个表以找出现有的键。您可以要求 Scan 只返回密钥,而不是完整的项目,但这仍然会花费您与阅读整个项目相同的成本(但会减少网络带宽)。幸运的是,在 DynamoDB 中读取比写入要便宜得多。此外,同样,如果您使用的是预置容量,您可能可以在现有的过度预置容量上免费缓慢地进行扫描。

    【讨论】:

    • 感谢您的详细解答!在接受您的回答之前,我会阅读有关该主题的更多信息,但这已经很有帮助
    【解决方案2】:

    没有办法避免一些成本,但您可以将其最小化。由于您要添加一个新字段,因此您可以使用 DynamoDB 更新项,它允许您仅写入您正在影响的字段。这将做几件事。

    1. 无需先读取数据再写入。这样做会花费更多,因为您需要先读取,然后再写入整个记录,这可能会比您通过更新写入的有限数据成本更高。
    2. 因为它是对新字段的更新,所以可以在不影响其他服务的情况下写入数据。

    要记住的一件事是,如果您现有的服务正在读取数据然后将其写回,您可能会遇到竞争条件问题。例如,您读取没有 TTL 列的数据,然后运行该进程以添加 TTL,然后您将没有 TTL 的记录写回。如果您认为您可能有这个问题,您也需要解决这个问题。

    【讨论】:

    • 你无法避免读取数据。您必须使用全表扫描,除非您碰巧知道每个项的主键。
    • 有效点,但即使你只需要读取键,而不是整个记录。
    • 这确实带来了重要的一点。在扫描表并更新值之前,您需要更改写入表的任何内容以写入 TTL 值。否则,您将拥有无法更新的记录。
    • 即使您只读取密钥,也不会保存任何 RCU,除非您有一个仅限密钥的 GSI,此时您支付的 GSI 只是您的主密钥的副本.
    • 我没有意识到这一点,尽管我没有真正考虑过。这是有道理的,因为 RCU 是基于对记录的检索,而不是基于返回的内容。我想只返回特定属性类似于过滤器,因为它是在 RCU 之后应用的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    相关资源
    最近更新 更多