CURDboy 问问各位,mysql 怎么多线程 insert 数据啊...

2017-12-19 17:55:43 +08:00
 Va1n3R

python3 写了个爬虫。
多线程爬取数据写入数据库
一开始使用的是 sqllite3,一直提示 database is blocked,后来发现 sqllite 不支持多线程读写
然后谷歌搜了一下,看到了别人推荐使用 mysql 来做这种任务...我只会基础的 CURD 操作,用了简单的多线程来操作,然而 mysql 貌似也不能直接多线程插入数据,stackoverflow 里面的老哥们说是需要建立连接池...头疼,之前只接触过基础的操作,请各位 V2er 赐教
python3 代码:

def getExin():
    while not Q.empty():
        i = Q.get()
        .*
        try:
            .*
        except :
            continue
        try:
            c.execute("INSERT INTO exin (username, password) \
                  VALUES (%s,'%s')" % (username, password))
            conn.commit()
        except:
            pass


for i in range(0, 99475):
    if len(str(i)) < 5:
        i = (5 - len(str(i))) * "0" + str(i)
    Q.put(i)

threads = []

conn = connect(user='root', password='root', database='test')
c = conn.cursor()
for i in range(800):
    x = threading.Thread(target=getExin,args=())
    threads.append(x)
for t in threads:
    t.start()
c.close()
print("All done")
3657 次点击
所在节点    Python
24 条回复
misaka19000
2017-12-19 18:01:57 +08:00
一个线程对应一个链接就行了
alvinbone88
2017-12-19 18:12:10 +08:00
Va1n3R
2017-12-19 18:23:43 +08:00
@misaka19000 尝试过会提示连接不上,我这里是 1000 线程
zeraba
2017-12-19 18:27:29 +08:00
executemany 不行么 是什么场景非要多线程多个事务去写入哪
Va1n3R
2017-12-19 18:30:07 +08:00
@zeraba 访问一次目标获取一次信息,然后写入数据库,就这么简单的逻辑,但是单线程太慢了...
zeraba
2017-12-19 18:36:42 +08:00
@Va1n3R 要么一次一次写 redis 要么把取回的数据先存成 list 或者 tuple 到了一定的量再批量插入 mysql 你这么搞 太费资源了
Va1n3R
2017-12-19 18:47:00 +08:00
@zeraba 资源不是问题,只是不想把简单问题复杂化,谢谢老哥啦
Cooky
2017-12-19 19:00:05 +08:00
你这只是一个连接多线程使用吧
kiwi95
2017-12-19 19:02:08 +08:00
你现在 Q 是共享的,那 Q 的 get,put 是不是阻塞的?然后多个线程也是操作一个连接作数据插入,这样多线程有什么意义呢,除非你的数据准备阶段占时间开销的大头,否则这样并不能提升速度
likuku
2017-12-19 19:10:46 +08:00
老生常谈提示下:得用 InnoDB
Va1n3R
2017-12-19 19:49:43 +08:00
@Cooky 我尝试过多线程每个都链接一次,但是 mysql 会拒绝我的访问....我开了 800~1000 的线程
Va1n3R
2017-12-19 19:50:48 +08:00
@kiwi95 Q 是 queue,应该不会阻塞吧,速度提升确实肉眼可见啊...
Sanko
2017-12-19 20:27:23 +08:00
executemany 应该不慢吧
Va1n3R
2017-12-19 22:39:17 +08:00
@Sanko
@zeraba 数据量挺大的,直接放入字典,我怕内存会爆啊
Cooky
2017-12-19 23:57:09 +08:00
@Va1n3R 看看 MySQL 默认最大连接数多少,改下配置
HanSonJ
2017-12-20 00:02:21 +08:00
这种情况,批量 insert 最佳

插入速度优化上百倍
billlee
2017-12-20 00:16:19 +08:00
你如果不批量插入,开再多线程,HDD 上一秒也只能提交 100 个事务。
jimzhong
2017-12-20 04:29:27 +08:00
你开多线程获得的性能提升未必有批量插入大。
huhujin
2017-12-20 09:22:40 +08:00
我瞎比说说:
for i in range(800):
x = threading.Thread(target=getExin,args=())
t.setDaemon(True)
x.start()
2ME
2017-12-20 09:26:17 +08:00
不懂 py .. 不过你这么搞肯定有问题 线程开太高 mysql 最大连接数会有问题 就算连得上 你 IO 还是会有问题 和#18 说的一样 你开多线程不一定有拼接 sql 批量插入来的实在

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/416052

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX