>데이터 베이스 >Redis >Redis 낙관적 잠금을 기반으로 동시 큐잉을 구현하는 방법

Redis 낙관적 잠금을 기반으로 동시 큐잉을 구현하는 방법

WBOY
WBOY앞으로
2023-06-04 09:58:091622검색

redis를 사용하여 scrapy 실행 횟수를 제어하는 ​​수요 시나리오가 있습니다. 시스템 배경을 4로 설정한 후 scrapy는 최대 4개의 작업만 시작할 수 있으며, 초과하는 작업은 대기열에 대기하게 됩니다.

개요

최근 django + scrapy + celery + redis 크롤러 시스템을 구축했습니다. 다른 프로그램을 실행하는 것 외에도 고객이 구입한 호스트도 제가 개발한 프로그램 세트를 실행해야 하므로 수동으로 제어해야 합니다. 방지해야 할 스크랩 인스턴스 수 너무 많은 크롤러가 시스템에 부담을 줍니다.

프로세스 설계

1. 크롤러 작업은 요청 형식으로 시작되며 모든 사용자 요청은 대기열에 포함되도록 셀러리에 입력됩니다.
2 작업 번호 제어 실행은 리드에 넘겨집니다. , 크롤러 시작에 필요한 필수 정보를 가져오고 크롤러를 시작하기 위해 Redis에서 정보를 가져오는 것을 포함하여 셀러리를 통해 Redis에 저장됩니다.
3 다음을 결정하기 위해 scrapyd 인터페이스를 통해 현재 실행 중인 크롤러 수를 가져옵니다. 단계: 4보다 작으면 redis에서 가져옵니다. 크롤러를 시작하려면 해당 정보를 가져옵니다. 4보다 크거나 같으면 계속 기다립니다.
4 실행 중인 크롤러 수가 감소하면 가져옵니다. 크롤러를 시작하는 데 필요한 시간에 맞춰 리드에서 해당 정보의 양을 가져옵니다.

코드 구현

비즈니스 코드는 약간 복잡하고 장황합니다. 여기서는 의사 코드를 사용하여 설명합니다.

import redis

# 实例化一个redis连接池
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, decode_responses=True, db=4, password='')

r = redis.Redis(connection_pool=pool)
# 爬虫实例限制为4 即只允许4个scrapy实例在运行
limited = 4

# 声明redis的乐观锁
lock = r.Lock()

# lock.acquire中有while循环,即它会线程阻塞,直到当前线程获得redis的lock,才会继续往下执行代码
if lock.acquire():
	# 1、从reids中取一条爬虫信息
	info = redis.get() 
	
	# 2、while循环监听爬虫运行的数量
	while True:
		req = requests.get('http://127.0.0.1:6800/daemonstatus.json').json()
		# 统计当前有多少个爬虫在运行
		running = req.get('running') + req.get('pending')
		
		# 3、判断是否等待还是要增加爬虫数量
		# 3.1 如果在运行的数量大于等于设置到量 则继续等待
		if running >= limited:
			continue
		
		# 3.2 如果小于 则启动爬虫
		start_scrapy(info)
		# 3.3 将info从redis中删除
		redis.delete(info)
		# 3.4 释放锁
		lock.release()
		break		

현재 이것은 실제 비즈니스 로직이 다음과 같이 매우 복잡할 수 있습니다.

작은 구덩이

scrapy의 시작 속도는 상대적으로 느리기 때문에 while 루프에서 크롤러를 시작하기 위해 코드가 실행될 때 잠시 대기 상태를 유지한 다음 scrapyd 인터페이스를 통해 크롤러 실행 횟수를 얻어야 합니다. 바로 읽으면 오판의 원인이 될 수 있습니다.

위 내용은 Redis 낙관적 잠금을 기반으로 동시 큐잉을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제