2013-10-14 1 views
0

일부 조건에 따라 사진의 일치 항목을 찾는 작업자가 있습니다. 각 사진은 고유 한 성냥을가집니다.Sidekiq가 데이터베이스를 병렬로 수정하지 못하도록하는 방법

class PhotoDeliveryWorker 
include Sidekiq::Worker 

def perform(photo_id) 
    photo = Photo.find(photo_id) 
    unless photo.match 
    matches = Photo.where(some_condition: "some_value") 
    match = matches.first 

    if match 
     # Do something to photo 
     photo.match = match 

     if photo.save 
     match.some_condition = "another_value" 
     else 
     schedule photo_id 
     end 
    else 
     # Couldn't find a match 
     schedule photo_id 
    end 
    end 
end 
private 
def schedule(photo_id) 
    PhotoDeliveryWorker.perform_in 1.hours, photo_id 
end 
end 

당신이 볼 수 있듯이, 작업자가 조건을 통과 한 후 향후 근로자에서 제외하는 match을 변경 목록과 일치하는 첫 번째 모델 객체를 가져옵니다 I는 다음과 같이 코딩.

문제는 한 번에 여러 명의 작업자가 수행 할 때 모두 동일한 matches 목록을 얻고 결과적으로 동일한 엔티티를 수정하는 것입니다. 하지만 각 사진마다 고유 한 일치가 필요합니다.

어떻게 해결할 수 있습니까?

추가 정보 :

Q : 왜 근로자를 이용합니까?

A : 일치하는 항목을 찾을 수없는 경우 나중에 다시 시도해야합니다.

Q : Sidekiq를 여러 스레드와 함께 사용하는 이유는 무엇입니까?

A : 최대한 빨리 사진을 처리해야합니다.

아마 각각의 시작 부분에 현재 활동중인 직원의 수를 얻고 첫 번째가 아닌 n 번째 일치를 얻을 수 있습니다. 하지만 그 해결책은 약간의 냄새가 난다.

UPDATE :

추가 질문 : 액티브가이 문제를 잠금에 대해 뭔가를 사용할 수 있을까요? 나는 with_lock과이 모든 것들에 익숙하지 않다.

+0

이렇게하기 위해 원시 SQL로 드롭 다운 할 수 있습니다 :'UPDATE photos SET match_id =? 여기서 id =? match_id는 NULL이다. 이렇게하면 첫 번째 업데이트 만 레코드를 찾아 업데이트합니다. –

+0

간단한 조건으로 가정하면, 사진 ID로 조건 당 redis list/set를 유지하고 'BRPOP'또는 'RPOP'를 사용하여 일치하는 ID를 가져오고이 ID가 결코 재사용되지 않도록 할 수 있습니다. 편집 : 아마 모든 ID가있는 목록/세트를 처리하여 재발행되지 않도록 할 수 있습니다. – lwe

답변

0

문제에 대한 매우 간단한 해결책은 작업량을 분리하여 작업자가 서로 간섭하지 않도록하는 것입니다.

근로자가 2 명인 경우 번호를 부여하고 photo.id % 2의 모듈로 계산할 수 있습니다. 이 방법으로 결과로 0과 1 만 얻습니다. 번호 0을 가진 작업자는 그의 일괄 처리에서만 작동하고, 번호 1을 가진 작업자는 다른 작업에서 작동합니다. 모듈러스를 늘리면 원하는 수의 직원까지 갈 수 있습니다.

+0

실제 코드는 훨씬 더 복잡하며 각 사진에 대해 가능한 실제 일치 항목 집합이 다를 수 있습니다. 그래서 그들은 평등하지 않으며, 나는이 목록을 각 근로자를위한 섹션으로 나눌 수 없습니다. 그러나 흥미로운 제안에 감사드립니다! – Bardt

+0

또 다른 쉬운 해결책은 성냥과 함께 노동자 ID를 유지하는 것입니다, 그래서 그들은 그 길을 떠날 수 있습니다. – phoet

+0

이런 종류의 작업을 수행하는 일반적인 방법은 다른 근로자에게 성냥을 발행하는 주요 작업자를 배치하는 것입니다. 그래서 당신은 단 하나의 작업자가 성냥을 발견 할 책임이 있고, 나머지는 어려운 일을하고 있으며 단 하나의 성냥을 할당받습니다. – phoet

관련 문제