파비의 매일매일 공부기록

파이썬 병렬 프로그래밍 - #7 샐러리를 이용한 테스크 분산 본문

Study/Python

파이썬 병렬 프로그래밍 - #7 샐러리를 이용한 테스크 분산

fabichoi 2021. 7. 25. 23:30

이번장은 드디어 셀러리를 활용한 데스크 분산에 대한 내용이다.

이 전장들에서 파이프를 사용해 프로세스 사이에 통신을 구축하는 방법과

네트워크에서 다른 머신 사이에 프로세스를 분산하는 방법을 배웠다.

 

이번장에서는 셀러리 프레임워크를 사용해 다른 머신 사이에 태스크를 분산하는 방법을 살펴볼 것이다.

 

셀러리 이해

- 분산 시스템을 생성하는 동안 어려움을 줄여주는 메커니즘을 제공하는 프레임워크

- 네트워크로 서로 연결되는 머신 사이 또는 로컬 작업자 사이에 메시지를 교환하여 작업 단위(task)를 분산하는 개념으로 작동

- task는 셀러리의 핵심 개념, 분산해야 하는 어떠한 작업을 task에 미리 캡슐화해야 함.

 

왜 셀러리를 사용하는가

- 인터넷에 퍼진 작업자 사이나 로컬 작업자들에게 투명한 방법으로 태스크 분산 가능

- 설정을 통해 작업자의 동시성을 간단한 방법으로 변경

- 동기/비동기/주기/태스크 스케줄링을 지원

- 오류가 났을 때 태스크를 다시 실행

 

셀러리 아키텍처의 이해

- 끼울 수 있는 컴포넌트와 선택된 메시지 전송에 따라 프로토콜을 사용하는 메시지 교환 메커니즘에 기반을 둠

- 책의 그림을 간단하게 설명하면, 각 클라이언트들이 테스크를 보내면 큐에 저장되고 워커(작업자)가 테스크를 실행하고 결과 뒷단으로 보내면 클라이언트가 테스크의 결과를 읽는 식으로 구성되어있다.

 

태스크로 작업

- 클라이언트 컴포넌트는 태스크를 생성하고 중개인에서 디스 패치하는 기능을 가짐

- 셀러리 앱의 인스턴스를 통해 접근 가능한 @app. task 데코레이터를 사용해 태스크 정의를 보여주는 코드 예제가 소개된다.

- 태스크 타입에는 동기식, 비동기식, 주기식, 스케줄링 상태가 존재.

- 태스크 호출을 수행하면 AsyncResult 타입의 인스턴스 반환. 이 객체는 태스크 상태가 끝났는지 혹은 분명히 있는지 점검 후 존재하면 반환하는 객체. 이 메커니즘을 사용하려면 결과 뒷단(result backend)를 활성화해야 함.

- 태스크를 디스패치하려면 delay, apply_async 등의 메소드를 호출해야 함.

- delay : apply_async를 호출하는 가장 간단한 방법

- apply_async : 태스크 실행을 위한 파라미터 설정 가능.

- apply : 로컬 프로세스에서 비동기식으로 태스크를 실행. 결과가 준비될 때까지 봉쇄.

 

메시지 전송(브로커)

- 브로커는 셀러리에서 핵심 컴포넌트. 브로커를 통해 메시지를 주고받으며 작업자와 통신.

- 셀러리는 수많은 브로거를 지원. 그러나 일부 브로커에는 셀러리 메커니즘을 모두 구현하지 않음.

- 기능적으로 가장 완전한 것은 RabbitMQ와 Redis.

 

작업자 이해

- 작업자는 수신한 태스크를 실행하는 역할.

- 셀러리는 작업자 동작을 제어하는 최적의 방법을 찾기 위한 일련의 메커니즘을 제공.

- 동시성 모드 : 작업자가 수행하는 모드로 프로세스, 스레드, 이벤트렛, 게벤트가 있음

- 원격 모드 : 이 메커니즘을 사용하면 작업자의 실행 시간을 포함해 동작 변경에 목적을 둔 최우선 순위 큐를 통해 특정 작업자나 작업자 목록에 직접 메시지 전달 가능

- 태스크 취소 : 하나 이상의 작업자에게 하나 또는 여러 태스크 실행을 무시하라고 명령 가능.

 

결과 뒷단 이해(result backend)

- 태스크의 상태와 결과를 저장하고 클라이언트 애플리케이션에 반환하는 역할을 함

- RabbitMQ, Redis, MongoDB, Memcached 등을 사용한다.

 

여기서부터는 예제라서 다른 장과 마찬가지로 책을 참조하면 될 듯. 

 

책 예제 구현 후기.

후.. 일단 윈도우즈에서 redis, celery를 가지고 구현하려 했지만 안됨.

이유는 윈도우즈용 redis 버전이 3.0 이 마지막임. 그 이후로는 업데이트가 안됨 ㅠㅠ

그래서 결국 linux 노트북에 redis 설치 후 접속 시도했는데,

문제는 redis.conf에서 localhost 외에 접속 가능하도록

bind 127.0.0.1 :1 주석 처리하고

proected-mode 를 no로 변경해야 한다.

위의 옵션 빼먹으면 redis-server 실행은 되어 있으나 접속을 못함 ㅡㅡ

 

여튼 그러고 나서 기존 소스를 실행해도 계속

ValueError: not enough values to unpack (expected 3, got 0) 이런 오류가 발생한다.

구글링 해보니 pip install eventlet으로 eventlet 패키지를 설치 한 뒤에

celery 실행 시 옵션을

celery -A tasks worker -l info -P eventlet으로 실행하면 된다.

 

와.. 한 3시간 삽질한 듯..?

그래도 셀러리 자체에 조금은 더 익숙해진 것 같아 다행이다.

근데 django랑 같이 쓰는 건 또 좀 다른 문제인 듯..;

반응형
Comments