2016-11-18 1 views
11

RabbitMQ와 함께 Celery를 사용하여 API 요청의 데이터를 처리하고 있습니다. 프로세스는 다음과 같이 진행됩니다셀러리 작업자 내 멀티 스레딩

요청 -> API -> RabbitMQ -> 셀러리 노동자 ->

가 이상적으로 더 셀러리 노동자를 생성 할하지만 메모리 제약에 의해 제한하고 돌려줍니다.

현재 내 프로세스의 병목 현상은 작업자에게 전달 된 URL에서 데이터를 가져 와서 다운로드하는 것입니다. 러피, 프로세스는 다음과 같습니다 URL을 가져 오는 동안 작업자가 잠시 동안 갇혀로이 용납

celery_gets_job(url): 
    var data = fetches_url(url) # takes 0.1s to 1.0s (bottleneck) 
    var result = processes_data(data) # takes 0.1ss 
    return result 

. 나는 스레딩을 통해이 개선을 찾고 있어요,하지만 난 가장 좋은 방법이 무엇인지 확실하지 오전 :

  • A의 같은 시간에 데이터를 처리하는 동안 들어오는 데이터 비동기 셀러리 작업자 다운로드를 만들 수있는 방법이 있나요 다른 스레드?

  • RabbitMQ를 통해 메시지를 전달하는 형태로 별도의 작업자 페치 및 처리를해야합니까?

+1

두 개의 다중 프로세스를 작성하여 샐러리 작업 내에서 [multiprocessing pipes] (https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Pipe)와 같은 것을 사용할 수 있습니다. 물론 멀티 프로세싱 프로세스는 풀로 제한되어야합니다. rabbitmq/result 백엔드를 통해 가져온 URL의 큰 데이터를 공유하면 내가 잘못하지 않았 더라면 좋지 않을 것입니다. 셀러리 낮은 수준의 api도 비슷한 종류의 기능을 가질 수 있습니다. –

+1

RabbitMQ에 대해 잘 모르겠지만'celery_gets_job'이 여러 개의 비 원자 연산을 가지고 있고 멀티 스레딩을 사용하는 동안 문제가 발생하므로 다중 처리라는 것이 멀티 스레딩보다 더 적합 할 것이라고 생각합니다. 'fetches_url (url)'을 실행하는 프로세스 풀과'processes_data (data)'를 수행 할 다른 프로세스에 의해 데이터가 채워지는 큐를 사용할 수 있습니다. – shrishinde

+0

http : // stackoverflow. com/questions/28315657/celery-eventlet-non-blocking-requests – fpbhb

답변

1

eventlet 라이브러리를 사용하면 표준 라이브러리를 패치하여 비동기로 만들 수 있습니다.

먼저 수입 비동기 urllib2가 :

from eventlet.green import urllib2 

그래서 당신이 URL에 몸을 얻을 것이다 :

def fetch(url): 
    body = urllib2.urlopen(url).read() 
    return body 

eventlethere를 참조하십시오.

+2

또한 이벤트 릿 실행 풀을 직접 사용하면 http://docs.celeryproject.org/en/latest/userguide/concurrency/eventlet.html에서 자동으로 원숭이 패치 io 호출을 수행해야합니다. – dyeray

+0

그렇다면'processes_data (data)'는 여전히 차단되어 결합 결과가 이전보다 느려 집니까? – ostrokach

0

하나는 데이터 다운로드 용이고 다른 하나는 다운로드 한 후 처리하기위한 두 가지 작업을 만듭니다. 이렇게하면 두 작업을 독립적으로 확장 할 수 있습니다. 참조 : Routing, Chains.