2012-02-15 2 views
15

셀/리더 배치를위한 단일 실패 지점 인 celerybeat를 해결하기 위해 권장되는 솔루션을 찾고 있습니다. 나는 웹을 검색하여 지금까지는 아무 것도 발견하지 못했습니다.단일 실패 지점 인 셀리 비트 주위에서 작업

내 경우, 하루에 한 번 스케줄러가 반나절 이상 실행할 수있는 일련의 작업을 시작합니다. celerybeat 인스턴스는 하나만있을 수 있으므로 실행중인 서버 나 서버에 문제가 발생하면 중요한 작업은 실행되지 않습니다.

신뢰할 수있는 (클러스터 된 또는 이와 유사한) 스케줄러가 필요한 유일한 사람이 될 수는 없으므로 이미이 솔루션을 사용하고 싶습니다. 필자가하지 않으면 일종의 데이터베이스 기반 스케줄러에 의존하고 싶지 않습니다.

답변

5

이에 대해 샐러리 github repo에 공개 문제가 있습니다. 비록 그들이 그것에 종사하고 있는지 모른다.

임시 해결책은 특정 PeriodicTask 인스턴스가 한 번에 하나만 실행되도록 작업에 대한 잠금을 추가 할 수 있습니다. 같은

뭔가 :

if not cache.add('My-unique-lock-name', True, timeout=lock_timeout): 
    return 

잠금 제한 시간을 알아내는 까다로운 잘입니다. 다른 셀러리 비트가 다른 시간에 실행하려고하면 0.9 * 작업 run_every 초를 사용합니다. 0.9 약간의 여유를두기 만하면 (예 : 셀러리가 일정보다 조금 늦은 경우 일정 시간이 지나면 잠금이 계속 활성화됩니다).

그런 다음 모든 시스템에서 celerybeat 인스턴스를 사용할 수 있습니다. 각 타스크는 모든 셀로 비트 인스턴스에 대해 대기 행렬에 있지만 하나의 타스크 만 실행을 완료합니다.

작업은 여전히 ​​run_every를 존중합니다. 최악의 시나리오 : 작업은 0.9 * run_every 속도로 실행됩니다.

이 경우 한 가지 문제 : 작업이 대기 중이지만 예정된 시간 (예 : 대기열 프로세서를 사용할 수 없었기 때문)에서 처리되지 않은 경우 잘못된 시간에 잠금이 설정되어 다음 작업이 실행되지 않을 수 있습니다. 이 문제를 해결하려면 작업이 다소 시간이 걸리는지 여부에 관계없이 일종의 탐지 메커니즘이 필요합니다.

여전히 프로덕션 환경에서 사용할 때는 일반적인 상황이 아니어야합니다.

또 다른 해결책은 celerybeat 스케줄러를 서브 클래스 화하고 해당 틱 메소드를 대체하는 것입니다. 그런 다음 모든 틱에 대해 작업을 처리하기 전에 잠금을 추가하십시오. 이렇게하면 같은 주기적 작업을 가진 셀리 비트 만 동일한 작업을 여러 번 대기시키지 않습니다. 각 틱마다 하나의 셀리 비트 (하나의 경쟁 조건을 획득 한 사람) 만 작업을 대기열에 넣습니다. 한 셀로선에서 다음 틱으로 다른 플레이어가 레이스에서 이길 것입니다.

물론 첫 번째 해결 방법과 함께 사용할 수 있습니다.

물론이 작업을 위해서는 캐시 백엔드를 모든 서버에 대해 복제 및/또는 공유해야합니다.

오래된 질문이지만 누구에게나 도움이되기를 바랍니다.