首页 体育 教育 财经 社会 娱乐 军事 国内 科技 互联网 房产 国际 女人 汽车 游戏

每一位爬虫工程师都应该学习Kafka

2019-12-19

拍摄: 产品司理

与产品司理环游世界的瞬间

这篇文章不会涉及到Kafka 的具体操作,而是告知你 Kafka 是什么,以及它能在爬虫开发中扮演什么重要人物。

假定咱们需求写一个微博爬虫,老板给的需求如下:

开发爬虫对你来说十分简略,所以三下五除二你就把爬虫开发好了:

接下来开端做报警功用,逻辑也十分简略:

再来看看计算关键词的功用,这个功用背面有一个网页,会实时显现抓取数据量的改变状况,能够显现每分钟、每小时的某个关键词的抓取量。

这个功用对你来说也挺简略,所以你完结了如下逻辑:

最终一个需求,对微博数据进行情感剖析。情感剖析的模块由其他部分搭档开发,你要做的便是每个小时拉取一批数据,发送到接口,获取回来,然后存入后端需求的数据库:

使命完结,所以你快乐地回家睡觉了。

跟着老板逐步添加新的关键词,你发现每一次完好抓取的时刻越来越长,一开端是2分钟抓取一轮,后来变成10分钟一轮,然后变成30分钟一轮,接下来变成1小时才干抓取一轮。跟着推迟越来越高,你的报警越来越不精确,微博都发出来一小时了,你的报警还没有发出来,由于那一条微博还没有来得及入库。

你的爬虫技能十分好,能绕过一切反爬虫机制,你有无限个署理 IP,所以你轻轻松松就把爬虫进步到了每秒一百万并发。现在只需求1分钟你就能完结悉数数据的抓取。这下没问题了吧。

可是报警仍是没有发出来。这是怎么回事?

经过排查,你发现了问题。数据抓取量上来了,可是 MongoDB 却无法一起接纳那么多的数据写入。数据写入速度远远小于爬取数据,很多的数据堆积在内存中。所以你的服务器爆破了。

你紧迫建立了100个数据库并编号0-99,关于抓取到的微博,先把每一条微博的 ID对100求余数,然后把数据存入余数对应的 MongoDB 中。每一台 MongoDB 的压力下降到了原本的1%。数据总算能够即时存进数据库里边了。

可是报警仍是没有发出来,不仅如此,现在实时抓取量计算功用也不能用了,还有什么问题?

现在报警程序要遍历100个数据库最近5分钟里边的每一条数据,承认是否有需求报警的内容。可是这个遍历进程就远远超越5分钟。

由于微博的归纳查找功用不是依照时刻排序的,那么就会呈现这样一种状况,早上10:01发的微博,你在12:02的时分才抓到。

不管你是在报警的时分挑选数据,仍是挑选数据推送给 NLP 剖析接口,假如你是以微博的发布时刻来查找,那么这一条都会被你直接漏掉——当你在10:05的时分检索10:00-10:05这5分钟宣布的微博,由于这一条微博没有抓到,你天然查找不到。

当你12:05开端检索12:00-12:05的数据时,你查找的是发布时刻为12:00-12:05的数据,所以10:01这条数据虽然是在12:02抓到的,但你也无法挑选出来。

那么是不是能够用抓取时刻来查找呢?例如10:05开端检索在10:00-10:05抓取到的数据,不管它的发布时刻是多少,都检索出来。

这样做的确能够确保不漏掉数据,但这样做的价值是你有必要保存、检索十分十分多的数据。例如每次抓取,只需发布时刻是最近10小时的,都要保存下来。所以报警程序在检索数据时,就需求检索这5分钟入库的,实践上发布时刻在10小时内的悉数数据。

什么,你说每次保存之前查看一下这条微博是否现已存在,假如存在就不保存?别忘了批量写入时刻都不够了,你还预备分一些时刻去查询?

老板忽然来跟你说,关键词“篮球”里边有很多的关于 蔡徐坤的内容,所以要你把一切包括蔡徐坤的数据悉数删掉。

那么,这个过滤逻辑放在哪里?放在爬虫的 pipelines.py 里边吗?那你要从头部署一切爬虫。今天是过滤蔡徐坤,明日是过滤范层层,后天是过滤王一博,每天添加关键词,你每天都得从头部署爬虫?

那你把关键词放在 Redis 或许 MongoDB 里边,每次刺进数据前,读取一切关键词,看微博里边不包括再存。

仍是那个问题,刺进时刻原本就不够了,你还要查数据库?

好,关键词过滤不放在爬虫里边了。你写了一个脚本,每分钟查看一次MongoDB新增的数据,假如发现包括 不需求的关键词,就把他删去。

现在问题来了,删去数据的程序每分钟查看一次,报警程序每5分钟查看一次。中心必定存在某些数据,还没有来得及删去,报警程序就报警了,老板收到报警来看数据,而你的删去程序又在这时把这个脏数据删了。

这下好了,天天报假警,狼来了的故事重演了。

假如你在爬虫开发的进程中遇到过上面的许多问题,那么,你就应该试一试运用 Kafka。一次性处理上面的一切问题。

把 Kafka 参加到你的爬虫流程中,那么你的爬虫架构变成了下面这样:

这看起来好像和数据直接写进 MongoDB 里边,然后各个程序读取 MongoDB 没什么差异啊?那 Kafka 能处理什么问题?

咱们来看看,在这个爬虫架构里边,咱们将会用到的 Kafka 的特性:

与其说 Kafka 在这个爬虫架构中像 MongoDB,不如说更像 Redis 的列表。

现在来简化一下咱们的模型,假如现在爬虫只要一个需求,便是查找,然后报警。那么咱们能够这样规划:

爬虫爬下来的数据,直接塞进 Redis 的列表右侧。报警程序从 Redis 列表左边一条一条读取。读取一条检视一条,假如包括报警关键词,就报警。然后读取下一条。

这样做有什么优点?

由于报警程序直接从 Redis 里边一条一条读取,不存在按时刻查找数据的进程,所以不会有数据推迟的问题。由于 Redis 是单线程数据库,所以能够一起发动很多个报警程序。由于 lpop 读取一条就删去一条,假如报警程序由于某种原因溃散了,再把它发动起来即可,它会接着作业,不会重复报警。

但运用 Redis 列表的优势也是下风:列表中的信息只能消费1次,被弹出了就没有了。

所以假如既需求报警,还需求把数据存入 MongoDB 备份,那么只要一个方法,便是报警程序查看完数据今后,把数据存入 MongoDB。

可我仅仅一个岗兵,为什么要让我做后勤兵的作业?

一个报警程序,让它做报警的作业就好了,它不应该做贮存数据的作业。

而运用 Kafka,它有 Redis 列表的这些优点,但又没有 Redis 列表的坏处!

咱们完全能够别离完结4个程序,不同程序之间消费数据的快慢互不影响。但同一个程序,不管是封闭再翻开,仍是一起运转屡次,都不会重复消费。

从 Kafka 中一条一条读取数据,做报警相关的作业。程序1能够一起发动多个。关了再从头翻开也不会重复消费。

这个程序从 Kafka 中一条一条读取数据,每凑够1000条就批量写入到 MongoDB 中。这个程序不要求实时贮存数据,有推迟也不要紧。存入MongoDB中也仅仅原始数据存档。一般状况下不会再从 MongoDB 里边读取出来。

从 Kafka 中读取数据,记载关键词、发布时刻。按小时和分钟别离对每个关键词的微博计数。最终把计数成果保存下来。

从 Kafka 中读取每一条数据,凑够一批发送给 NLP 剖析接口。拿到成果存入后端数据库中。

4个需求都处理了,那么假如仍是需求你首要移除脏数据,再剖析怎么办呢?实践上十分简略,你加一个 Kafka 就好了!

除了上面的微博比如以外,咱们再来看看在开发通用爬虫的时分,怎么运用 Kafka。

在任何时分,不管是 XPath 提取数据仍是解析网站回来的 JSON,都不是爬虫开发的首要作业。爬虫开发的首要作业一直是爬虫的调度和反爬虫的开发。

咱们现在写 Scrapy 的时分,处理反爬虫的逻辑和提取数据的逻辑都是写在一个爬虫项目中的,那么在开发的时分实践上很难完结多人协作。

现在咱们把网站内容的爬虫和数据提取分隔,完结下面这样一个爬虫架构:

爬虫开发技能好的同学,担任完结绕过反爬虫,获取网站的内容,不管是 HTML 源代码仍是接口回来的JSON。拿到今后,直接塞进 Kafka。

爬虫技能相对一般的同学、实习生,需求做的仅仅从 Kafka 里边获取数据,不需求关怀这个数据是来自于 Scrapy 仍是 Selenium。他们要做的仅仅把这些HTML 或许JSON 依照产品要求解析成格局化的数据,然后塞进 Kafka,供后续数据剖析的同学持续读取并运用。

如此一来,一个数据小组的作业就分隔了,每个人做各自担任的作业,约定好格局,同步开发,互不影响。

上面描绘的功用,实践上有不少 MQ 都能完结。但为什么是 Kafka 而不是其他呢?由于Kafka 集群的功能十分高,在废物电脑上建立的集群能抗住每秒10万并发的数据写入量。而假如挑选功能好一些的服务器,每秒100万的数据写入也能轻松应对。

这篇文章经过两个比如介绍了 Kafka 在爬虫开发中的效果。作为一个爬虫工程师,作为我的读者。请一定要把握 Kafka。

下一篇文章,咱们来讲讲怎么运用 Kafka。比你在网上看到的教程会更简略,更容易懂。

重视本大众号,回复“爬虫与Kafka”获取本文对应的思想导图原图。

热门文章

随机推荐

推荐文章