目前情况:
一个 50 个目标网站的爬虫项目,有个 200 台的集群服务器。
爬取的内容基本上是从列表页(需要翻页)开始,抓取详情页 url,然后通过 url 抓取详情页内容。
目前架构:
master(mian) 写 redis 队列任务
slave(worker) 读 redis 队列,抓取网页,解析网页,储存网页。大部分逻辑都在这里。
如果 worker 遇到了新任务,例如任务是列表页,新任务就是详情页。还需要由 worker 把新任务写到 redis ……
目前遇到的问题:
每次增加新的目标网站,都需要把 worker 集群全部更新代码
因为 worker 中集成了太多例如解析/储存这样的功能。
####于是我有个一个新的构想。
把 worker 功能抽离出来,只让集群负责抓取网页。
由 main 负责抓取之后的解析 /存储。
这样的好处就是 worker 集群代码基本保持不动,所有改动都集中在 main 服务器上。
不知道这样设计是否有问题?我觉得储存可能会有瓶颈。
####之前还有一个想法
是把“解析逻辑”和“储存逻辑”也通过任务队列传递给 worker,但是传来传去,还有新的任务生成,任务堆堆叠叠变得无比复杂。半放弃状态。
##各位兄弟姐妹,这个架构到底应该怎么设计啊?
1
p2pCoder 2018-05-15 15:35:11 +08:00
可以考虑用微服务
抓取之后的解析和存储写成微服务(根据解析和存储对资源的不同要求可以再往下拆分) 可以根据爬取的网站去映射不同的微服务,网站不同 URL 解析存储微服务下不同的方法 这样每增加一个网站,就只用新写一个服务,然后注册服务,然后,爬取的结果加上 URL 通过与服务注册与发现中心交互就可以发现相应的微服务,把网页元数据发过去 解析,存储,可扩展性就很好 我们大数据老板当时参考 spring cloud 设计这样的爬虫架构,我也折腾了一下 eureka zk consul 与 pythonjiaohu,不过最后整个爬虫项目组砍了,这些也没是实际用 |
2
kslr 2018-05-15 15:47:31 +08:00
解析逻辑:维护一个 list 包含目标和解析规则通过消息队列平均分配给 work
存储逻辑:发送队列、RPC 返回、直接存储 看你的要求 |
3
woscaizi 2018-05-15 15:52:12 +08:00 via iPhone
@p2pCoder 这样相当于把 woker 现有的功能做纵向拆分,把解析网页服务做横向扩展吧?比楼主 master 做网页解析速度更快。不过网页解析服务每当程序修改还需要修改每个节点的程序。
|
4
p2pCoder 2018-05-15 16:28:33 +08:00
@woscaizi 不用修改 每个节点的程序,每新加一个网站,就写一个微服务,微服务可以部署多个
可以写个路由,来根据 url,根据域名来动态映射到服务,根据 url 路径映射到具体解析的接口,然后直接去服务注册于发现中心 去获取 服务实例,调用相关借口 服务 不用 部署到每个节点,而是根据需要增加服务的数量 |
5
hippoboy OP @p2pCoder 其实这个微服务也可以启在 main 上,这样微服务的这台服务器集中解析存储操作。其实更简单的是不是不用微服务,直接让 worker 把 raw_page 用队列退推回到 main 就行了,main 起多个协程处理就得了,和我改进的想法本质差不多吧?还是我有什么误解?
|
6
p2pCoder 2018-05-15 17:17:05 +08:00
@hippoboy 最核心的问题是,main 起多个协程这个操作,有没有与 main 本身实现解耦,可不可以做到新加一个网站,就可以随时起一个协程,并动态调用到,说白了
就是动态增加一个爬取网站,可不可以实现 ,直接新写 一段代码,然后,部署,就可以直接解析,存储你的 raw_page,不用修改以前的代码,也不用改变以前的部署 还有 main 本身如何实现扩展,当单机网络 io 或者磁盘 io 或者 cpu 陷入瓶颈的时候,如何提高 存储和解析的能力 |
8
snal123 2018-05-15 21:52:48 +08:00 via iPhone
爬虫萌新不懂为什么不用 scrapy
|
9
hippoboy OP @snal123 [请问使用 scrapy 的优势是什么?直接用 requests 不是很简单?]( https://www.v2ex.com/t/306922)
|