项目情况
最近做了一个爬虫系统,使用scrapy 作为核心,用kafka作队列,然后加上 java的消费者,还有其它周边服务,形成一个架构,这里进行一个简单的整理
基础结构
考虑到数据的扩展性和互联网的不确认性,考虑使用 nosql来存储大部分业务数据,同时为了更好的处理文字搜索, 于是决定使用elasticsearch + mysql的方式来处理.
然后,我们考虑了底层服务,这涉及到数据获取,解析与内容的保存,这一层的实现逻辑也有很多,经过找网上资料和讨论思考,我们决定采用python爬虫框架.
引入异步队列
但我们计算到,爬虫的数据量比较大,如果让一个流程同时做 获取,解析,整理,保存,会导致这个流程过长,是一件风险比较大的事,而且,爬虫的网络环境和,整理保存的环境不太一样,耦合到一起不是靠谱的事.所以我们引入了异步结构,使用kafka作为我们的消息队列,接收python来的数据. 同时提供一个消费者对数据进行消费.
引入定时器
同时,对爬虫获取数据的时机,我们需要有一个爬虫开启的,有两种方案,1让python进程自己定时执行,2,引入外部进程管理. 考虑到内聚原则,我们采用2方案,同时这个外部进程定时器也可以做其它的定时工作,统一管理.
形成集群
当然,一个进程,尤其是python爬虫,速度太慢(单机网络请求,线程不够等),我们要引入集群.
爬虫,kafka和消费者,是各自集群,节点和节点没有直接的联系,实际上es和mysql也可以是集群,不影响讲述,这里没有描述 出来
最终情况
webapi的进程,涉及到用户, 和部分cms功能,于是也部分功能使用mysql,最后的结构大约如图.
其它说明
模块说明
图中对redis和logstach和其它一些第三方模块等的描述就没写上去了。
mysql处理如用户,权限,各种配置之类,es主要是存抓取的数据
关于集群
虽然好几个地方都用了集群,但其机制不尽相同
python爬虫的集群是 在redis中保存requests,是用scrapyd 的一个web服务来提供,可以开很多job,一个job即一个进程,所以实际上这一集群节点不只两个,这一块内容可查看本博客的关于爬虫的文章
kafka是第三方的,且其有数据存储,除了节点状态的保持,其数据分片和副本也是有的,请自行查看其它文章
消费者是一个java进程,其集群 很简单,对kafka进行partition的指定,这一块用kafka的client即可,本身的业务逻辑不多。
关于一些改进的思考
批量处理
数据量大的话,批量是一个值得考虑的地方,且其思路不局限在一个功能点.
比如,消费者->es中,可以保存起来批量入,或者引入logstach来处理。
任务和任务之间的关联
从逻辑层面上,任务之间的先后是个很考究的事情,还有其花费时间会不会对其它任务有干扰。这个要看业务
另一方面,前一个任务的处理结果,是否是后一个数据的入参,这个情况可以考虑用redis来达到数据的共用.