如果两条评论几乎同时到达并且实例激增,那么您在此处对 1 秒实体更新有一定的了解。(如果您确实走这条路,请确保为您的列表属性设置 indexed=False。)在继续之前考虑一下这是如何发挥作用的,而另一种似乎更复杂,但一旦投入生产可能会提供真正的优势。
为什么不创建一个带有计数器字段的 CommentParent 模型,以及一个单独的带有 parent_id 和 date_created(自动)作为索引字段的 Comments 模型。当有新评论进入时,会启动一个新评论线程 put() 父实体,并将评论文本和 parent_id 引用发送到任务队列。对线程的所有未来评论都类似地直接传递到队列(产生非常快的在线处理程序延迟)。让任务队列 put() Comments 记录,并更新 CommentParent 计数器。为了避免计数器更新的 1 秒限制,您需要考虑一下调整您的 TQ,或者用分片计数器代替实体计数器。(众所周知,大容量应用程序中的计数器很难。)
当用户进入此评论线程时,客户端会收到 parent_id 和当前计数。然后它请求使用 parent_id= date_created> 过滤器通过简单查询处理的前 N 条记录(假设 LIFO 模型),并按 date_created 降序和 fetch() 限制或计数器排序,以限制您在查询中的处理。 ier() 循环(我会使用后者。)您将评论和每个评论都传回 date_created (作为下一个查询的“光标指针”)。客户端使用初始计数器值来维护“加载 N 更多”按钮标签。(我还将添加另一个返回值,它是一个 is_finished 布尔值,只要您的查询返回少于您的获取限制,就将其设置为 true - 这将避免完全依赖计数器数学。)
这有一些缺点。最终的一致性和任务队列延迟可能意味着偶尔的不同步计数或错过评论。您需要与 date_created gt 和降序设置所需的自定义索引相关的开销。但是,您也有真正的好处:在线处理程序的延迟非常快,并且几乎同时的评论集群没有问题导致您出现 1 秒实体更新限制的问题。您还有一个非常重要的好处,那就是让任务队列充当评论量中任何小峰值的缓冲区。如果没有此缓冲区,您可能会受到每次出现此类峰值时启动几个实例的困扰。这是 15 分钟收费乘以此类实例的数量,
您还可以使用一些非常简单的方法来使用 memcache 来限制需要运行的实际查询的数量。如果线程处于活动状态,您可以缓存前 N 个查询结果,并使用该缓存直到做出新评论。像这样的东西。当然,你也可以在你的方法中使用 memcache。不管怎样,考虑一下使用 memcache。
HTH-步骤