我有以下代码,我每周通过一个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)
我想有更好的方法可以解决这个问题。我该如何处理?
答案 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)