多线程与协程爬虫有很大区别吗?多线程转协程能优化多少?

2020-08-06 15:38:56 +08:00
 Te11UA
目前一个爬虫项目运行在 4c8g 下的机器,requests 运行在 4 进程* 400 线程下,单页面 200k 左右。
最近发现 CPU 和内存都有一点瓶颈,如果转成协程的话是否能优化爬取速率呢?
(不讨论反爬的情况,单纯从爬虫效率上看)
7678 次点击
所在节点    Python
54 条回复
auxox
2020-08-06 19:10:19 +08:00
系统优化的第一步是先找到瓶颈点
saberlong
2020-08-06 19:30:24 +08:00
@wysnylc 另外你可以找下百万 Go TCP, 百万 websocket 同时连接的文章。有每个连接使用 go 程,和 reactor epoll 的性能对比。
newmlp
2020-08-06 19:41:06 +08:00
@wysnylc 你的认知就觉得除了协程,就没其他办法一次发出几千几万个请求了?
Vibra
2020-08-06 19:54:35 +08:00
省了切换的时间,但是尽管有 Gil 的存在,因为线程 io 的自动切换,其实差不了太多。
wysnylc
2020-08-06 21:22:23 +08:00
@newmlp #23 你是不是回错人了
wysnylc
2020-08-06 21:24:37 +08:00
@saberlong #22 你是不是忘了 netty 是用什么写的?别无脑吹 go 了百万链接瓶颈根本不在线程协程而是内存带宽磁盘,线程创建也没那么耗费资源
给你个链接学学吧:
为什么 Java 坚持多线程不选择协程? - 大宽宽的回答 - 知乎
https://www.zhihu.com/question/332042250/answer/734115120
ClericPy
2020-08-06 21:25:13 +08:00
Talk is cheap, 试试就知道了

直接说结论:

1. 本次测试不记带宽发送本地端口的请求, 本地 server 使用 golang 默认的 net/http 简单实现的

2. 对比 httpx 协程和 requests 多线程, 二者都使用连接池复用连接. 前者比后者快了大概 20%(虽然后者被我负优化了...), 启用 uvloop 以后也没拉开太大差距.

3. 对比 aiohttp 和 requests, 不使用 uvloop 的时候前者是后者 3 倍, 开了 uvloop 大概 3068 qps, 是后者的 3.15 倍, 而 golang 内置的 net/http 测试也才 3300. 虽然很大因素是 aiohttp 内核很多地方使用 Cython 实现的...

4. 对比 windows vs linux, 前者是游戏本所以多核(但是只能用一个...), 后者在阿里云服务器上虽然单 CPU 但是有 uvloop 加成, 速度提高一倍

部分代码: https://github.com/ClericPy/torequests#benchmarks


一句话总结, 以上测试纯属娱乐不作数, 真想用快的, 就选 aiohttp 就好了

之前貌似还看到, 裸 uvloop 单核情况下和 golang 差不多
silencefly
2020-08-06 21:31:11 +08:00
多进程加协程
OysterQAQ
2020-08-06 21:45:56 +08:00
协程属于用户空间的多线程实现,有上下文切换 但是会比内核空间的上下文切换代价小很多,但是如果从瓶颈来看的话 需要看看要爬的网站是否有连接数以及速率的限制,楼上说 cpu 只有 4 核多线程没意义,但是其实爬虫这种 io 密集型场景,线程在 http 请求阻塞的时候是不占用 cpu 的,超过核心数的线程在这时候能更好的占满 cpu,不至于让 cpu 空转
wuhanchu
2020-08-06 22:06:08 +08:00
不应该一起用吗
chihiro2014
2020-08-06 22:10:35 +08:00
协程不就是单线程线程池么
wangritian
2020-08-07 01:56:01 +08:00
如果更换协程后仍然限制 1600 总并发,猜测 cpu 稍微减轻,内存较大下降;不限制并发,cpu 和带宽会有一个顶满
binux
2020-08-07 02:09:09 +08:00
@wysnylc 我发现你根本就没看懂这里讨论的问题是什么。
你用 netty 搞 IO 异步 + worker 线程和 python 的协程没有任何区别。
wnpllrzodiac
2020-08-07 07:28:01 +08:00
协程不能多核,自己开多实例。但是代码逻辑简单清晰易维护
xiaolinjia
2020-08-07 08:50:25 +08:00
@wnpllrzodiac 之前看过一个库,说是可以多进程+协程。叫 aiomultiprocess 。
cwjokaka
2020-08-07 09:25:40 +08:00
转成协程对应使用的库也要改成异步的,不小心用了阻塞的方法就完蛋
warcraft1236
2020-08-07 09:27:03 +08:00
看上边说 GIL 的,你们真的理解 GIL 是啥吗?他这个又不是 CPU 负载高,GIL 没啥影响
CriseLYJ
2020-08-07 09:45:57 +08:00
多进程+异步实现,充分利用多个 cpu,异步减少 cpu 资源消耗。
CODEWEA
2020-08-07 10:25:55 +08:00
你资源就那么大,再玩也没有招
knva
2020-08-07 11:28:55 +08:00
没啥区别,爬虫爬快了不怕对面 block ?

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

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

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

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

© 2021 V2EX