앞서 토픽에 데이터를 보내는 프로듀서에 대해 알아보았으니 이제 토픽으로부터 데이터를 읽는 역할을 수행하는 컨슈머에 대해 알아보자.
카프카 브로커가 컨슈머에 데이터를 push 하는 것이 아니라 컨슈머가 데이터를 pull 해온다.
하나 이상의 파티션으로부터 데이터를 읽어오는 것도 가능하다.
위처럼 파티션으로부터 데이터를 읽어와야 하는 컨슈머들은 자동적으로 어떤 카프카 브로커(서버)로부터 데이터를 읽을지 알고 있다.
파티션으로부터 오프셋에 따라 데이터를 순차적으로 읽어온다.
Consumer Deserializer
컨슈머는 메시지를 읽고 Kafka로부터 받은 바이트를 객체나 데이터로 역직렬화한다.
컨슈머에서 역직렬화하기 위해서는 프로듀서에서 해당 토픽을 저장할 때 어떠한 형식의 Serializer인지에 따라 알맞은 Deserializer를 사용해야 한다.
따라서 토픽을 생성하고 특정 데이터 타입으로 메시지 전송을 시작했다면 중간에 데이터 타입을 변경해서는 안 된다. (필요시에는 새로운 토픽을 생성해야 한다.)
Consumer Group
파티션 0~4까지 5개의 파티션으로 이루어진 토픽과 컨슈머 1~3 3개의 컨슈머로 이루어진 컨슈머 그룹이 있다고 해보자.
컨슈머 그룹 내에 있는 각각의 컨슈머는 서로 다른 파티션으로부터 읽기 작업을 수행한다. 이런 식으로 그룹이 카프카 토픽 전체를 읽게 된다.
컨슈머의 개수를 파티션 개수보다도 더 많게 설정한다면 몇몇 컨슈머는 inactive 상태가 될 것이다.
하나의 토픽에 다수의 컨슈머 그룹을 둘 수도 있다. 각 컨슈머 그룹은 독립적으로 읽기 작업을 수행할 것이고 다만 같은 컨슈머 그룹에 속해 있는 컨슈머들은 서로 다른 파티션의 읽기 작업을 수행할 것이다.
- 다수의 컨슈머 그룹이 있는 이유는 무엇일까? 같은 데이터로부터 서로 다른 서비스를 제공할 수 있을 것이다. 서비스당 하나의 컨슈머 그룹을 가지게 된다.
- 각각의 컨슈머 그룹 생성을 위해 group.id라는 컨슈머 프로퍼티를 사용하여 컨슈머 그룹에 이름을 지어줄 것이다. 이를 통해 컨슈머는 자신이 속한 그룹을 알 수 있다.
Consumer Offset
컨슈머 그룹이 읽고 있던 오프셋을 저장한다.
Kafka 토픽 안에서 __consumer_offsets로 오프셋 정보가 저장된다.
컨슈머가 토픽으로부터 데이터를 읽은 뒤에 주기적으로 오프셋 정보를 커밋 한다. 이를 통해 토픽의 데이터를 어디까지 성공적으로 읽었는지 알 수 있다. 컨슈머가 죽더라도 다시 돌아왔을 때 읽었던 곳으로부터 다시 읽어올 수 있을 것이다.
Delivery semantics for consumers
컨슈머가 데이터를 읽는 전략에는 3가지 방식이 있다.
- At least once (usually preferred)
- 메시지가 처리된 직후에 오프셋을 커밋 한다.
- 처리가 잘못된다면 메시지를 다시 읽는다.
- 따라서 메시지 처리가 반복적으로 수행될 수 있으므로 메시지 처리가 멱등성을 가지도록 해야 한다.
- At most once
- 컨슈머가 메시지를 받자마자 오프셋을 커밋 한다. (메시지가 실제 처리되기 전에 오프셋 커밋)
- 처리가 잘못되면 일부 메시지를 잃게 된다.
- Exactly once (추후 자세히 정리 필요)
- 메시지를 딱 한 번 처리한다.
- 트랜잭션 API (Kafka 스트림 API를 사용하면 쉽게 처리 가능)
참고)
'Kafka' 카테고리의 다른 글
[Kafka] 'Topic Replication'에 대해 알아보자 (0) | 2024.03.11 |
---|---|
[Kafka] 'Broker'에 대해 알아보자 (0) | 2024.03.06 |
[Kafka] 'Producer과 Message key'에 대해 알아보자 (0) | 2024.03.02 |
[Kafka] 'Topic과 Partition'에 대해 알아보자 (0) | 2024.02.28 |