2013-04-10 6 views
0

이 대기열을보고있는 여러 작업자가있는 단일 작업 대기열이 있습니다. (각 작업은 단일 사용자에 해당). 주어진 시간에 대기열에있는 사용자 당 여러 작업이있을 수 있습니다.사용자 당 하나의 작업 만 주어진 시간에 작업자가 처리 할 수있는 작업 대기열 시스템 설계

저는 직원이 주어진 시간에 사용자 당 2 개 이상의 직업을 처리하는 것을 원하지 않습니다. 이 시간에이 사용자를 처리하는 다른 작업자가없는 경우에만 작업자가 작업을 선택해야합니다. 사용자의 작업이 작업자에 의해 처리되는 경우, 작업이 끝나 자마자 바로 다음 사용자 작업을 선택하기를 원합니다.

나는 근로자를 불가지론 자로 유지하고 싶다. (즉, 모든 근로자가 어떤 사용자의 일을 처리 할 수 ​​있어야한다.) 이렇게하면 수평으로 확장하는 데 도움이됩니다.

어떻게해야합니까? 나는 사용자 당 별도의 대기열을 만드는 방법에 대해 설명하고 있지만 작업자는 엄청난 수의 대기열을 감시해야하며 자원을 낭비 할 수 있습니다. 내가 지금 대기열 서버로 beanstalkd를 사용하고 있습니다.

도움을 주시면 감사하겠습니다.

답변

0

먼저 사용자 당 하나의 작업 만 처리하면 다른 사용자의 처리 작업이 극도로 지연 될 수 있습니다. 대기열에 user1에 대한 대량의 순차 작업 수가 포함되어 있고 user2에 대한 큰 연속 순차 작업 수가있는 시나리오를 고려해보십시오. 제안 된 아키텍처의 결과로 사용자 1 작업 큐를 비우게됩니다 처음으로 그리고 나서 user2 작업이 처리되기 시작하여 user3은 오랜 시간 동안 기다리게됩니다 ...

여러 개의 대기열 (여전히 사용자 당 하나는 아님)을 도입하고 작업을 라운드 로빈 방식으로 대기시킴으로써 상황을 완화 할 수 있습니다. 그러나 이것이 알 수 있듯이 여전히 100 % 신뢰할 만하지는 않습니다.

그러나이 요구 사항을 하나의 (또는 몇 가지) 대기열로 정말 보장하려면 실제로 공유 잠금 메커니즘 (예 : memcached)을 사용하여 해당 사용자에 대한 작업을 유지하면서 사용자 당 잠금을 유지하는 것이 좋습니다. 처리 중. This article에는 방법이 설명되어 있으며이를 수행하려면 gems이 있습니다. 다음 알고리즘을 사용할 수 있습니다.

job = @beanstalkd.reserve 
user_id = job.body["user_id"] 
if (get_lock_for(user_id) 
    # process job 
    # .... 
    job.delete 
end