Meet Kafka
by Jaesang Lim
1. 카프카를 만나보자!
이렇게 복잡하게 처리하지 말고 한 곳에서 데이터를 받은 다음 필요한 곳으로 보내줄 수는 없을까?..
Pub/Sub Messaging System을 이용한 구조
- 메시징 패러다임 중 하나
- Subscriber가 정해져 있지 않고 대신 Publisher가 발행한 메시지는 정해진 범주에 따라, 각 범주에 대한 구독을 신청한 Subscriber에게 전달됨
- Subscriber는 Publisher에 대한 지식이 없어도 원하는 메시지만을 수신할 수 있음
- 이렇게 Publisher와 Subscriber를 분리함으로써 융통성있는 네트워크 토폴로지와 높은 확장성을 가능케 함
그렇다면 이 상황에서 Kafka를 쓴다면 ?!?! GOOOD!
Apache Kafka
- LinkedIn에서 오픈소스로 공개
- 빠르고 확장 가능하며 고가용성의 분산 메시징 시스템
- 실시간 데이터 전송을 위한 통합 시스템으로 설계되었음
- 전통적인 메시징 모델인 “Publish - Subscribe”와 “Queueing”의 장점을 혼합
- 메시징 모델
- Publish - Subscribe
- Publisher가 Subscriber로 데이터를 Broadcast하기 때문에 확장이 어려움
- Queuing
- 여러 Consumer가 하나의 Queue에서 데이터를 읽을 수 있으므로 데이터 처리를 쉽게 분산시킬 수 있음
- Queue는 Multi Subscriber를 지원하지 않기 때문에 한 번에 하나의 프로세스만 데이터를 읽을 수 있음
- Publish - Subscribe
메세지 ( Message)
- Kafka의 데이터 처리 단위 ( 데이터베이스로 비유하면 Row나 Record )
- Kafka는 메시지를 바이트 배열로 처리하며 메시지 포맷은 관심없음
- 바이트 배열로 처리하는 이유는 성능과 관련이 있다고 함 관련 문서
- 메시지는 Key라고 불리는 메타데이터를 포함할 수 있음
- Key 역시 바이트 배열이고 Kafka는 Key에 대해서도 관심갖지 않음
- Key는 메시지를 어느 파티션에 저장할지 결정할 때 사용
배치 ( Batch )
- 효율성을 이유로 Kafka에서는 메시지를 배치로 처리
- 배치는 같은 토픽, 같은 파티션에 저장되는 메시지 묶음
- 한 번에 처리되는 메시지양을 늘리면 처리량은 향상되는 대신 지연 시간이 늘어남
- 배치는 네트워크 전송 비용과 저장 비용 감소를 위해 압축할 수 있음
스키마 (Schema)
- 메시지는 바이트 배열이지만 쉽게 이해할 수 있도록 스키마를 갖는 것을 추천
- 일관성있는 데이터 형식은 쓰기와 읽기를 분리 가능하게 함
- 쓰기와 읽기가 강하게 연결되어 있으면 호환성 유지를 위해 한 쪽이 수정되면 다른 한 쪽도 수정이 필요함
- 많은 Kafka 개발자들은 Apache Avro를 선호함
- Apache Avro의 장점
- 스키마가 메시지 내용과 분리
- 스키마 변경에도 코드 수정 불필요
- 강한 타입 체크
- 스키마 변경에도 호환성 유지 가능
토픽과 파티션
- 메시지는 토픽으로 분류
- 데이터베이스에서 테이블이 토픽과 비슷한 역할을 함
- 토픽은 다시 파티션으로 나누어짐
- 파티션은 “Append Only”이며 파티션에 저장된 메시지는 들어온 순서대로 읽힘
- 파티션 내에서는 들어온 시간 순으로 정렬되어 있으나
- 토픽 내 전체 파티션 내에서는 시간 순으로 정렬되어 있는 것을 보장하지 않음
- 파티션은 여러 서버에 분산될 수 있기 때문에 Kafka는 파티션을 통해 Redundancy와 Scalability를 제공
Producer
- Kafka의 데이터를 사용하는 두 개의 클라이언트 중 하나
- 메시지 (Message)를 만들어내는 생산자
- 생산한 메시지는 Kafka로 보냄
- 생산한 메시지는 토픽 (Topic)으로 분류
- 메시지가 어느 파티션에 저장되는지 관심없음
- 다만, 메시지에 포함된 Key로 같은 Key를 가진 메시지가 같은 파티션에 저장되도록 할 수 있음
Consumer
- Kafka에서 데이터를 사용하는 두 개의 클라이언트 중 하나
- 하나 이상의 토픽을 구독하거나 토픽을 구독하지 않을 수 있음
- 메시지는 생산된 순서대로 읽음
- 오프셋 (Offset)
- Consumers는 파티션에서 읽은 부분까지를 오프셋 (Offset)으로 기억하기 때문에 Conumser가 중단되거나 재시작되더라도 위치를 잃어버리지 않음
- 메시지가 만들어질 때 부여됨
- 오프셋은 증가하는 정수값
- 오프셋은 Kafka 내부나 Zookeeper에 저장됨
- Consumer Group
- 하나 이상의 Consumer가 하나의 토픽을 같이 구독
- Consumer Group은 각 파티션이 그룹 내 오직 하나의 멤버만 접근하도록 보장
브로커 (Broker)
- Kafka 서버 하나를 브로커라고 부름
- 브로커는 다음 역할을 수행
- Producer에서 생산한 메시지를 수신
- 메시지에 오프셋을 붙임
- 메시지를 디스크에 저장
- Consumer의 요청을 처리
- 하드웨어와 사용 방식에 따라 한 대의 브로커가 1초에 수백만 개의 메시지를 처리할 수 있음
클러스터 ( Cluster)
- 브로커는 클러스터로 동작하도록 설계되었음
- 클러스터의 브로커 중 하나는 “Cluster Controller” 역할을 함
- Cluster Controller는 살아있는 멤버 중 하나에서 자동으로 선출됨
- 브로커에 파티션을 할당하거나 장애 상황을 모니터링하는 등의 관리자 역할을 함
- 복제 (Replication)
- 같은 파티션을 여러 브로커에 복제하여 저장 가능
- 그러한 파티션들 중 하나는 그 파티션의 리더가 되고 그 파티션에 읽기나 쓰기 작업을 할 때는 리더 파티션에서만 처리할 수 있음
- 리더 파티션에 장애가 발생하면 다른 파티션이 리더가 됨
리텐션 (Retention)
- 메시지를 소비된 이후에도 일정 기간동안 저장하는 기능
- 메시지 보존은 기간이나 용량으로 설정할 수 있음
- 토픽 별로 리텐션 설정을 다르게 할 수 있음
- “log compacted”로 설정되면 Key별로 가장 마지막에 생산된 메시지만 보존함
Kafka를 사용해야 하는 이유
- Multiple Producers
- 여러 Producer가 한 개 또는 여러 개의 토픽을 구독할 수 있음
- Multiple Consumers
- Consumer들이 서로 영향을 끼치지 않고 메시지를 자유롭게 읽을 수 있는데 이러한 점은 다른 메시징 시스템에서는 불가능함
- Disk-Based Retention
- 실시간 처리 뿐만 아니라 다른 요구사항에도 대응 가능
- 또한 리텐션은 데이터 유실도 방지
- Scalable
- 확장은 장비를 내리지 않고 가능하고 시스템의 가용성에 영향을 주지 않음
- High Performance
참고자료
이 글은 Kafka: The Definitive Guide 원서를 읽고 정리한 내용입니다 :)
Subscribe via RSS