skarltjr / Memory_Write_Record

나의 모든 학습 기록
0 stars 0 forks source link

복기(celery 브로커로 redis를 택한 이유) & celery를 택한 이유 #144

Open skarltjr opened 1 year ago

skarltjr commented 1 year ago
  1. 개요

    이전에 celery의 브로커로 redis를 활용했다.
    그 이유에 대해 분명하게 기록하고 새로 알게된 내용은 업데이트하고자 한다.
  2. 상황

    • 주석 2023-01-30 094540
1. 
요청을 전달받는 자동화 봇 서비스와 요청을 처리하는 worker 서비스가 존재한다.
worker 서비스의 경우 모든 작업이 외부 api 호출을 필요로하는 상황
이런 기능이 한 서비스에 구현된다면 외부서비스의 장애가 그대로 내 서비스에 전파될것같았고
실제로 이를 경험했다.
따라서 두 서비스를 분리하고 비동기로 작업을 전달하고자했다.
2.
먼저 메세지가 누락되지 않으면 최선이겠지만 누락되더라도 크리티컬한 이슈가 없다.
그냥 수동으로 한 번 처리하면되기때문이다.
3. 메세지 자체가 매우 가볍다.
4. 일일 처리량이 최대 10개 정도다.
5. celery 공식문서에 브로커 예제가 rabbitmq, redis만 있었다.
skarltjr commented 1 year ago

rabbitmq

  1. 장점

    메세지 브로커로 적어도 한 번 읽음을 보장해준다
    오랫동안 널리 사용된 기술로 참고할 자료가 많다
    celery와 함께 사용된 예제 또한 다양하다.
    - 개인적으로 중요
    모니터링 및 확장기능이 내장되어 다양한 기능 활용이 가능
    - 이러한 기능은 크게 필요가 없는 상황이었다.
  2. 단점

    기본적인 설정 및 옵션이 레디스 활용보다 복잡하다.
    무엇보다 가장 중요한건 다양한 기능을 제공하는만큼 보다 많은 리소스를 필요로한다.
    - 이게 rabbitmq를 굳이 선택하지 않은 이유인데 많은 기능을 필요로 하지 않을뿐더러 메세지 자체도 굉장히 가볍고
    - 설령 메세지가 누락된다하더라도 심각한 문제가 발생하지 않는다.
skarltjr commented 1 year ago

redis

  1. 장점
    
    인메모리 디비로 빠르고 쉽게 메세지를 처리할 수 있다.
    - 개인적인 생각으로 내 서비스의 목적은 사용자의 요청에 대한 처리 및 응답이다.
    - 그리고 요청 처리는 빠를수록 좋다고 생각했고
    - 요청에 대한 처리 및 응답이 빨라야 목적에 보다 부합한다고 생각했다.

한편으론 메세지 자체가 굉장히 작기 때문에 사실상 속도 자체는 비슷했고 적어도 한 번 읽음을 보장해주는 메세지 브로커를 택하는게 맞지 않을까라는 아쉬움도 남았다.

비교적 쉬운 사용 가능

skarltjr commented 1 year ago

결론

결론적으로 redis를 택했다.
이유는 
1. 굳이 더 많은 리소스를 사용할 이유가 없었다.
2. 조직원들의 요청에 대한 처리는 속도가 중요하다고 생각했다.
3. 누락자체가 큰 이슈를 가져오지 않는다.
4. 모니터링등의 다른 기능은 굳이 고려하지 않아도 된 상황이었다.

아쉬운점

사용자 관점에서.. 
처리속도가 거의 비슷하다면 누락이 없는경우가 베스트라고 생각.
사용자 관점에서 제대로 생각하지 못한 실수다.

그래서 다시 결정을 해야한다면 사용자 입장을 고려한 측면에서 rabbitmq를 사용할거같다.
skarltjr commented 1 year ago

안정성을 위한 Timeout

외부 서비스 호출에서 응답 시간이 매우 길어질경우 이를 실패처리할 수 있다.
보통 Timeout 시간이 30초인데 이를 3~5초 정도 짧은 시간으로 설정했다.
그래서 timeout이 발생하면 현재 외부 서비스를 활용할 수 없음으로 판단한다.
skarltjr commented 1 year ago

그럼 왜 celery 라이브러리를 활용했는가?

1. a, b 서비스가 존재하는 상황에서 메세지는 a -> b로만 전달되는 단방향인 상황 
2. a에서 b로 메세지를 전달하는 일을 비동기로 처리하고자 의도 + 비동기를 자체적으로 지원하는 라이브러리
따라서 celery를 선택

그럼 celery는 어떻게 동작하는가?

main service에서 처리하고자 하는 메세지를 브로커에 전달(비동기) 워커는 이를 push받아 처리

- celery의 worker의 경우 기본적으로 하나의 요청을 수행한 뒤 다음 요청을 처리한다. 
- 다만 설정을 통해 가용 가능한 cpu를 활용하여 병렬처리가 가능하다
- celery의 경우 브로커가 메세지를 worker에게 push해주는 방식을 활용한다.
  - 즉 워커가 지속적으로 큐를 관찰하는 poll방식을 사용하지 않는다는것

개인적으로 이 push-based 방식은 장점 : 이벤트가 존재할때만 이를 파악하여 push하기때문에 워커가 지속적으로 관찰하는 리소스를 필요로하지않는다. 단점 : broker가 할 일이 많아진다. 즉 브로커가 리소스를 더 필요로 할 수 있다는것. 만약 제한된 리소스라면 브로커의 성능이 낮아질 수 있다고 생각.