문제

MySQL InnoDB 테이블에 엄청난 URL 목록이 있으며, 작업자가 처리 할 URL 세트를 위해 MySQL을 쿼리하는 작업자 프로세스가 있습니다. URL은 즉시 처리되는 것으로 표시되어야하므로 다른 작업자 프로세스는 동일한 처리를 시작하여 자원을 낭비하지 않도록해야합니다.

현재 나는 먼저 URL을 얻기 위해 이것을합니다.

SELECT DISTINCT url FROM urls WHERE task_assigned is NULL ORDER BY id LIMIT 100

그런 다음 코드에서 나는 각 URL을 순진하게 루프하여 처리중인 것으로 표시합니다.

UPDATE urls SET task_assigned = NOW() WHERE url = ? COLLATE utf8_bin

나는 이것이 얼마나 어리 석고 비효율적인지 완벽하게 알고 있습니다. 더 중요한 것은 다른 작업자 프로세스가 내 업데이트 중에 목록을 얻지 못할 것이라는 보장이 없다는 것이 중요하지 않습니다. 이것을하는 아름다운 방법은 무엇입니까? 거래로 만들어야합니까?

도움이 되었습니까?

해결책

MySQL에서 사용할 수있는 다음은 MySQL에서 사용할 수 있도록 나타납니다 (MySQL 5 매뉴얼을 한눈에). 그것이 최선의 접근법인지 확실하지 않지만 PostgreSQL에서 이전에 사용한 접근 방식입니다.

BEGIN TRANSACTION;
SELECT DISTINCT url FROM urls WHERE task_assigned is NULL ORDER BY id LIMIT 100 FOR UPDATE;
UPDATE urls SET task_assigned = NOW() WHERE url IN [list of URLs] COLLATE utf8_bin;
COMMIT;

실제로 PostgreSQL에서 나는 a를 사용한다 하나의 SELECT를 대신하여 업데이트의 반환 조항이있는 업데이트 명령문이지만 PostgreSQL 별 확장자입니다.

귀하의 접근 방식에서 볼 수있는 한 가지 잠재적 문제는 중복 URL입니다. IF URL http://www.example.com/ 테이블에 두 번 나타나고 ID 23과 42로 표시되면 SELECT 에서이 두 ID 중 하나로 반환되지만 업데이트는 두 행에 영향을 미칩니다. 귀하의 응용 프로그램에서 그 행동이 의미가 있는지 모르겠습니다. 아마도 URL에 어떤 종류의 고유 한 제약 조건을 넣을 수 없어서 발생할 수없고 URL이 아닌 ID 목록을 사용합니다. IN 조항 (더 빠르야 함).

다른 팁

먼저 모든 URL을 선택한 다음 스레드를 사용하여 비동기 적으로 구문 분석해야합니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top