데이터 엔지니어 기술 블로그

[🧙Kafka] 카프카 정리 - 기본 개념 본문

데이터 엔지니어링

[🧙Kafka] 카프카 정리 - 기본 개념

jun_yeong_park 2021. 3. 12. 13:29
반응형

카프카

아파치 카프카

포춘 500대 기업의 1/3을 포함하여 많은 조직에서 사용되고 있다. 끊임없이 진화하고 성장하는 스트림으로 데이터를 처리하는데에 중점을 두었다.

카프카는 메세징 시스템이지만 클러스터로 실행되고 수동으로 연결하는 개별적인 메시징 브로커 대신에 회사의 모든 데이터 스트림을 처리를 위한 탄력적으로 확장할 수 있는 중심 플랫폼 역할을 한다. 실시간 버전의 하둡을 생각하고 만들어졌다.

 

 

 

 

메세지 발행과 구독하기(publish/subscribe)

이 구조에서는 데이터를 발행자가 구독자에게 직접 보내지 않고 중간에 브로커가 도와준다.

Pub/Sub 구조가 아닌 곳에서는 여러 서버에서 나오는 로그, 메트릭 등을 사용해야 할 때 모니터링 서버, 분석 서버, UI 서버 등에 각자 연결해야 하지만 Pub/Sub구조라면 중간 서버에로 보내면 사용하는 곳에서 가져가는 형식으로 단순화 할 수 있다.

카프카는 분산 커밋 로그 또는 분산 스트리밍 플랫폼이라고도 한다. 파일 시스템이나 데이터베이스의 커밋 로그는 시스템의 상태를 일관성 있게 유지 할 수 있도록 모든 트랜잭션을 지속적으로 기록한다. 카프카도 이와 같은 방식으로 지속해서 저장하고 읽을 수 있다.

 

메시지와 배치

데이터의 기본 단위를 메시지라고 한다. 카프카는 메시지를 바이트 배열의 데이터로 간주한다. 메시지에는 키라는 메타데이터가 존재한다.

카프카의 메시지 데이터는 토픽으로 분류된 파티션에 수록된다. 

데이터를 수록할 파티션을 결정하기 위해 일관된 해시 값으로 키를 생성한다. 같은 키 값을 갖는 메시지는 항상 같은 파티션에 수록된다.

 

토픽, 파티션, 메세지

 

파티션의 데이터는 아래와 같이 저장된다.

출처: https://www.instaclustr.com/a-visual-understanding-to-ensuring-your-kafka-data-is-literally-in-order/

스키마

카프카는 단순히 바이트 배열로 처리하지만, 내용을 이해하기 쉽도록 메시지의 구조를 나타내는 스키마를 사용할 수 있다.

스키마로 JSON, XML 등의 형식을 사용할 수 있으나 데이터 타입의 지원이 부족하고 스키마 버전 간 호환성이 떨어지므로 Avro를 선호한다.

Avro는 하둡을 위해 개발된 직렬화 프레임워크이다. 스키마 구버전과 신버전의 호환성을 제공하고 강력한 데이터 타입을 지원한다.

기존에는 메시지 쓰기와 읽기 작업이 중간을 거치지 않아서 한 쪽에서 업데이트하면 다른 쪽도 업데이트 해주어야 했지만, 스키마를 공유 레포지터리에 저장하여 사용할 수 있으므로 애플리케이션 변경 없이 메시지를 처리할 수 있다.

 

- 직렬화의 목적은 객체를 상태 그대로 파일이나 데이터베이스에 저장하고, 이후에 다시 불러와서 사용하는 것이다.

- avro 직렬화 예시

import avro.schema
from avro.datafile import DataFileReader, DataFileWriter
from avro.io import DatumReader, DatumWriter

schema = avro.schema.parse(open("user.avsc").read())  # need to know the schema to write

writer = DataFileWriter(open("users.avro", "w"), DatumWriter(), schema)
writer.append({"name": "Alyssa", "favorite_number": 256})
writer.append({"name": "Ben", "favorite_number": 7, "favorite_color": "red"})
writer.close()

 

카프카 메시지 처리 방식 정리

1. 프로듀서가 토픽에 메시지를 추가한다. 그러면 토픽안에 있는 파티션에 순서대로 쌓인다. 파티션이 여러개고, 프로듀서가 메시지를 보낼 때 key를 지정했으면 해시값을 구해서 파티션을 할당하며 지정하지 않았으면 라운드 로빈으로 할당된다. 파티션이 여러개면 메시지가 나눠서 저장된다.

2. 컨슈머가 토픽에 쌓인 순서대로 이전에 가져간 곳 부터 메시지를 복사해서 가져간다. 큐의 메시지는 삭제되지 않는다. 

새로운 컨슈머가 붙었을 때는 처음부터 가져가고 똑같이 복사해서 가져간다.

3. 파티션의 레코드는 최대 레코드 보존 시간이나 보존 크기가 넘으면 삭제된다.

 

 

 

Replication Factor

고가용성을 유지하기 위해 토픽을 이루는 파티션을 리플리케이션 할 수 있다.

토픽 1개는 하나의 브로커에 저장된다. 그러나 리플리케이션 팩터의 수를 2 이상으로 늘리면 여러 브로커에 저장될 수 있다.

리플리케이션 팩터의 수가 3개라면, 하나는 리더가 되고 나머지는 팔로워가 된다.

만약 마스터가 다운된다면 팔로워가 새로운 리더가 되어 메시지를 문제없이 처리할 수 있게 된다.

 

프로듀서와 컨슈머

기본적으로 프로듀서는 메시지가 어떤 파티션에 수록되는지 관여하지 않으나, 키와 파티셔너라는 것을 사용하여 관여할 수 있다. 파티셔너는 키의 해시값을 생성하고 특정 파티션에 대응하여 항상 같은 파티션에 수록될 수 있게 해준다.

 

컨슈머는 오프셋(offset)을 유지하여 메시지의 전에 읽었던 메시지의 위치를 알 수 있다. 이것을 이용해 중지하였다가 다시 읽어도 오프셋 부터 읽을 수 있다.

 

컨슈머 그룹은 하나 이상의 컨슈머로 구성된다. 한 토픽을 소비하기 위해 같은 그룹의 여러 컨슈머가 함께 동작한다. 한 토픽의 각 파티션은 하나의 컨슈머만 소비할 수 있다. 이것을 소유권(ownership) 이라고 한다.

Consumer Group

 

브로커와 클러스터

하나의 카프카 서버를 브로커라고 하고 메시지를 수신하면 오프셋을 지정하고 자신의 디스크에 저장한다. 브로커는 클러스터의 일부로 동작한다.

브로커 중 하나는 자동으로 클러스터 컨트롤러(cluster controller)로 선정된다. 컨트롤러는 각 브로커에게 담당 파티션을 할당하고 브로커들을 모니터링하는 등의 기능을 맡는다.

각 파티션은 클러스터의 한 브로커가 소유하며 그 브로커를 파티션 리더(partition leader) 라고 한다. 그 외에 복제(replication) 되는 브로커를 파티션 팔로워(partition follower)라고 한다.

 

보존(retention)

일정 기간 메시지를 보존하는데, 7일 / 크기 1GB라고 토픽 크기를 지정하면 7일이 넘거나 1GB가 넘으면 삭제된다. 

압축 로그라는 기능이 있는데 이 기능을 사용하면 같은 키를 가진 메시지를 두 번 이상 보냈다고 했을 때 가장 최신 메시지만 저장되고 그 이전 것은 사라진다.

 

다중 클러스터

다중 데이터센터로 클러스터가 설치되어 동작할 때 메시지가 데이터센터 간에 복제되어야 하기 하는데 이런 경우에 사용할 수 있다.

다중 클러스터를 지원하기 위해 카프카 프로젝트에는 미러메이커(MirrorMaker)라는 도구가 포함되어 있다. 이 도구도 컨슈머와 프로듀서로 큐(queue)로 연결된다.

 

카프카를 사용하는 이유 

  • 다중 프로듀서
  • 다중 컨슈머
  • 디스크 기반의 보존(유실될 가능성 낮음)
  • 확장성(소규모에서 시작해서 인프라가 확장됨에 따라 카프카의 사이즈도 증가시킬 수 있음)
  • 고성능

 

데이터 생태계

프로듀서 - 메트릭, 로그, 트랙젝션 데이터, 사물인터넷 데이터 등

컨슈머 - 온라인 애플리케이션(Apache Solr, OpenTSDB), 스트림 처리(Samza, Spark, Storm, Flink), 오프라인 처리(Hadoop)

 

 

이용 사례

링크드인의 활동 추적

- 웹 사이트에 접속하여 페이지 이동, 특정 컨텐츠 조회 등을 수행하면 이것에 관한 메시지 데이터를 생성하는 프론트엔드 앱이 동작한다. 페이지 뷰와 클릭 기록 등을 카프카로 보내면 백엔드에서 리포트를 생성하거나, 머신 러닝 시스템에 제공하는 등의 작업을 한다.

 

메시지 전송

- 사용자에게 알림 메시지(이메일 등)를 전송하는 애플리케이션에 유용하다. 각 애플리케이션에서 전송될 모든 메시지를 카프카로 보내서 카프카에서 알림 메시지로 애플리케이션으로 보내 사용자가 원하는 수신방법을 적용하여 사용자에게 보낸다.

 

메트릭과 로깅

- 애플리케이션과 시스템의 메트릭과 로그 데이터를 모으는데 이상적이다. 각 애플리케이션에서 카프카 토픽으로 저장한 후 모니터링과 보안 시스템이나 하둡 등에서 사용될 수 있다. 또는 ElasticSearch에서도 사용될 수 있다.

 

커밋 로그

- 카프카는 커밋 로그를 기반으로 한다. 커밋 로그는 데이터가 변경된 내역을 로그 메시지로 모아둔 것을 말한다.

- 데이터베이스의 변경 사항이 카프카 메시지 스트림으로 생성될 수 있다. 애플리케이션에서는 해당 스트림을 모니터링하여 발생 시점의 최신 변경 데이터를 받을 수 있으며 변경 로그 스트림(changelog stream)이라고 한다. 

- 변경 데이터를 원격 시스템에 복제하거나, 여러 애플리케이션의 변경 데이터를 하나의 데이터베이스 뷰로 통합할 수 있다.

- 변경 데이터를 모아두는 버퍼를 카프카의 메시지 보존 기능으로 사용할 수 있다.

 

스트림 프로세싱

- 하둡에서는 긴 시간에 걸쳐 데이터를 사용하고 카프카는 실시간으로 처리하는데, 실시간 처리 기능을 스트림 프로세싱이라고 한다.

 

카프카의 기원

링크드인에서 복잡한 추적 요청이 있었는데 그것은 사용자 요청이 내부의 여러 애플리케이션에서 어떻게 전달되고 있는지 알아내는 것이었다. 기존의 모니터링 시스템에서는 폴링 기반으로 메트릭을 집중 처리했으나 시간 간격이 길었고 애플리케이션 소유자가 자신의 메트릭을 관리할 수 없었다. 같은 내용을 측정하는 메트릭이어도 시스템이 달랐을 때 일관성이 없었다.

HTTP로 사용자 활동 정보를 추적하는 시스템도 있었으나 XML형식이었고 일관성이 없었다. 스키마 통일을 위해 시스템이 중단되는 경우도 있었다.

ActiveMQ를 사용하려고 했으나 브로커를 중단시키는 결함이 발생되었고 시스템 확장을 지원하지 못했다.

 

 

 

[카프카 핵심 가이드]를 참조하였습니다.

반응형
Comments