我有一个看起来像这样的ndb模型:
class Post(ndb.Model):
time = ndb.DateTimeProperty()
body = ndb.TextProperty()
我只对存储N个帖子感兴趣。 因此,如果我已经有N个帖子实体,并且我添加了一个新实体,我想删除最旧的帖子(基于DateTime),以便添加新的实体并且entites的总数仍为N;类似于循环队列的东西。
最有效的方法是什么?我可以想到两种方式:
1)在插入时处理这个,所以获取偏移量为N-1的实体(结果应该只是一个实体)并删除它然后插入新实体(或按时间顺序上升并抓住第一个实体)。
2)在cronjob中处理它,所以每隔24小时获取偏移量为N的实体并删除所有实体。
当然可以选择将它们留在那里...... 我不会使用超过N个实体,但我猜测删除实体可能很昂贵所以我每次检索帖子时都可以进行提取(N)并按时间顺序排序。
这一点的重点是做一些便宜的事情,所以我不浪费资源。
编辑: 我预测N可能在100-300左右
答案 0 :(得分:1)
你没有提到预期的qps量,但“每24小时”的cron工作表明低到中等。你也没有说N = 100或N = 10,000。如果不是高容量事务,那么这可以通过由定期调度的cron启动的拉取队列很容易地处理 - 类似于每隔几分钟。您需要第二个实体来跟踪最后使用的ID号。拉队列任务将简单地读取最后使用的实体ID号(假设这些范围从100-199,N = 100)。租用任务并通过它们创建新(替换)实体的新ID列表。很简单。完成租用任务后,执行多次放置()。我不能确定多重放置()的有效限制是什么,但是使用像你这样的小型实体一次做几百个没问题。如果你说N = 10,000,那么我仍然会这样做,但你需要迭代使用块的租约任务。我还要添加一个索引属性,该属性设置为以毫秒为单位的unix时间戳,其中id号位于小数位。这将为您提供一个非常简单的索引字段,以按顺序连续遍历您的实体。如果您依赖多个puts()和DateProperty,则可能会遇到日期冲突问题。
总结:找出一种方法,为您的实体ID利用编码方案,使您能够进行排序,并使用cron + pull队列。利用时间戳字段进行排序查询。
HTH,stevep
答案 1 :(得分:1)
选项1涉及每个新帖子1次放置,1次查询和1次删除。
选项2每个新帖子使用1个放置,每天使用一个查询+批量删除。
选项3每个新帖子使用1个
在所有情况下,您都会使用相同的查询获得最新的N个帖子,这些帖子可以进行memcached以提高性能(在添加新帖子时使缓存无效)。请记住,您的查询应按先下降的顺序排序,然后获得前N个结果。
因此,假设每天有多个新帖子,选项2比选项1更有效,而且费用更低。
选项3 /不删除帖子更有效率(在数据库操作方面)你可能有兴趣保留旧帖子的历史记录,但是你需要为存储空间付费 - 如果你没有增加千兆字节数那个月这个很小,可能是你最好的选择。