我在写一个剧本:从数据库获取URL列表(大约10000个URL)
下载所有页面并将其插入数据库
解析代码
如果(某些条件)在数据库中执行其他插入操作
我有一个Xeon四核超线程,所以总共有8个线程可用,我在Linux下(64位)。在
我使用cStringIO作为缓冲区,pycurl来获取页面,BeautifulSoup来解析它们,MySQLdb来与数据库交互。在
我试图简化下面的代码(删除所有try/except,解析操作,…)。在import cStringIO, threading, MySQLdb.cursors, pycurl
NUM_THREADS = 100
lock_list = threading.Lock()
lock_query = threading.Lock()
db = MySQLdb.connect(host = "...", user = "...", passwd = "...", db = "...", cursorclass=MySQLdb.cursors.DictCursor)
cur = db.cursor()
cur.execute("SELECT...")
rows = cur.fetchall()
rows = [x for x in rows] # convert to a list so it's editable
class MyThread(threading.Thread):
def run(self):
""" initialize a StringIO object and a pycurl object """
while True:
lock_list.acquire() # acquire the lock to extract a url
if not rows: # list is empty, no more url to process
lock_list.release()
break
row = rows.pop()
lock_list.release()
""" download the page with pycurl and do some check """
""" WARNING: possible bottleneck if all the pycurl
connections are waiting for the timeout """
lock_query.acquire()
cur.execute("INSERT INTO ...") # insert the full page into the database
db.commit()
lock_query.release()
"""do some parse with BeautifulSoup using the StringIO object"""
if something is not None:
lock_query.acquire()
cur.execute("INSERT INTO ...") # insert the result of parsing into the database
db.commit()
lock_query.release()
# create and start all the threads
threads = []
for i in range(NUM_THREADS):
t = MyThread()
t.start()
threads.append(t)
# wait for threads to finish
for t in threads:
t.join()
我使用multithreading,所以如果某些请求超时失败,我不需要等待。该特定线程将等待,但其他线程可以继续使用其他url。在
Here除了脚本什么都不做时的屏幕截图。似乎有5个核心忙,而另一个不忙。所以问题是:我应该创建和线程数一样多的游标吗?在
我真的需要执行锁吗?如果线程执行执行.cur()但不是数据库提交()和另一个线程一起使用另一个查询执行并提交?在
我读过关于Queue类的文章,但是我不确定我是否理解正确:我可以使用它而不是执行锁+提取url+释放?在
使用multithreading我会遭受I/O(网络)瓶颈的困扰吗?使用100个线程,我的速度不会超过~500Kb/s,而我的连接可以更快。如果我转到multiprocess,我会看到这方面的一些改进吗?在
同样的问题,但是对于MySQL:使用我的代码,这方面可能存在瓶颈?所有这些锁+插入查询+释放都可以在某种程度上得到改进?在
如果方法是multithreading,那么100是一个高数量的线程吗?我的意思是,太多的线程执行I/O请求(或DB查询)是无用的,因为这些操作相互排斥?或者更多的线程意味着更高的网络速度?在