Consumer Groups 이란?
Kafka를 사용하고 스케일링을 하려고 할 때 애플리케이션 안에 많은 컨슈머들이 그룹 형태로 데이터를 읽는데 이걸 컨슈머 그룹이라고 한다.
- 컨슈머 그룹이 파티션을 읽는 방식으로 같은 그룹에 속한 각각의 컨슈머는 모든 파티션에서 읽기를 공유한다.
파티션 개수보다 컨슈머가 많아질 경우
- 파티션과 컨슈머가 동일하면 각각 1:1 매칭이 되어 각기 읽는다.
- 파티션이 컨슈머보다 많을때는 자동으로 컨슈머가 파티션을 캐치하여 구독해서 자동으로 배분한다.
- 만약 파티션이 컨슈머보다 적다면 남는 컨슈머는 자동으로 비활성 대기 상태로 변한다.
토픽에 대한 다수의 컨슈머 그룹이 존재할때
- 토픽에 대해 다수의 컨슈머 그룹이 존재해도 상관 없다.
- 각각의 파티션에 다수의 리더가 존재한다. 하지만 컨슈머 그룹안에서는 오직 하나의 컨슈머가 하나의 파티션에 지정된다.
각기 다른 그룹이 필요한 이유는 무엇일까?
서비스 | 택배 위치 서비스 | 택배 알림 서비스 |
---|---|---|
데이터 스트림 | GPS | GPS |
그룹 | A | B |
어떠한 서비스가 있다. 예를들면 택배 서비스를 기준으로 택배 서비스의 실시간 위치를 공유하는 서비스, 택배 알림 서비스가 있다. 두개는 GPS라는 위치를 기준으로 동일한 데이터 스트림을 읽는다.
- 결과적으로 서비스당 하나의 컨슈머 그룹을 갖게 된다는 얘기다.
- 하나의 컨슈머는 알림 서비스, 하나의 컨슈머는 위치 서비스에 할당된다. 같은 데이터를 바라보지만 각기 다른 서비스에 그룹이 읽어들이기 때문에 분산 처리를 하여 레이턴시가 현저히 줄어든다.
각각의 컨슈머 그룹 생성방법
- group.id라는 컨슈머 프로퍼티를 사용해서 컨슈머 그룹에 이름을 만들어준다.
- 컨슈머에 이름을 지정해주는 자신이 속한 그룹을 알게 된다.
컨슈머 오프셋 정의
카프카는 **각 파티션마다 메세지가 저장되는 위치**를 오프셋(offset) 이라고 부르고,
오프셋은 파티션 내에서 유일하고 순사적으로 증가하는 숫자(64비트 정수) 형태로 되어 있다
컨슈머 그룹이 읽고 있던 오프셋을 저장하면서 그 오프셋은 Kafka 토픽 안에서 시작부분에 밑줄이 두 개 있는 __consumer_offsets라는 이름으로 있게 된다.
- 이것을 Kafka 내부 토픽이라고 한다.
컨슈머 오프셋이 중요한 이유?
수직 표시된 숫자 집합체가 오프셋, 토픽에 많은걸 기록햇고 그 위치를 나타내는게 오프셋이다. 컨슈머 그룹안에 컨슈머가 있고 가끔식 오프셋을 커밋한다. 커미되면 그 컨슈머는 그 오프셋으로 부터 계속 데이터를 읽을 수 있게 된다.
간단히 설명하면 “ 나 여기까지 작업 완료했다고 보고 올리는 것이고, 그걸 기록으로 남긴다. 즉 커밋한다. “ 라고 보면된다.
- Apache Kafka로부터 받은 데이터에 대한 처리를 컨슈머가 완료하면 컨슈머는 종종 오프셋을 커밋해야 하고Kafka 브로커가 컨슈머 오프셋 토픽에 기록하라고 알린다.
- 오프셋을 커밋함으로써 사용자가 Kafka 토픽을 어디까지 성공적으로 읽었는지 알 수 있게된다.
- 커밋을 통해 컨슈머가 죽엇을때를 대비해서 마지막까지 성공적으로 처리한 위치를 기억하고 다시 처리를 위해서 필요하다. 결과적으로 오프셋덕에 충돌이나 실패한 곳으로 부터 데이터를 재생할 수 있는 매커니즘을 가질수 있게 된다.
컨슈머의 다양한 전달 방식
- Java 컨슈머는 최소한 한 번 모드에서 자동으로 오프셋을 커밋한다 (기본값)
- 수동 커밋을 선택하면 3가지의 전달 방식이 있다.
- 최소한 한 번모드는 메세지가 처리된 직후에 오프셋이 커밋이 된다는 얘기다. 이렇게 하면 처리가 잘못 되었을경우 그 메세지를 다시 읽을 기회가 1번 주어진다.
멱등 확인 및 옵션
첫 번째 수행을 한 뒤 여러 차례 적용해도 결과를 변경시키지 않는 작업 또는 기능의 속성
- 첫번째 옵션인 멱등은 메세지를 다시 처리해도 그게 시스템에 영향을 미치지 않는다는 의미다.
- 최대한 한 번 옵션은 컨슈머가 메세지를 받자마자 오프셋을 커밋하게 된다.
- 만일 처리가 잘못되면 일부 메세지를 잃게 된다. 다시 읽지 않기 때문이다.
- 메세리를 실제로 처리하기 전에 오프셋을 커밋했기 때문이다.
- 정확히 한 번 옵션은 메세지를 딱 한 번 처리한다.
- Kafka 대 Kafka 워크플로를 할 때 트랜잭션 API를 사용할 수 있고, Kafka 스트림 API도 사용한다면 아주 쉽게 사용할 수 있다.
- Kafka에서 외부 시스템으로 간다면 시스템이 영향이 미치지 않게 하기 위해 멱등 컨슈머를 꼭 사용해야 한다.
알아야하는 내용
오프셋을 커밋하는 방법과 시기에 따라 최소한 한 번 모드나 최대한 한 번 또는 정확히 한 번 모드에 있게 될 것이다.