scrapy使用布隆过滤器

前言

搜一下scrapy布隆过滤器其实已经有现成的了,看了下代码发现还有能优化的地方,就在上面做了点优化

ScrapyRedisBloomFilter: https://github.com/Python3WebSpider/ScrapyRedisBloomFilter

优化点

代码里的去重逻辑主要是scrapy_redis_bloomfilter.dupefilter 这个文件,去重关键代码如下:
在这里插入图片描述
self.bf是一个布隆过滤器的实例。每执行一次bf.exists就会使用6个不同的hash函数计算出值,然后执行6次redis的getbit操作,判断相应的bit位。也就是说,bf.exists会和redis服务器进行6次交互操作,bf.insert也是6次,只是变成了setbit。(这里的6个指的是hash函数的个数,也就是设置的BLOOMFILTER_HASH_NUMBER 的默认值)

这就导致了去重一个url最少要和redis服务器交互6次(存在),最多是12次(不存在的情况)。如果网络差点或者数据量很大,那么去重所带来的网络开销会很大,同时也会卡住scrapy的异步逻辑,让scrapy变的很慢。

优化方式

redis其实已经实现了布隆过滤器,直接拿到用就行了,官方的优化肯定比咱们做的好。更重要的是,使用redis的布隆过滤器,只需要传一个url给redis服务端,服务端告诉你这个url存不存在,这样去重只需要和服务端进行一次交互就能完成。

python使用redis布隆过滤器
import redis

redis_url = "redis://127.0.0.1:6379"
server = redis.StrictRedis.from_url(redis_url, decode_responses=True)

bf = server.bf()
# redis key
key = "test"
# 错误率
errorRate = 0.001
# 去重数据量
capacity = 10000
if not server.exists(key):
    print(bf.create(key, errorRate, capacity))

for i in range(10):
    print(i, bf.add(key, f"http://www.httpbin.org/get?a={i}"))
for i in range(20):
    print(i, bf.add(key, f"http://www.httpbin.org/get?a={i}"))
for i in range(10):
    print(i, bf.exists(key, f"http://www.httpbin.org/get?a={i}"))

基本操作大概就是add和exists了,更多的命令看官方文档:https://redis.io/commands/?group=module。另外,python的接口和官方文档可能有点不一样,比如创建布隆过滤器,命令是BF.RESERVE,在python里的方法则是bf.create

要在redis中使用布隆过滤器,需要先加载一个插件,或者直接运行带布隆过滤器的docker版redis,这个可以参考:docker启动带布隆过滤器的redis

我是直接使用docker,如果要在docker设置redis的密码,启动命令如下:

docker run -d -p 6379:6379 --name redisbloom redislabs/rebloom:latest \
/usr/local/bin/redis-server \
--appendonly yes \
--requirepass "123456" \
--loadmodule "/usr/lib/redis/modules/redisbloom.so"

--requirepass 后面跟的就是密码

代码

改动的地方比较少,用上面的bf替换掉代码的bf即可

完整代码请看:https://github.com/kanadeblisst/scrapy_redis_bf

使用

安装

pip install scrapy-redis-bf

使用

将如下设置加入到scrapy项目的settings.py文件中

SCHEDULER = "scrapy_redis_bf.scheduler.Scheduler"

DUPEFILTER_CLASS = "scrapy_redis_bf.dupefilter.RFPDupeFilter"

REDIS_URL = 'redis://localhost:6379'

# 错误率
BLOOMFILTER_ERRORRATE = 0.001
# 去重量
BLOOMFILTER_CAPACITY = 10000
测试

GitHub项目的tests文件夹有个测试的scrapy项目,修改里面的REDIS_URL运行scrapy crawl test即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值