执行数据库清理时,App Engine 出现内存限制超出错误
Getting memory limit exceed error on App Engine when doing a db clean
我有以下代码,我每周 运行 通过 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)
我想有更好的方法来处理这个问题。我该如何处理?
您是否尝试过将您的用户查询设为 keys_only
查询?除了密钥之外,您没有使用任何用户属性,这将有助于减少内存使用量。
您应该通过设置 page_size 并使用 Cursor 对大型查询进行分页。
您的处理程序可以使用下一个游标通过任务队列调用自身,直到到达结果集的末尾。您可以选择使用 deferred API cut down on boilerplate code 来完成此类任务。
也就是说,'join' 您在 User 和 Store 之间所做的操作可能会使这具有挑战性。我会首先翻阅用户,因为从您所描述的情况来看,用户会随着时间的推移而增长,但每个用户的故事数量是有限的。
With executing long-running queries in background tasks, it's possible for the in-context cache to consume large amounts of memory. This is because the cache keeps a copy of every entity that is retrieved or stored in the current context.
尝试禁用缓存
To avoid memory exceptions in long-running tasks, you can disable the cache or set a policy that excludes whichever entities are consuming the most memory.
ctx = ndb.get_context
ctx.set_cache_policy(False)
ctx.set_memcache_policy(False)
我有以下代码,我每周 运行 通过 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)
我想有更好的方法来处理这个问题。我该如何处理?
您是否尝试过将您的用户查询设为 keys_only
查询?除了密钥之外,您没有使用任何用户属性,这将有助于减少内存使用量。
您应该通过设置 page_size 并使用 Cursor 对大型查询进行分页。
您的处理程序可以使用下一个游标通过任务队列调用自身,直到到达结果集的末尾。您可以选择使用 deferred API cut down on boilerplate code 来完成此类任务。
也就是说,'join' 您在 User 和 Store 之间所做的操作可能会使这具有挑战性。我会首先翻阅用户,因为从您所描述的情况来看,用户会随着时间的推移而增长,但每个用户的故事数量是有限的。
With executing long-running queries in background tasks, it's possible for the in-context cache to consume large amounts of memory. This is because the cache keeps a copy of every entity that is retrieved or stored in the current context.
尝试禁用缓存
To avoid memory exceptions in long-running tasks, you can disable the cache or set a policy that excludes whichever entities are consuming the most memory.
ctx = ndb.get_context
ctx.set_cache_policy(False)
ctx.set_memcache_policy(False)