【问题标题】:Google App Engine - What's the recommended way to keep entity amount within limit?Google App Engine - 将实体数量保持在限制范围内的推荐方法是什么?
【发布时间】:2012-11-08 03:04:38
【问题描述】:

我有一些实体,我需要通过丢弃旧实体将它们保持在有限的数量内。就像日志条目维护一样。 GAE 有什么好的方法可以做到这一点?

我的想法:

选项 1. 为这些实体中的每一个添加一个 Date 属性。创建 cron 作业以每天检查数据存储统计信息。如果超过限制,则查询该类型的一些实体并按日期排序,最旧的在前。删除它们,直到大小小于例如 0.9 * max_limit。

选项 2。选项 1 需要一个带索引的附加属性。我观察到实体键 ID 可能可能会增加。所以我想只查询键并按升序排序。删除 id 较小的那些。它不需要额外的属性(日期)和索引。但是我很担心key id是否会越来越多?

我认为这是一项常见的数据维护任务。有什么成熟的方法可以做到吗?

顺便说一下,我的应用程序的一个小广告,免费且纯粹是为了程序员的乐趣! http://robotypo.appspot.com

【问题讨论】:

    标签: google-app-engine google-cloud-datastore


    【解决方案1】:

    您不能假设 ID 总是在增加。 docs about ID gen 只保证:

    以这种方式分配的 ID 不会被 Datastore 的 自动 ID 序列生成器,可在实体键中使用,无需 冲突。

    default sort order也不保证按ID号排序:

    如果没有指定排序顺序,则按顺序返回结果 它们是从 Datastore 中检索的。

    这是含糊的,并没有说默认顺序是按ID。


    一种解决方案可能是使用一个跟踪第一个元素的旋转计数器。当您想添加新实体时:获取计数器,将其递增,将其修改为限制,然后添加一个带有 ID 的新元素作为计数器的值。这一切都必须在事务中完成,以保证计数器不会被另一个请求增加。具有相同键的新元素将覆盖存在的元素(如果有)。

    当您想要全部获取它们时,您可以手动生成密钥(因为它们都是已知的),进行批量获取,按 ID 排序,然后在计数器的值处将它们分成两部分并交换它们。


    如果您希望 ID 唯一,您可以维护一个单独的计数器(使用事务来修改和读取它以确保您的安全)并以 ID 作为其值创建实体,然后在达到限制时删除 ID。

    【讨论】:

    • 感谢您的回答。很高兴知道无法保证自动生成的 ID 和默认提取。您提到的旋转计数器方法对于维护大量实体非常有效。但是,对于实际情况还有另一个要求:永远不应重复使用 ID,因为它们在其他地方被引用。找不到它们很好,但如果不正确(更改为另一个实体)会令人困惑。有没有办法在不创建另一个 ID 来唯一标识他们的情况下这样做?
    【解决方案2】:

    您可以创建第二个实体(我们称之为 A),它保留您要限制的实体的键列表,如下所示(伪代码):

    class A:
        List<Key> limitedEntities;
    

    添加新实体时,将其键添加到A的列表中。如果列表长度超过限制,则取列表的第一个元素并删除相应的实体。

    请注意,当您添加或删除一个实体时,您应该修改事务中的实体 A 的列表。由于这些实体属于不同的实体组,您应该考虑使用Cross-Group Transactions

    希望这会有所帮助!

    【讨论】:

    • 感谢您的回答。当限制较小时,此方法很有帮助且有效。如果限制很大,比如 100 万,有什么建议吗?
    • 如果您有
    猜你喜欢
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多