请求管理业务
- 请求去重管理:防止重复请求。(可以布隆过滤器)
- 请求缓冲管理:临时存储请求
- 常用数据结构:队列 Queue(常用), 列表,字典,元组
- 请求调度管理:派遣并控制请求调度顺序,请求优先级管理
- 请求调度优先级
- 广度优先(FIFO队列)
- 深度优先(LIFO队列)
- 权重优先(优先级队列)
- 请求调度优先级
队列
临时队列
- 内置队列模块 (Queue 常用于多线程,多进程从mutiprocess中引入)
- asyncio中的队列模块
- gevent中的队列模块
- tornado中的队列模块
为什么有这么多的队列? 因为每个队列一般都和异步模型,多线程,多进程通信用的,由于每个异步模型,在底层实现的原理不同,所以通信的时候处理方式有不同,所以会有多个队列模块。 但每个队列模块,api基本一样
持久化队列
- scrapy - queuelib 队列 (硬盘中 disk_queue),基于
- 有基于文件 sqlite 的 持久化
- pyspider - redis_queue 模块
- 基于 redis 的队列
- fifo队列 用 lists 列表,lpush,rpop
- lifo队列 用 lists 列表,lpush,lpop
- 优先级队列,用 Sorted Set 有序集合,zadd ,zrang ,zrem
- 基于 redis 的队列
redis锁及分布式锁
- 因为在实现优先级队列时,zrange 取出队列中的值后,再zrem删除这个值(符合队列取出的逻辑),这中间会时间间隔,会出现多线程取值错误的情况
- 所以需要锁机制
- 一般redis事务也可以保证操作的原子性,但是不像mysql事务,不能百分百保证
redis锁
- 一般用在单进程的多线程场景,如果是多进程的场景,则需要使用分布式锁
- 说明:
- 使用了锁机制后,能确保在同一份数据只会被某一个线程获取到,而 不会被多个线程同时获取,从而保证了数据不会被处理多次的情况发 生 2.此处相当于实现了同一个线程内部zrange与zrem是一个原子性操作