在appengine(python)上获取url后释放内存的最佳做法

时间:2013-01-29 12:21:50

标签: python google-app-engine

我的问题是如何最好地释放内存对appengine的异步url fetch需要的响应。这是我在python中基本上做的事情:

rpcs = []

for event in event_list:
    url = 'http://someurl.com'
    rpc = urlfetch.create_rpc()
    rpc.callback = create_callback(rpc)
    urlfetch.make_fetch_call(rpc, url)
    rpcs.append(rpc)

for rpc in rpcs:
    rpc.wait()

在我的测试场景中,它为1500请求执行此操作。但是我需要一个架构来在很短的时间内处理更多。

然后有一个回调函数,它将一个任务添加到队列来处理结果:

def event_callback(rpc):
    result = rpc.get_result()
    data = json.loads(result.content)
    taskqueue.add(queue_name='name', url='url', params={'data': data})

我的问题是,我执行了很多并发RPC调用,我的实例的内存崩溃了:“在为975个请求提供服务后,超出了软私有内存限制159.234 MB”

我已经尝试了三件事:

del result
del data

result = None
data = None

我在回调函数后手动运行了垃圾收集器。

gc.collect()

但是在回调函数将任务添加到队列之后,似乎没有任何东西直接释放内存 - 因此实例崩溃了。还有其他办法吗?

2 个答案:

答案 0 :(得分:2)

错误的方法:将这些网址放入(put)-queue,将其速率提高到所需的值(defaut:5 / sec),并让每个任务处理一个url-fetch(或其中的一个组)。请注意,安全限制为3000 url-fetch-api-calls / minute(并且一个url-fetch可能使用多个api-call)

答案 1 :(得分:1)

也可以将任务队列用于urlfetch,扇出并避免耗尽内存,注册命名任务并将event_list游标提供给下一个任务。您可能希望在这种情况下获取+进程,而不是为每个进程注册新任务,尤其是在进程还包括数据存储区写入的情况下。

我也发现ndb使这些异步解决方案更加优雅。

scalable appspipelines上查看Brett Slatkins的演讲。