Kafka의 Consumer Thread 최적화하기

dgPassFrontmatter: true

메모리 제약 조건 하에서 Kafka의 처리 성능을 개선한 경험을 공유하고자 한다.

기존 상황과 문제점

처음에는 단일 컨슈머 스레드를 사용했다. 이 구성으로는 초당 약 400개의 메시지밖에 처리하지 못하는 한계가 있었다. 물론 사용자가 없는 프로젝트이긴 했지만, 사용자가 있다는 가정을 한다면 실시간 로그를 많은 사용자 애플리케이션에서 수집해야 하므로 성능 향상이 필요하다.

성능 개선을 위한 분석

가용 메모리가 1GB로 제한된 상황에서, 최적의 구성을 찾기 위해 몇 가지 계산을 진행했다.

메모리 사용량 분석

최적의 구성 도출

표: 3초 간격으로 총 소비된 메시지 수(thread 1개)

| Timestamp | Total Messages Consumed | Messages Consumed in 3 Seconds |
|

-- |

|

1초 평균 : 383.3

표: 3초 간격으로 총 소비된 메시지 수(thread 2개)

| Timestamp | Total Messages Consumed | Messages Consumed in 3 Seconds |
|

-- |

|

1초 평균 : 576

표: 3초 간격으로 총 소비된 메시지 수(thread 5개)

|Timestamp|Total Messages Consumed|Messages Consumed in 3 Seconds|
|
|
|
|
|2024-05-23 07:02:21.178118|2552|-|
|2024-05-23 07:02:24.178118|4750|2198|
|2024-05-23 07:02:27.178118|6981|2231|
|2024-05-23 07:02:30.178118|9880|2899|
|2024-05-23 07:02:33.178118|13096|3216|
|2024-05-23 07:02:36.178118|16409|3313|
|2024-05-23 07:02:39.178118|18138|1729|
|2024-05-23 07:02:42.178118|20233|2095|
|2024-05-23 07:02:45.178118|22698|2465|
|2024-05-23 07:02:48.178118|24582|1884|

1초 평균 : 927

표: 3초 간격으로 총 소비된 메시지 수(thread 10개)

|Timestamp|Total Messages Consumed|Messages Consumed in 3 Seconds|
|
|
|
|
|2024-05-23 07:02:21.178118|2867|-|
|2024-05-23 07:02:24.178118|6353|3486|
|2024-05-23 07:02:27.178118|9587|3234|
|2024-05-23 07:02:30.178118|12700|3113|
|2024-05-23 07:02:33.178118|15146|2446|
|2024-05-23 07:02:36.178118|17630|2484|
|2024-05-23 07:02:39.178118|20565|2935|
|2024-05-23 07:02:42.178118|23887|3322|
|2024-05-23 07:02:45.178118|27417|3530|
|2024-05-23 07:02:48.178118|30987|3570|
|2024-05-23 07:02:51.178118|34352|3365|
|2024-05-23 07:02:54.178118|37950|3598|
|2024-05-23 07:02:57.178118|41499|3549|
|2024-05-23 07:03:00.178118|45007|3508|
|2024-05-23 07:03:03.178118|48560|4553|
|2024-05-23 07:03:06.178118|52065|3705|
|2024-05-23 07:03:09.178118|55547|4482|
|2024-05-23 07:03:12.178118|59054|3507|

1초 평균 : 1104

이 데이터를 분석해보면 스레드 개수 증가에 따른 처리량이 다음과 같다:

스레드 수를 늘릴 때마다 성능 향상폭이 감소하는 것을 볼 수 있다.

특히 5개 -> 10개 구간은 성능 향상이 이전에 비해 굉장히 완만해진다.

5개 스레드와 10개 스레드를 구체적으로 비교해보자.

스레드 5개:

스레드 10개:

따라서 10개 스레드는 5개 대비 메모리를 2배 사용하지만, 성능은 19% 정도만 향상되고, 처리량이 불안정하다. 그래서 5개의 스레드를 두기로 결정했다.

물론 사용량이 많아 5개의 스레드로 처리를 감당할 수 없다면 또 다른 고민이 필요할 것이다.

성능 지표(5개 스레드 기준)

352MB를 할당해 처리 성능을 약 2.4배 향상시킬 수 있었다.
실제 운영 환경에서는 항상 리소스 제약이 있는데, 여러 제약 조건 내에서 최적의 성능을 끌어내는 것이 중요하다고 생각한다.