카프카 컨슈머에서 비동기로 돌리는거 왜 권장안하는가
- 컨슈머 메시지 소비(성능)을 위해 비동기로 돌리는 경우가 있음
- kafka에 메시지가 쌓이게 되면 taskExecutor 큐가 꽉차게된다.
- 이러면 rejected 뭐시기 에러가 나서 (큐가 더이상 task를 받지 못한다는 에러) 카프카에 커밋은 됐는데 (카프카에서 메시지를 땡기면 커밋한다고 가정) 메시지 처리를 못해서 전부 유실된다.
그럼 taskExecutor 큐 사이즈 무한으로 늘리면 되지 않나요?
- OOM 난다~ -> 그럼 메시지 전부 유실된다.
그럼 카프카에 커밋 시점을 비동기 스레드가 전부 처리한 뒤 하면 되는거 아닌가요?
- 그러면 아래 같은 상황에서 무슨 기준으로 커밋을 칠건디?
- 예를 들어 1번 메시지, 2번 메시지 각각 들어왔을 때 비동기로 돌리다가 2번 메시지가 먼저 처리되면 commit을 2번으로 칠건가? 그러면 1번 실패했을 때 유실될건데 이런 상황은 어떻게 다룰거지? -> 복잡해진다. 근데 이런걸 해주는 라이브러리(중앙에서 커밋 관리)가 있긴하다.
그럼 어떻게해요?
- 컨슈머 스레드(Concurrency)를 늘려야한다.
- 근데 파티션이랑 컨슈머 스레드는 보통 1:1로 붙기 때문에 다음과 같은 상황에서는 도움이 되지 못한다.
- 파티션 10개, 컨슈머 10대, Concurrency = 2 -> 이러면 쓰레드 하나당 파티션에 붙기 때문에 20 - 10 = 10 개의 스레드는 놀고있다.
- 따라서 Concurrency를 늘리려면 파티션도 같이 늘려줘야 한다.
- 근데 파티션을 한번 늘리면 줄이기가 매우 까다롭기 때문에 신중히 늘려야한다.