isPowerfulBlog
큐(Queue)를 이용한 비동기(Async) 작업 처리 속도 및 확장성 개선 본문
데이터 엔지니어 인턴으로 입사해 데이터 파이프라인 작업을 하다보니 어떻게 작업을 효과적으로 할 수 있을 지에 대한 고민을 많이 하게 되는 것 같다.
아래는 데이터 파이프라인을 개선해 나가면서 큐를 도입했던 이유를 작성헀다.
—
동기 -> 비동기
맨 처음, 동기 작업으로 코드를 짠다. 하나의 input에 대해서 기대한 output이 잘 나오는가? 그것을 가장 먼저 생각했다.
일련의 단위 작업들을 순차적으로 처리하는 것을 가만히 보고 있자니 느리다! 라는 생각이 들었다. 그래서 작업 속도를 개선하고자 이제 앞 작업의 완료 여부와 상관 없이 다른 작업을 병렬적으로 수행할 수 있도록 비동기 작업으로 전환하게 되었다.
비동기 호출을 여러번 하면 병렬적으로 작업이 진행되기 때문에 가지고 있는 컴퓨팅 자원을 더 적극적으로 활용하며, 속도도 대폭 높일 수 있게 되었다.
단순 비동기 작업 -> 큐 기반 비동기 작업
동기에서 비동기로 전환하면서 비약적인 성능 향상이 나타났고, 리소스를 적극 활용하고 있는 모습에 뿌듯해졌다.
이렇게 개선을 하고나니 또 다음 문제에 부딪혔다.
- 확장성: 처리 작업량 및 속도를 높이기 위해 비동기 호출을 많이 하면 시스템부하가 발생한다.
- 안정성: 비동기 호출 시 worker가 바로 작업에 들어가기 때문에 worker에 장애가 발생하여 컨테이너가 종료되거나 재부팅될 경우 작업들이 소실된다. 재부팅 시 worker가 연속적으로 작업을 이어나갈 수 없다.
파이프라인의 확장성과 안정성을 개선하기 위해 큐를 도입하게 되었다.
처음 큐를 도입했던 파이프라인에서는 많은 양의 작업을 빠르게 처리해야했기 때문에 Redis라는 인메모리(in-memory) 데이터베이스를 도입했다.
하지만 새로운 데이터 파이프라인에서는 그렇게 많은 양을 그렇게 빠르게 처리해야할 필요가 없었으므로 Redis가 과하지 않은가?에 대해서 고민하게 되었고, 상황에 따라 어떤 큐를 쓰는게 좋을지 찾아보게 되었다.
일단적으로
인메모리 DB는 일반 DB와 어떻게 다른가?
인메모리 DB는 데이터를 디스크에 기록하지 않고 메모리에 기록해뒀다가 바로 꺼내쓴다.
그래서 디스크 I/O 과정이 없기 때문에 일반 DB에 비해 굉장히 빠르다.
대신 디스크 저장장치에 기록하는 것이 아니기 때문에 프로세스가 종료되거나 시스템이 재부팅되면 메모리가 날라간다. 영속성이 중요하다면 인메모리 디비 사용을 주의해야한다.
내가 최근 겪은 데이터 파이프라인 작업들은 대부분 빠른 데이터 처리, 순차적인 데이터 처리를 요구하는 상황이었기 때문에, 이 상황을 기준으로 좀 더 구체적인 경우에 따라 어떤 큐를 선택해야할지 고민해보았다.
간단하게 작업 순서를 보장하고 싶은 상황
: 파이썬 내장 Queue
간단히 작업 순서를 보장하고 싶을때는 내장되어있는 큐를 쓸 수 있다.
다만 코드를 돌리는 컨테이너가 종료된다면 당연히 큐 안에 있는 작업이 날아간다.
근데 큐 안에 있던 작업들을 보존하여 컨테이너 재부팅 시에 연속적으로 작업을 하길 원한다면?
컨테이너 종료 시그널 발생 시, 아래 두 가지를 시도해볼 수 있겠다.
- 파일 쓰기: 아주 간단하다. 근데 파일 시스템 I/O 작업을 해야해서 속도가 느리다.
- SQLite: 파일 기반의 경량 데이터베이스이기 때문에 서버 없이 동작한다. 구조적인 데이터를 다루기에도 좋다.
둘 다 대용량 처리에는 적합하지 않다. 하지만 가벼운 데이터 파이프라인에 활용하기 좋은 것 같다.
좀 더 많은 데이터를 처리, 가볍고 빠르게 처리하고 싶은 상황
: Redis
인메모리 DB라서 위에서 언급했듯이 굉장히 빠르다. 사용법이 단순해서 사용하기도 굉장히 편하다.
Redis 서버를 따로 운영하면 코드 실행 컨테이너의 종료 여부와 관계 없이 작업들을 보존할 수 있다.
옵션 설정으로 디스크에 쓰기도 가능.
데이터 전달 방향을 하나로 국한하지 않고 다양하게 통신하고 싶은 상황
: RedisMQ
Redis 기반 경량 메시징 시스템 구축이 가능하다.
대용량 데이터 스트림 처리, 다양한 통신
: Kafka
디스크 기반 메시징 시스템이라 영속성 보장 -> 대규모 로그, 이벤트 데이터의 파이프라인으로 주로 사용된다.
아직 작업했던 파이프라인 중 메세지큐가 필요한 케이스는 없었지만,
나중에 마주칠 일이 있으면 좋겠다!!!!!!
'Data Engineering' 카테고리의 다른 글
[LangChain] multi query invoke, ainvoke 속도 비교하기 (1) | 2024.04.25 |
---|---|
[LangChain] S3, MinIO Loader 구현하고 PDFParser 사용하기 (0) | 2024.04.12 |
[Kafka] Docker에서 Kafka Multi Broker Cluster 구성하기 (1) | 2023.03.22 |
[Kafka] Docker로 Producer, Consumer 통신하기 (Python) (0) | 2023.03.22 |
[Kafka] Docker에서 Kafka 단일 Broker Cluster 구성하기 (0) | 2023.03.22 |