我遇到了用于我的python脚本迭代数据集所花费的时间的问题。数据集约为40k文件。这足以导致pymongo游标发出多个内部并从开发者处抽象出来的提取。我尽可能简化我的脚本以示范问题:pymongo光标getMore需要很长时间
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个独立的主机,一个APPSERVER运行mongos,以及3个其他分区主机,每个分区主副本集和其他两个主副副本集。
我可以从碎片服务器(带有指向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
所以,很明显这是怎么回事就在这里,游标请求的第一BATCHSIZE是100,然后每个后续的一个是价值4米的数据,这对我来说似乎超过了7k个文件。每次获取成本为2-3秒!!!!
我想我可以通过移动我的应用程序更接近mongos实例来解决这个问题。我在APPSERVER上运行上面的代码(连接指向本地主机),希望减少网络使用情况......但情况更糟!
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秒!
我知道我有四个独立的主机需要沟通,所以这不能是即时的。但是我需要遍历大概10m记录的集合。在每7k 2秒的时间内,这需要只需一小时!我不能有这个!
顺便说一句,我是新来的蟒蛇/蒙戈的世界里,我已经习惯了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秒)方法之间的巨大差异?谢谢!
我的所有主机都是ec2实例,所以网络延迟不是问题,从APPSERVER ping分片服务器需要0.400ms – Landon
这些40k文档的平均大小是多少? – JohnnyHK
该集合上的stat()显示:'“avgObjSize”:835.3698755446427,' – Landon