在进行数据库清理时,获取内存限制会超出App Engine上的错误

时间:2016-04-10 08:09:31

标签: google-app-engine google-app-engine-python

我有以下代码,我每周通过一个cron作业运行以清除旧的数据库条目。 3-4分钟后,我得到Exceeded soft private memory limit of 128 MB with 189 MB after servicing 1006 requests total

然后还有这条消息While handling this request, the process that handled this request was found to be using too much memory and was terminated. This is likely to cause a new process to be used for the next request to your application. If you see this message frequently, you may have a memory leak in your application.下面是明确的代码。

def clean_user_older_stories(user):
  stories = Story.query(Story.user==user.key).order(-Story.created_time).fetch(offset=200, limit=500, keys_only=True)
  print 'stories len ' + str(len(stories))
  ndb.delete_multi(stories)


def clean_older_stories():
  for user in User.query():
    clean_user_older_stories(user)

我想有更好的方法可以解决这个问题。我该如何处理?

2 个答案:

答案 0 :(得分:2)

您是否尝试过在keys_only查询中进行用户查询?除了密钥之外,您没有使用任何用户属性,这有助于减少内存使用量。

您应该通过设置page_size并使用Cursor来浏览大型查询。

您的处理程序可以使用下一个游标通过任务队列调用自身,直到达到结果集的末尾。您可以选择使用deferred API cut down on boilerplate code进行此类任务。

话虽这么说,你在用户和商店之间做的'加入'可能会带来这种挑战。我会首先浏览用户,因为它似乎来自你描述的内容用户将加班,但每个用户的故事数量有限。

答案 1 :(得分:2)

这是因为In-Context Cache

  

在后台任务中执行长时间运行的查询时,上下文缓存可能会消耗大量内存。这是因为缓存保留了在当前上下文中检索或存储的每个实体的副本。

尝试禁用缓存

  

为了避免在长时间运行的任务中出现内存异常,您可以禁用缓存或设置一个策略,排除那些消耗最多内存的实体。

ctx = ndb.get_context
ctx.set_cache_policy(False)
ctx.set_memcache_policy(False)