Python スクリプトがデータ セットを反復するのにかかる時間に問題があります。データセットは約 40k ドキュメントです。これは、pymongo カーソルが内部的で開発者から離れて抽象化された複数のフェッチを発行するのに十分な大きさです。問題を示すために、スクリプトを可能な限り単純化しました。
from pymongo import Connection
import time
def main():
starttime = time.time()
cursor = db.survey_answers.find()
counter=0;
lastsecond=-1;
for entry in cursor:
if int(time.time()-starttime)!=lastsecond:
print "loop number:", counter, " seconds:",int(time.time()-starttime);
lastsecond= int(time.time()-starttime)
counter+=1;
print (time.time()-starttime), "seconds for the mongo query to get rows:",counter;
connection = Connection(APPSERVER)#either localhost or hostname depending on test
db = connection.beacon
if __name__ == "__main__":
main()
私のセットアップは次のとおりです。私は 4 つの個別のホスト、mongos を実行する 1 つの APPSERVER、およびそれぞれが他の 2 つのプライマリ レプリカ セットとセカンダリ レプリカ セットである 3 つの他のシャード ホストを持っています。
これをシャード サーバーの 1 つから (APPSERVER ホスト名を指す接続を使用して) 実行すると、次のようになります。
loop number: 0 seconds: 0
loop number: 101 seconds: 2
loop number: 7343 seconds: 5
loop number: 14666 seconds: 8
loop number: 21810 seconds: 10
loop number: 28985 seconds: 13
loop number: 36078 seconds: 15
16.0257680416 seconds for the mongo query to get rows: 41541
したがって、ここで何が起こっているかは明らかです。カーソル要求の最初のバッチサイズは 100 で、その後の各バッチサイズは 4m 相当のデータであり、私にとっては 7k をわずかに超えるドキュメントのように見えます。そして、各フェッチには2〜3秒かかります!!!!
アプリケーションを mongos インスタンスの近くに移動することで、この問題を解決できると考えました。ネットワークの使用量を減らすことを期待して、上記のコードを APPSERVER で (接続が localhost を指すように) 実行しました ....しかし、それはさらに悪いことでした!
loop number: 0 seconds: 0
loop number: 101 seconds: 9
loop number: 7343 seconds: 19
loop number: 14666 seconds: 28
loop number: 21810 seconds: 38
loop number: 28985 seconds: 47
loop number: 36078 seconds: 53
53.5974030495 seconds for the mongo query to get rows: 41541
カーソルのサイズは両方のテストでまったく同じです。これは素晴らしいことですが、ここでは各カーソルのフェッチに9 ~ 10 秒かかります!!!
通信する必要がある 4 つの別々のホストがあることはわかっているので、これはすぐにはできません。しかし、おそらく 10m のレコードのコレクションを反復処理する必要があります。7k あたり 2 秒で、1 時間弱かかります。私はこれを持つことはできません !
ところで、私は python/mongo の世界に不慣れで、php と mysql に慣れていて、これがほんの一瞬で処理されることを期待しています。
$q=mysql_query("select * from big_table");//let's say 10m rows here ....
$c=0;
while($r=mysql_fetch_rows($q))
$c++;
echo $c." rows examined";
私が提示したpymongo(〜1時間)とphp / mysql(<1秒)のアプローチの巨大な違いを誰かが説明できますか?ありがとう!