4.3 카프카 컨슈머

문법식·2023년 2월 8일
0

컨슈머는 카프카에 적재된 데이터를 처리한다.

멀티 스레드 컨슈머

카프카는 처리량을 늘리기 위해 파티션과 컨슈머 개수를 늘려서 운영할 수 있다. 파티션을 여러 개로 운영하는 경우 데이터를 병렬처리하기 위해서 파티션 개수와 컨슈머 개수를 동일하게 맞추는 것이 중요하다. 파티션 개수가 n개라면 동일 컨슈머 그룹으로 묶인 컨슈머 스레드를 최대 n개 운영할 수 있다. 그러므로 n개의 스레드를 가진 1개의 프로세스를 운영하거나 1개의 스레드를 가진 프로세스를 n개 운영하는 방법도 있다. 컨슈머를 멀티 스레드로 활용하는 방식은 크게 두 가지로 나뉜다.

카프카 컨슈머 멀티 워커 스레드 전략

브로커로부터 전달받은 레코드들을 병렬로 처리한다면 1개의 컨슈머 스레드로 받은 데이터들을 더욱 향상된 속도로 처리할 수 있다.
멀티 스레드를 생성하는 ExecutorService 자바 라이브러리를 사용하면 레코드를 병렬처리 하는 스레드를 효율적으로 생성하고 관리할 수 있다. Executor를 사용하여 스레드 개수를 제어하는 스레드 풀을 생성할 수 있는데, 데이터 처리 환경에 맞는 스레드풀을 사용하면 된다. 작업 이후 스레드가 종료되어야 한다면 CachedThreadPool을 사용하여 스레드를 실행한다.
스레드를 사용하면 한번 poll()을 통해 받은 데이터를 병렬처리함으로써 속도의 이점을 확실히 얻을 수 있다. 그러나 몇 가지 주의해야 하는 사항이 있다.

  • 컨슈머 스레드가 poll()(자동 커밋함)을 통해 데이터를 가져오면 데이터 처리가 끝나지 않았음에도 불구하고 커밋을 하기 때문에 리밸런싱, 컨슈머 장애 시에 데이터 유실이 발생할 수 있다.
  • 레코드 처리의 역전 현상이다. 워커 스레드들로 병렬처리하면 스레드별로 처리 시간이 다를 수 있다. 이로 인해 레코드의 순서가 뒤바뀌는 현상이 발생할 수 있다. 레코드 처리에 있어 중복이 발생하거나 데이터의 역전현상이 발생해도 되며 매우 빠른 처리 속도가 필요한 데이터 처리에 적합하다.

카프카 컨슈머 멀티 스레드 전략

구독하고자 하는 토픽의 파티션 개수만큼만 컨슈머 스레드를 운영하는 것이다. 위의 전략은 컨슈머 스레드가 데이터를 가져오면 워커 스레드들이 데이터를 처리하는 전략이라면 이 전략은 각 스레드가 각자 데이터를 가져오고 처리하는 전략이다.


컨슈머 랙

컨슈머 랙(LAG)은 토픽의 최신 오프셋(LOG-END-OFFSET)과 컨슈머 오프셋(CURRENT-OFFSET) 간의 차이다. 컨슈머 랙은 컨슈머가 정상 동작하는지 여부를 확인할 수 있기 때문에 컨슈머 애플리케이션을 운영한다면 필수적으로 모니터링해야 하는 지표이다.
컨슈머 랙은 컨슈머 그룹과 토픽, 파티션별로 생성된다. 1개의 토픽에 3개의 파티션이 있고 1개의 컨슈머 그룹이 토픽을 구독하여 데이터를 가져가면 컨슈머 랙은 총 3개가 된다.
프로듀서가 보내는 데이터양이 컨슈머의 데이터 처리량보다 크다면 컨슈머 랙은 늘어난다. 반대로 프로듀서가 보내는 데이터양이 컨슈머의 데이터 처리량보다 적으면 컨슈머 랙은 줄어들고 최솟값은 0으로 지연이 없음을 뜻한다.
컨슈머 랙을 모니터링함으로써 컨슈머의 장애를 확인할 수 있고 파티션 개수를 정하는 데에 참고할 수 있다. 컨슈머 랙을 확인하는 방법은 총 3가지이다.

카프카 명령어를 사용하여 컨슈머 랙 조회

kafka-consumer-groups.sh 명령어를 사용하면 컨슈머 랙을 포함한 특정 컨슈머 그룹의 상태를 확인할 수 있다. 컨슈머 랙을 확인하기 위한 가장 기초적인 방법으로 다음과 같이 명령어를 사용하면 된다.

$ bin/kafka-consumer-groups.sh --bootstrap-server my-kafka(카프카 클러스터 퍼블릭 IP 혹은 도메인):9092(포트 번호) --group my-group --describe

카프카 명령어를 통해 컨슈머 랙을 확인하는 방법은 일회성에 그치고 지표를 지속적으로 기록하고 모니터링하기에는 부족하다.

컨슈머 metrics() 메서드를 사용하여 컨슈머 랙 조회

컨슈머 애플리케이션에서 KafkaConsumer 인스턴스의 metrics()메서드를 활용하면 컨슈머 랙 지표를 확인할 수 있다. 컨슈머 인스턴스가 제공하는 컨슈머 랙 관련 모니터링 지표는 3가지로 records-lag-max, records-lag, records-lag-avg이다.
metrics() 메서드로 컨슈머 랙을 확인하는 방법은 3가지 문제점이 있다.

  • 컨슈머가 정상 동작하는 경우에만 확인할 수 있다. metrics() 메서드는 컨슈머가 정상적으로 실행될 경우에만 호출된다.
  • 컨슈머 애플리케이션을 여러 종류로 운영할 경우 각기 다른 컨슈머 애플리케이션에 metrics() 메서드를 호출하여 컨슈머 랙을 수집하는 로직을 중복해서 넣어야 한다. 왜냐하면 특정 컨슈머 그룹에 해당하는 애플리케이션이 수집하는 컨슈머 랙은 자신 컨슈머 그룹에 대한 컨슈머 랙만 한정되기 때문이다. 컨슈머 랙은 컨슈머 그룹과 토픽, 파티션별로 생성된다는 점을 상기하면 된다.
  • 컨슈머 랙을 모니터링하는 코드를 추가할 수 없는 카프카 서드 파티 애플리케이션의 컨슈머 랙 모니터링은 불가능하다.

외부 모니터링 툴을 사용하여 컨슈머 랙 조회

컨슈머 랙을 모니터링하는 가장 최선의 방법은 외부 모니터링 툴을 사용하는 것이다. 데이터 독, 컨플루언트 컨트롤 센터와 같은 카프카 클러스터 종합 모니터링 툴을 사용하면 카프카 운영에 필요한 다양한 지표를 모니터링할 수 있다. 컨슈머 랙 모니터링만을 위한 툴로 오픈소스로 공개되어 있는 버로우가 있다.

카프카 버로우

버로우를 카프카 클러스터와 연동하면 REST API를 통해 컨슈머 그룹별 컨슈머 랙을 조회할 수 있다.
버로우는 다수의 카프카 클러스터를 동시에 연결하여 컨슈머 랙을 확인한다. 그러나 모니터링을 위해 컨슈머 랙 지표를 수집, 적재, 알람 설정을 하고 싶다면 별도의 저장소와 대시보드를 구축해야 한다.
버로우의 기능 중 가장 돋보이는 것은 컨슈머와 파티션의 상태를 단순히 컨슈머 랙으 임계치로 나타내지 않았다는 점이다. 특정 파티션의 컨슈머 랙이 특정 시점에만 100만이 넘었다고 컨슈머 또는 파티션에 이슈가 있다고 단정 지을 수는 없다. 왜냐하면 프로듀서가 데이터를 많이 보내면 일시적으로 임계치가 넘어가는 현상이 발생할 수도 있기 때문이다. 컨슈머 애플리케이션을 운영할 때 컨슈머 랙이 임계치에 도달할 때마다 알람을 받는 것은 무의미한 일이다. 그래서 버로우에서는 임개치가 아닌 슬라이딩 윈도우 계산을 통해 문제가 생긴 파티션과 컨슈머의 상태를 표현한다. 파티션의 상태를 OK, STALED, STOPPED로 표현하고 컨슈머의 상태를 OK, WARNING, ERROR로 표현한다.

  • 최신 오프셋과 컨슈머 오프셋이 조금씩 차이가 나면서 증가하는 상황
    파티션은 OK, 컨슈머도 OK
  • 최신 오프셋과 컨슈머 오프셋이 점차 벌어져서 컨슈머 랙이 증가하는 상황
    파티션은 OK, 컨슈머는 WARNING
  • 최신 오프셋이 증가하고 있지만 컨슈머 오프셋이 멈춘 그래프, 컨슈머 랙이 급격하게 증가하는 상황
    파티션은 STALED, 컨슈머는 ERROR

컨슈머 랙 모니터링 아키텍처

카프카 클러스터#0  → 카프카 버로우
카프카 클러스터#1         ↓  
                    텔레그레프
                        ↓
                    엘라스틱서치
                        ↑
 👨‍🏫       →          그라파나
        컨슈머 랙 
       그래프 조회                     
  • 버로우: REST API를 통해 컨슈머 랙을 조회할 수 있다.
  • 텔레그래프: 데이터 수집 및 전달에 특화된 툴. 버로우를 조회하여 데이터를 엘라스틱 서치에 전달한다.
  • 엘라스틱서치: 컨슈머 랙 정보를 담는 저장소
  • 그라파나: 엘라스틱 서치의 정보를 시각화하고 특정 조건에 따라 슬랙 알람을 보낼 수 있는 웹 대시보드 툴

컨슈머 배포 프로세스

중단 배포

중단 배포는 컨슈머 애플리케이션을 완전히 종료한 이후에 개선된 코드를 가진 애플리케이션을 배포하는 방식이다. 이 방법은 한정된 서버 자원을 운영하는 기업에 적합하다. 기존 애플리케이션을 완전히 종료한 이후 신규 애플리케이션을 배포, 실행하여 버전을 올리는 방식이다. 기존 컨슈머 애플리케이션이 종료되면 더는 토픽의 데이터를 가져갈 수 없기 때문에 컨슈머 랙이 늘어난다. 컨슈머 랙이 늘어나는 것은 지연인 발생한다는 뜻이다.
중단 배포를 사용할 경우 새로운 로직이 적용된 신규 애플리케이션의 실행 전후를 명확하게 특정 오프셋 지점으로 나눌 수 있다는 장점이 있다. 이러한 특징은 신규 배포한 애플리케이션에 이슈가 발생해서 롤백할 때 유용하다.

무중단 배포

컨슈머의 중단이 불가능한 애플리케이션의 신규 로직 배포가 필요한 경우에는 무중단 배포가 필요하다.

블루/그린

블루/그린 배포는 이전 버전 애플리케이션과 신규 버전 애플리케이션을 동시에 띄워놓고 트래픽을 전환하는 방법이다. 이 방법은 파티션 개수와 컨슈머 개수를 동일하게 실행하는 애플리케이션을 운영할 때 유용하다. 블루/그린 배포는 리밸런스가 한 번만 발생하기 때문에 많으 수의 파티션을 운영하는 경우에도 짧은 리밸런스 시간으로 배포를 수행할 수 있다.

롤링

롤링 배포는 블루/그린 배포의 인스턴스 할당과 반환으로 인한 리소스 나입를 줄이면서 무중단 배포를 할 수 있다. 롤링 배포의 중요한 점은 파티션 개수가 인스턴스 개수와 같거나, 그보다 많아야 한다는 점이다. 예를 들어, 파티션을 2개로 운영하는 토픽이 있다면 롤링 배포를 위해 최소한 2개으 인스턴스가 필요하다. 2개의 인스턴스 중 1개의 인스턴스를 신규 번전으로 실행하고 모니터링한 후 나머지 1개의 인스턴스를 신규 버전으로 배포하여 롤링 업그레이드를 진행할 수 있다. 이 경우에는 리밸런스가 총 2번 발생한다. 파티션 개수가 많을수록 리밸런스 시간도 길어지므로 파티션 개수가 많지 않은 경우에 효과적인 방법이다.

카나리

카나리(canary)는 한국어로 카나리아라는 이름의 애완용 새를 뜻한다. 카니리아는 탄광에서 유독 가스의 누출 위험을 알리는 용도로 사용되었다. 사람에 비해 작은 몸집을 가진 카나리아는 유독 가스의 미세한 유출에도 빠른 시간에 사망했기 대문에 광부들은 카나리아가 죽으면 즉시 탄광을 탈출하여 생명을 보존할 수 있었다. 여기에 착안하여 작은 위험을 통해 큰 위험을 예방하는 방버인 카나리 배포라는 개념이 탄생했다. 카나리 배포를 이용하면 많은 데이터 중 일부분을 시규 버전의 애플리케이션에 먼저 배포함으로써 이슈가 없는지 사전에 탐지할 수 있다. 예를 들어, 100개 파티션으로 운영하는 토픽이 있을 경우 1개 파티션에 컨슈머를 따로 배정하여 일부 데이터에 대해 신규 버전의 애플리케이션이 우선적으로 처리하는 방식으로 테스트할 수 있다. 카나리 배포로 사전 테스트가 완료되면 나머지 99개 파티션에 할당된 컨슈머는 롤링 또는 블루/그린 배포를 수행하여 무중단 배포가 가능하다.

profile
백엔드

0개의 댓글