1

3 億の URL のリストがあります。この URL を使用して非同期 REST API 呼び出しを呼び出す必要があります。応答は必要ありません。これをtwistedで実装しようとしました。リストが1000を超えるURLで大きくなると、エラーが発生します。これを達成する方法を教えてください

Please find my code 

# start of my program
from twisted.web import client
from twisted.internet import reactor, defer
#list of urls to be invoked
urls = [
 'http://test.com/apiname/?s=85465&ts=1370591808', 
 'http://test.com/apiname/?s=85465&ts=1370591808', 
 'http://test.com/apiname/?s=85465&ts=1370591808', 
 'http://test.com/apiname/?s=85465&ts=1370591808', 
 'http://test.com/apiname/?s=85465&ts=1370591808', 
 'http://test.com/apiname/?s=85465&ts=1370591808', 
 'http://test.com/apiname/?s=85465&ts=1370591808', 
 'http://test.com/apiname/?s=85465&ts=1370591808'
]
#list of urls

#the call back
def finish(results):
    for result in results:
    print 'GOT PAGE', len(result), 'bytes'
    reactor.stop()


waiting = [client.getPage(url) for url in urls]
defer.gatherResults(waiting).addCallback(finish)

reactor.run()
4

1 に答える 1

1

提供されたソースを考えると、最初の問題は、3 億の URL 文字列が大量の RAM を消費することです。各文字列にはバイト数を超えるオーバーヘッドがあり、文字列をリストに組み合わせるには再割り当てが必要になる可能性があることに注意してください。

さらに、ここでの微妙なバグは、waiting = [ ... ] を使用して結果をリストに蓄積しようとしていることだと思います。本当は、gatherResults() をフィードするイテレータが必要だったのではないかと思います。

これらの両方の問題を解決するには、ファイルを「urls.txt」に書き込み、代わりに次のことを試してください(urls = [...] でビットをドロップすることもできます)

import sys.stdin
waiting = (client.getPage(url.strip() for url in sys.stdin)
defer.gatherResults(waiting).addCallback(finish)

reactor.run()

python script.py <urls.txtを使用して実行するだけです

[...] と (...) の違いはかなり大きいです。[...] ... 部分をすぐに実行し、結果の巨大なリストを作成します。(...) は、... の反復ごとに 1 つの結果を生成するジェネレーターを作成します。

注:私はそれをテストする機会がありませんでした(私はTwistedをあまり使用していません)が、あなたが投稿したものから、これらの変更はRAMの問題に役立つはずです

于 2013-06-27T19:13:32.810 に答える