celery의 빛과 그림자

Post on 25-Jan-2017

3.132 Views

Category:

Technology

10 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Celery의 빛과 그림자PYCON KOREA 2015

정민영 THE BEATPACKING COMPANY

발표자

• 정민영

• 비트패킹컴퍼니 CTO

• PyconKR 2014/Deview 2014 ‘제약을 넘어: Gevent’ 발표 (Deview 2014 Top 10)

• AWSKRUG Founder / AWS Community Hero

이런 분들을 위해 준비했어요!

• 비동기 처리를 해야되긴 한다던데… 뭐가 뭔지 모르겠던 분!

• Celery가 뭔가 좋은거 같긴한데…써도 되나 의심스러우셨던 분들!

• Celery를 쓰고 있는데 뭔가 작동이 이상해서 고민이셨던 분 들!

Celery?

Distributed Task Queue

혹은

(종합적인)비동기 처리기

비동기 처리기?

비동기 처리기는 왜 필요한걸까?

고갱님 어떤 서비스

진지하게 가입을 해볼까?

이메일, 이름, .. 좋아 가입!

비동기 처리기는 왜 필요한걸까?

어떤 서비스

진지하게 가입을 해볼까?

이메일, 이름, .. 좋아 가입!

에.. 고객님 프로필 사진을 업로드하고.. 크기도 적당히

3개쯤 준비해두고..

고갱님

비동기 처리기는 왜 필요한걸까?

어떤 서비스

진지하게 가입을 해볼까?

이메일, 이름, .. 좋아 가입!

에.. 고객님 프로필 사진을 업로드하고.. 크기도 적당히 3개쯤 준비해두고.. 요즘 유행이니까 배경 블러도 만들

어 두고…

고갱님

비동기 처리기는 왜 필요한걸까?

어떤 서비스

진지하게 가입을 해볼까?

이메일, 이름, .. 좋아 가입!

에.. 고객님 프로필 사진을 업로드하고.. 크기도 적당히 3개쯤 준비해두고.. 요즘 유행이니까 배경 블러도 만들어 두고… 아 친구도 찾아드려야 하는데 까먹을뻔 했

네 데헷(*^^*)..

고갱님

비동기 처리기는 왜 필요한걸까?

어떤 서비스

에.. 고객님 프로필 사진을 업로드하고.. 크기도 적당히 3개쯤 준비해두고.. 요즘 유행이니까 배경 블러도 만들어 두고… 아 친구도 찾아드려야 하는데 까먹을뻔 했네 데헷(*^^*).. 자 다했다 이제 이메일 보내드려야지!

비동기 처리기는 왜 필요한걸까?

어떤 서비스

어…어.. 고..고갱님??

비동기 처리기는 왜 필요한걸까?

• 비동기 처리기는 동기적으로 수행하지 않아도 되는 일들을 처리해 주는 역활을 합니다.

• 즉 결과를 즉시 받을 필요 없거나, 지연하여 처리해야 되는 일들을 보통 처리합니다.

• 물론 그것이 제대로 처리가 되지 않아도 된다는 이야기는 아니기 때문에, 별도의 잘 만들어진 처리기가 필요해요!

그런데 왜 꼭 여야 하나요?

근데 왜 꼭 Celery여야 하죠?

• 완전 쉽게 연동할 수 있어요!

• (아마도) 당신이 상상할 수 있는 모든 기능을 제공해요!

• 일단 남들이 제일 많이 써요!

Celery… 너란 채소….

완전 쉽게 연동할 수 있어요!

from����������� ������������������  celery����������� ������������������  import����������� ������������������  Celeryapp����������� ������������������  =����������� ������������������  Celery('hello',����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  broker='amqp://guest@localhost//')����������� ������������������  

@app.taskdef����������� ������������������  add(a,����������� ������������������  b):����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  return����������� ������������������  a����������� ������������������  +����������� ������������������  b

완전 쉽게 연동할 수 있어요!

from����������� ������������������  tasks����������� ������������������  import����������� ������������������  addadd.delay(1,����������� ������������������  2)����������� ������������������  

완전 쉽게 연동할 수 있어요!

from����������� ������������������  tasks����������� ������������������  import����������� ������������������  addr����������� ������������������  =����������� ������������������  add(1,����������� ������������������  2)r.get(timeout=1)����������� ������������������  

완전 쉽게 연동할 수 있어요!

(아마도) 당신이 상상할 수 있는 모든 기능

(아마도) 당신이 상상할 수 있는 모든 기능

(아마도) 당신이 상상할 수 있는 모든 기능

T.delay(arg,����������� ������������������  kwarg=value)����������� ������������������  !T.apply_async((arg,����������� ������������������  ),����������� ������������������  {'kwarg':����������� ������������������  value})����������� ������������������  !T.apply_async(countdown=10)����������� ������������������  !T.apply_async(eta=now����������� ������������������  +����������� ������������������  timedelta(seconds=10))����������� ������������������  !T.apply_async(countdown=60,����������� ������������������  expires=120)����������� ������������������  !T.apply_async(expires=now����������� ������������������  +����������� ������������������  timedelta(days=2))����������� ������������������  

(아마도) 당신이 상상할 수 있는 모든 기능

>>> from celery import chain

# 2 + 2 + 4 + 8 >>> res = chain(add.s(2, 2), add.s(4), add.s(8))() >>> res.get() 16

(아마도) 당신이 상상할 수 있는 모든 기능

>>> from celery import chain !# 2 + 2 + 4 + 8 >>> res = chain(add.s(2, 2), add.s(4), add.s(8))() >>> res.get() 16 !>>> (add.s(2, 2) | add.s(4) | add.s(8))().get() 16

(아마도) 당신이 상상할 수 있는 모든 기능

new_user_workflow = (create_user.s() | group( import_contacts.s(), send_welcome_email.s()) ) new_user_workflow.delay(username='artv', first='Art', last='Vandelay', email='art@vandelay.com')

(아마도) 당신이 상상할 수 있는 모든 기능

from datetime import timedelta !CELERYBEAT_SCHEDULE = { 'add-every-30-seconds': { 'task': 'tasks.add', 'schedule': timedelta(seconds=30), 'args': (16, 16) }, } !CELERY_TIMEZONE = 'UTC'

(아마도) 당신이 상상할 수 있는 모든 기능

(아마도) 당신이 상상할 수 있는 모든 기능

뭐… 좋은건 알겠는데….

There ain't no such thing as a free lunch

There ain't no such thing as a free lunch

– kkung

비트 성장의 가장 첫번째 난관은 셀러ㄹ…

–고..고갱님

푸시가 새벽 2시에 왔습니다. 미ㅊ..거 아닙니까?

잘 알고 써야 하는 Celery!

• 적은 규모에서, 간편하게 쓰기에는 더 없이 훌륭하지만…

• 의외로 조금만 규모가 커져도 신경써야 할 부분이 많아요!

• 특히 처음부터 고려하지 않으면 알 수 없는 이상작동처럼 느껴질 수도 있으니 주의가 필요한 부분이 있어요!

Broker

나..나쁜거?

어떤 녀석이 일(Task)을 처리할지 중개(Broker)

Celery 구조

Web APP Broker

Worker

Worker

Worker

Celery는 무수히 많은 Broker를 지원 하지만..

AMQP 모사 일부 기능 제한

AMQP 모사 일부 기능 제한

특히 AMQP중에서도..

RabbitMQ is the default broker so it does not require any additional

dependencies or initial configuration

그래도 굳이 다른 Broker를 쓰시겠다면….

http://raksik.funshop.co.kr/goods/detail/27795

ack, visibility_timeout

ackBroker Worker

Message

Ack

Consume

ack + visibility timeoutBroker Worker

Message

Message

Visibility Timeout

Redis/SQS에서의 visibility timeout

• visibility timeout내에 ack가 전달되지 않으면, task가 중복 실행됩니다.

• eta, countdown 시간보다 visibility timeout이 커야해요.

• AWS SQS의 최대 시간 제한은 12시간!

그 외의 고생길(!)

• Redis는 메모리가 부족한 상황에서 임의로 key가 삭제될 수 있어요!

• SQS는 API요청당 과금을 하고, Pub/Sub이 아닌 Polling모델 이에요. 자주 땡길(!)수록 요금이 나와요.

• SQS를 Broker로 사용하면 Celery의 주요한 모니터링 기능 대부분을 사용할 수 없어요.

왜 고생을 사서 하는 거죠? ….

prefetch의 배신

prefetch의 배신(?)

• prefetch에 대한 일반적인 기대는….

• Task들을 그냥 미리 땡겨두는거죠. 심플하게. 다른 뜻 없이.

• 여기에 무슨 다른 오해의 소지가 있겠어…?

S S S L S S S S

S S S L

prefetch : 4

L S S S

queue size : 8

concurrency: 1

이렇게 되는거 아냐? 라고 생각하셨다면…

아니 진짜… 진짜… 이거 아냐…?

Prefetch is a term inherited from AMQP that is often misunderstood by users.

The prefetch limit is a limit for the number of tasks (messages) a worker can reserve for itself

S S S L S S S S

S S S L

prefetch : 4

L / / /

queue size : 8

S S S S

concurrency: 1

오해받기 쉬운 그/그녀 prefetch….

• prefetch된 단위 전체의 작업을 소비해야(ack*) 다음 prefetch가 수행 됩니다.

• task가 비워지는 대로 다음 task를 broker에서 가져올꺼라는 일반적인 기대와 차이가 있어요!(often misunderstood)

• 물론 task payload의 크기가 적고, latency가 중요하다면 합리적인 결정이기도 합니다.

Prefork pool prefetch

P1PA P2

T1

T2

T3

-ofair

그런데 무조건 쓸 수 있는건 아니고요….

에헤이.. 방법이 있겠죠? 좀 나눕시다 에헤

Task를 한 큐에 담지 마세요!

• prefetch의 특성상 평균 수행 시간이 비슷한 것들이 같은 Queue에 있는 것이 성능상 훨씬 유리합니다.

• 또한 Task의 절대적인 수 자체도 중요한 요소에요.

• 처리의 중요도/시급도(Priority)에 따른 분류도 중요해요.

• 위와 같은 요소를 고려해서 Queue를 나눠 주세요

CELERY_ROUTES����������� ������������������  =����������� ������������������  {����������� ������������������  

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  'feed.tasks.import_feed':����������� ������������������  {����������� ������������������  

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  'queue':����������� ������������������  'feeds'����������� ������������������  

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  }����������� ������������������  

}����������� ������������������  

$ celery -A pykr worker -Q feeds

정말 간단한데 성능에 큰 영향을 주는

또 다른 요소

무시를 무시하지 마세요

무시를 무시하지 마세요?

ignore_result

ignore_result

• Celery는 기본적으로 수행 결과(return)를 ‘저장’ 해야 작업이 끝납니다.

• 하지만 대부분 Task내에서 직접 결과를 다른 곳에 저장하지, `return` 자체를 쓰는 경우는 드물어요!

• 보통은 Task 연계를 하는 경우만 필요하답니다!

• 결과를 저장하는 비용이 적지 않기 때문에 이걸 끄기만 해도 무척 성능이 좋아져요!

그래서 Celery를 쓰라는거야 말라는 거야…?

잘 쓰면 됩니다!

그래도 역시 Celery!

• 비록 여러 어려움을 설명하긴 했지만, 이는 꼭 잘못된 디자인/구현 이라기 보다는 여러 제약속에서 특정 선택을 했을 뿐인 경우가 많아요!

• Celery 없이 문제를 해결하려다 보면 결국 바퀴를 다시 만들게 되는 경우가 많아요!

• Celery는 요집도 조집도 우리집도 너희집도 많이 쓰기 때문에 같이 어려운 문제를 같이 해결해 줄 사람이 많아요!

• 본래 ‘분산’ ‘비동기’ 이런 단어 들어가면 복잡도가 만배(…)

감사합니다.

절 찬 채 용 중

부 스 상 담 환 영

top related