异步入库问题
来源:14-12 scrapy写入数据到elasticsearch中 - 1
慕数据8096394
2020-05-06
bobby老师,想问一下异步入库的问题,
问题如下:
1. 是否可以通过异步发送请求来解决ES异步入库的问题
2. 如何在pipeline文件中异步发送请求
3. 入库通用写法的讨论
4. scrapy多线程下的异步入库的讨论
讨论如下:
问题1的讨论
因为ES本身有提供写入数据库的REST API,那如果我们如下操作就可以达到异步入库的目的了:
- 构建一个REST请求语句,然后异步发送请求
- 而scrapy自带的Request就是异步的,那么就可以通过spider中yield Request出去
- url就是构建的写入ES的url,
问题2的讨论
但是这样下载内容就相当于在request中完成,而不是pipeline中,想的是在pipeline中发送异步的http请求,
- 如何能够在pipeline中调用scrapy的requests,scrapy自带的make_request_from_url是否可以
- grequests库或者gevent+requests
问题3的讨论
推而广之,现有的异步入库的方法
- 异步框架实现的方法asyncio/gevent/twisted
- 将入库做成一个服务,对外提供一个接口(类似ES),然后异步发送请求
- 消息队列
- scrapy-redis,都写入redis,然后写一个方法逐步获取后写出
个人看法
- 方法1 最省时省力,效果也最好
- 方法2 针对特定的情况比较简单(如ES,只需要构建REST API语句) 其他情况比较费力,且费时(需要发送和处理请求)
- 方法3 通用性强,也不算费力
- 方法4 比较费力,也比较慢
问题4的讨论
scrapy默认是REACTOR_THREADPOOL_MAXSIZE=10个线程的,会有一些线程在处理其他事情,所以不是10个线程都能用,那如果我开20个线程,在这些线程中同步的入库方法
是不是就可以看成是异步的方法
比如在其他语言中,可以开多个线程每个线程进行自己的爬取,执行自己的入库语句,而在scrapy中把线程数量和并发请求分开配置了,官网这里的说明也不是很清楚
1回答
-
bobby
2020-05-09
非常赞的想法,能提到这些说明你对异步io有了很好的理解,这种讨论的意义很大,而且每个都说到了点子上,关于这里的讨论有几个疑问:
1. 构建scrapy的Request可以完成这个效果,但是这样做,就没法使用elasticsearch dsl这个强大的库了
2. 如果不使用elasticsearch dsl这种库后期接口越来越多是不是意味着代码很难维护。因为有太多的request是为了解决入库es的问题
3. 后期如果不入库es了,是不是这些代码都要移除,难度会不会大,万一某个地方搞错了爬虫是不是会挂掉
结合上面的问题,其实我个人更加推荐的做法是解析到item以后,自己写一个pipeline,这个pipeline将item写入到消息队列中,可以选择redis,rabbitmq,不过我个人更加推荐使用kafka,然后自己再写一个系统去读取item并入库,这个系统中你爱用什么用什么,使用asyncio也行,后期如果入库的逻辑或者数据库变化了,比如想入库到hbase中也不会影响scrapy的逻辑,连个系统中不会互相影响。大家有意见可以进一步讨论
00
相似问题