3

我的问题是如何最好地释放内存来响应 appengine 上的异步 url 获取需求。这是我在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()

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

4

2 回答 2

2

错误的做法:将这些 url 放入(放置)队列,将其速率提高到所需值(默认值:5/秒),并让每个任务处理一个 url-fetch(或其中的一组)。请注意,安全限制为 3000 次 url-fetch-api-calls/分钟(一个 url-fetch 可能使用多个 api-call)

于 2013-01-29T13:22:59.377 回答
1

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

我还发现 ndb 可以让这些异步解决方案更加优雅。

查看 Brett Slatkins 关于可扩展应用程序管道的演讲。

于 2013-01-29T13:23:34.267 回答