하나의 MySQL 인스턴스가 있고이 처리 작업을 실행하기 위해 n 서버의 연결을 추측하고 있습니다. 여기에 작업 대기열을 구현 중입니다.
당신이 언급 한 table
은 InnoDB 액세스 방법 (또는 Percona 또는 MariaDB에서 제공하는 다른 트랜잭션 친숙한 액세스 방법 중 하나)을 사용해야합니다.
테이블의 항목을 일괄 처리해야합니까? 즉, 그들은 어떻게 든 상호 연관되어 있습니까? 아니면 서버 프로세스가 하나씩 처리 할 수 있습니까? 이것은 중요한 질문입니다. 개별적으로 또는 작은 배치로 처리 할 수 있다면 서버 프로세스 간의로드 밸런싱을 향상시킬 수 있기 때문입니다. 작은 배치를 가정 해 봅시다.
아이디어는 다른 서버 프로세스에 해당 행이있는 경우 서버 프로세스가 테이블의 행을 점유하지 못하도록하는 것입니다. 나는 이런 종류의 일을 많이해야했고, 여기에 제 제안이 있습니다. 나는이 작품을 알아.
먼저 테이블에 정수 열을 추가하십시오. 그것을 "일하는"또는 그런 것으로 부르십시오. 기본값 인 0을 지정하십시오.
둘째, 각 서버에 영구 ID 번호를 할당하십시오. 서버의 IP 주소의 마지막 부분 (예 : 서버의 IP 주소가 10.1.0.123이고 ID 번호가 123 인 경우)은 사용 환경에 따라 고유하기 때문에 좋은 선택입니다.
그런 다음 서버가 작업 할 때이 두 가지 SQL 쿼리를 사용하십시오.
UPDATE table
SET working = :this_server_id
WHERE working = 0
AND time_scheduled < CURRENT_TIME
ORDER BY time_scheduled
LIMIT 1
SELECT table_id, whatever, whatever
FROM table
WHERE working = :this_server_id
첫 번째 쿼리는 일관되게 일괄 처리 작업을 수행합니다. working = 0
을 제외하고는 다른 서버 프로세스가 동시에 들어오는 경우 아무런 프로세스도 행을 가져올 수 없으므로 동일한 행을 가져 오지 않습니다. LIMIT 1은 배치 크기를 제한합니다. 당신은 이것을 할 필요는 없지만 그렇게 할 수는 있습니다. 나는 또한 가장 오래 기다렸던 행을 먼저 처리하기 위해 ORDER BY
을 던졌다. 그것은 아마도 일을하는 데 유용한 방법 일 것입니다.
두 번째 쿼리는 작업을 수행하는 데 필요한 정보를 검색합니다. 작업중인 행에 대해 기본 키 값 (table_id
)을 검색하는 것을 잊지 마십시오.
그런 다음 서버 프로세스는 필요한 모든 작업을 수행합니다.
완료되면 나중에 다시 대기열에 던져 넣어야합니다.이를 수행하려면 서버 프로세스가 time_scheduled
을 필요에 맞게 설정 한 다음 working = 0
으로 설정해야합니다. 예를 들어, 처리중인 각 행에 대해이 쿼리를 실행할 수 있습니다.
UPDATE table
SET time_scheduled = CURRENT_TIME + INTERVAL 5 MINUTE,
working = 0
WHERE table_id = ?table_id_from_previous_query
그게 전부입니다.
한 가지를 제외하고. 현실 세계에서 이러한 큐잉 시스템은 때때로 파열됩니다. 서버 프로세스가 중단됩니다. 등. 머피의 법칙을 참고하십시오. 모니터링 쿼리가 필요합니다. 이 시스템에서 쉽습니다.
이 쿼리는 그 작업을해야하는데 서버와 함께, 5 분 이상 연체 모든 작업의 목록을 제공합니다.
SELECT working, COUNT(*) stale_jobs
FROM table
WHERE time_scheduled < CURRENT_TIME - INTERVAL 5 MINUTE
GROUP BY WORKING
이 쿼리가 비어 있으면 모두 정상입니다. working
이 0으로 설정된 많은 작업이 발생하면 서버가 계속 작동하지 않습니다. 어떤 서버 ID 번호로 설정된 working
의 작업이 발생하면 해당 서버는 점심 시간을 보냅니다. 필요가있을 경우
당신은이 쿼리와 함께 점심을 사라 서버에 할당 된 모든 작업을 재설정 할 수 있습니다.
UPDATE table
SET working=0
WHERE working=?server_id_at_lunch
그런데 복합 지수가 (working, time_scheduled)
인 경우 실적이 좋을 것입니다.
mysql 서버가 모든 서버에서 공유됩니까? – user4035
예, 모두 동일한 서버에서 가져옵니다. – fandangosoeren