목차
0. 카프카에 대해 알아보기
1. 발행/구독 메세지 전달
- 발행/구독 메세지 전달 publish/subscribe messaging
- 전송자(발행자)가 데이터(메세지)를 보낼 때 직접 수신자(구독자)에게 보내지 X
- 전송자는 어떤 형태로든 메세지 분류하여 전송
- 수신자는 이렇게 분류된 메세지를 구독
- 보통, 메세지를 전달받고 중계해주는 중간 지점 역할을 하는 브로커 broker가 존재
초기의 발행/구독 시스템
- 발행자와 구독자가 직접 연결된 경우
- 메세지 큐나 프로세스 간 통신 채널을 놓는 것
- e.g. 모니터링 지표 전송하는 애플리케이션
- 지표 서버, 프론트엔드 서버
- 서비스가 발전하면서, 지표를 여러 목적으로 활용하는 많은 어플리케이션이 추가됨
- → 연결 추적 어려움
- → 기술 부채 technical debt 명백
- → 모든 애플리케이션으로부터 지표를 받는 하나의 애플리케이션을 만들고, 이 지푯값들을 필요로 하는 시스템 및 지표 질의 서버 제공
- → 메세지 발행/구독 시스템
- e.g.지푯값 발행/구독
- 메세지 큐나 프로세스 간 통신 채널을 놓는 것
개별 메세지 큐 시스템
- 지표를 다루는 것 이외에도 로그 메세지 및 사용자 활동이 필요한 경우
- → 비슷한 시스템을 구성하여, 정보의 발행자와 구독자를 분리
- → 세 개의 발행/구독 시스템 (다수의 발행/구독 시스템) 구축
- 이는 메세지 큐나 프로세스 간 통신 채널을 놓는 포인트 투 포인트 point-to-point 연결 활용 방식보다 바람직
- 그러나, 중복이 많음
- 버그도 한계도 제각각인 다수의 데이터 큐 시스템 유지 관리 필요
- 메세지 교환 필요로 하는 사레 추가 발생 가능
- 일반화된 유형의 데이터를 발행하고 구독할 수 있는 중앙 집중화된 시스템 필요
2. 카프카 입문
- 아파치 카프카
- 앞서 말한 내용과 같은 문제를 해결하기 위해 나온 메세지 발행/구독 시스템
- 파일시스템, 데이터베이스
- 커밋 로그 commit log: 모든 트랜직션을 기록, 지속성 있게 보존 → 시스템 상태를 일관성 있게 복구 가능
- 데이터는 순서를 유지한채로 지속성 있게 보관, 결정적 deterministic으로 읽기 가능
- 확장시 성능을 향상시키고, 실패 발생 시에도 데이터 사용에는 문제가 없도록 시스템 안에서 데이터 분산 저장 가능
메세지와 배치
- 메세지 message
- 카프카 데이터의 기본 단위
- 데이터베이스의 로우 row나 레코드 record와 비슷해 보일 수도 있음
- 메세지=단순히 바이트의 배열 → 특정한 형식이나 의미 X
- 키
- 메세지는 키 key라 불리는 메타데이터 포함 가능
- 특별한 의미 없는 바이트 배열
- 메세지 저장할 파티션 결정하기 위해 사용됨
- 가장 간단한 방법: 키값에서 일정한 해시값을 생성, 이 값을 토픽의 파티션 수로 나눈 뒤, 나머지 값에 해당하는 파티션에 메세지를 저장
- → 같은 키값을 가진 메세지는 항상 같은 파티션에 저장됨 (파티션 수가 변하지 않는 한)
- 배치 batch
- 메세지를 배치 batch 단위로 저장
- 토픽의 파티션에 쓰여지는 메세지들의 집합
- 메세지를 쓸 때, 네트워크상에서 신호가 오가는 것은 막대한 오베헤드를 발생시킴. 배치 단위 사용 시 이를 감소시킬 수 있음
- 지연 latency과 처리량 throught 사이에 트레이드 오프 발생
- 배치 크기가 커질수록 시간당 처리되는 메세지 수는 증가
- 각각의 메세지가 전달되는 데 걸리는 시간 증가
- 효율적인 데이터 전송과 저장을 위해, 처리 능력을 들여서 압축되는 경우가 많음
스키마
- 내용을 이해하기 쉽도록 일정한 구조(=스키마)를 부여하는 것이 권장됨
- 쓰기 쉽고 사람이 알아볼 수 있는
- JSON JavaScript Object Notation
- XML eXtensible Markup Language
- 타입 처리 기능이나 스키마 버전 간의 호환성 유지 기능 떨어짐
- 카프카 개발자들이 선호
- 아파치 에이브로 Avro
- 직렬화 프레임워크는 원래 하둡 프로젝트를 위해 개발된 것
- 조밀한 직렬화 형식 제공
- 메세지 본체와 스키마 분리 → 스키마 변경 시에 코드 생성 필요 X
- 강력한 데이터 타이핑 typing, 스키마 변경에 따른 상위 호환성, 하위 호환성 지원
- 아파치 에이브로 Avro
- 카프카에서는 일관적인 데이터 형식이 중요
- 메세지 쓰기와 읽기 작업 분리 가능
- 결합 시
- 메세지 구독하는 애플리케이션들 먼저 구버전, 신버전 동시 지원할 수 있도록 업데이트 필요
- 메세지 발행하는 애플리케이션이 신버전 형식을 사용하도록 업데이트
- 즉, 잘 정의된 스키마를 공유 저장소에 저장
- 카프카는 두 버전 형식을 동시에 지원하는 작업 없이도 메세지 처리 가능
토픽과 파티션
- 메세지는 토픽topic 단위로 분류
- 데이터베이스의 테이블이나 파일시스템의 폴더와 유사한 개념
- 토픽은 파티션partition으로 나뉘어짐
- 파티션은 하나의 로그에 해당
- 파티션에 메세지가 쓰여질 때, 추가만 가능 append-only 형태로 쓰여짐
- 읽을 때 맨 앞부터 제일 끝까지 순서로 읽힘
- 토픽에 여러 개의 파티션이 있기 때문에, 토픽 안의 메세지 전체에 대한 순서는 보장되지 않음
- 카프카가 데이터 중복과 확장성을 제공하는 방법
- 각 파티션이 서로 다른 서버에 저장 가능
- 하나의 토픽이 여러 개의 서버로 수평적 확장
- 파티션 복제 가능
- 서로 다른 서버들이 동일한 파티션의 복제본 저장
- 서버 중 하나에 장애가 발생 시 상황 처리 가능
- 스트림 stream
- (파티션의 개수와 상관 없이) 하나의 토픽에 저장된 데이터
- 프로듀서producer로부터 컨슈머consumer로의 하나의 데이터 흐름을 나타냄
- 메세지의 집합 = 스트림
- 메세지를 실시간으로 처리하는 것처럼, 스트림 처리 stream processing에 대해 이야기할 때 사용됨
- e.g. 카프카 스트림즈, 아파치 삼자, 아파치 스톰 등
- ↔ 하둡 (시간이 흐른 뒤 데이터를 대량으로 한 번에 처리)
프로듀서와 컨슈머
- 카프카 클라이언트 = 이 시스템의 사용자
- 프로듀서, 컨슈머
- 고급 클라이언트 API
- 카프카 커넥트 Kafka Connect API, 카프카 스트림즈
- 프로듀서
- 새로운 메세지를 생성
- 다른 발행/구독 시스템에서는 발행자 혹은 작성자 라고 부름
- 메세지는 특정한 토픽에 쓰여짐
- 기본) 메세지 파티션들 사이에 고르게 나눠서 씀
- 프로듀서가 특정한 파티션 지정해서 메세지를 쓰기도 함
- 메세지 키와 키값의 해시를 특정 파티션으로 대응시켜 주는 파티셔너 사용
- 메세지를 파티션으로 대응하는 다름의 규칙을 가진 컨스텀 파티셔너 사용
- 컨슈머
- 메세지를 읽음
- 다른 발행/구독 시스템에서는 구독자 혹은 독자 라고 부름
- 1개 이상의 토픽 구독
- 여기에 저장된 메세지들을 각 파티션에 쓰여진 순서대로 읽어옴
- 메세지의 오프셋 offset을 기록, 어느 메세지까지 읽었는지 유지
- 오프셋: 지속적으로 증가하는 정수값
- 메세지 저아 시 각각의 메세지에 부여해주는 또 다른 메타 데이터
- 주어진 파티션의 각 메세지는 고유한 오프셋을 가짐
- 뒤에 오는 메세지가 앞의 메세지보다 더 큰 오프셋을 가짐
- 파티션별로 다음 번에 사용 가능한 오프셋 값을 저장
- → 컨슈머는 읽기 작업을 정지했다가 다시 시작 시 마지막 읽었던 메세지의 바로 다음 메세지부터 읽기 가능
- 컨슈머 그룹 consumer group
- 컨슈머는 컨슈머 그룹 consumer group의 일원으로서 작동
- 토픽에 저장된 데이터를 읽어오기 위해 협업하는 하나 이상의 컨슈머로 구성
- 각 파티션이 하나의 컨슈머에 의해서만 읽히도록 함
- 컨슈머에서 파티션으로의 대응 관계: 컨슈머의 파티션 소유권 ownership
- → 대량의 메세지를 갖는 토픽들을 읽기 위해 컨슈머 수평 확장 가능
- → 하나의 장애 발생 시, 그룹 안의 다른 컨슈머들이 장애가 발생한 컨슈머가 읽던 파티션 재할당 가능
브로커와 클러스터
- 브로커
- 하나의 카프카 서버를 브로커라고 부름
- 브로커: 프로듀서로부터 메세지를 전달받아 오프셋을 할당한 뒤 디스크 저장소에 씀
- 컨슈머의 파티션 읽기 fetch 요청 처리하고 발행된 메세지 보냄
- 하나의 브로커는 초당 수천 개의 파티션과 수백만 개의 메세지 쉽게 처리 가능
- 클러스터
- 카프카 브로커는 클러스터의 일부로서 작동하도록 설계됨
- 하나의 클러스터 안에 여러 개의 브로커 포함 가능
- 그 중 하나의 브로커가 클러스터 컨트롤러의 역할
- 컨트롤러는 클러스터 안의 현재 작동 중인 브로커 중 하나가 자동으로 선정됨
- 파티션을 브로커에게 할당, 장애를 발생한 브로커 모니터링 등의 관리 담당
- 파티션은 클러스터 안의 브로커 중 하나가 담당
- 그 브로커는 파티션 리더라고 부름
- 복제된 파티션이 여러 브로커에게 할당 가능 = 파티션의 팔로워
- 복제하여 파티션의 메세지 중복 저장
- → 리더 브로커에 장애가 발생 시, 팔로워 중 하나가 리더 역할 이어 받음
- 모든 프로듀서는 리더 브로커에 메세지를 발행해야, 컨슈머는 리더나 팔로워 중 하나로 데이터 읽기 가능
- 보존 기능 (아파치 카프카의 핵심 기능 중 하나)
- 일정 기간 동안 메세지를 지속성 있게 보관하는 보존 기능
- 특정 기간 동안 메세지를 보관하거나, 파티션 크기가 특정 사이즈에 도달할 때까지 데이터를 보관
- 한도 값에 도달하면 메세지는 만료되어 삭제됨
- 보존 설정은 어떤 시점에 있어서 사용 가능한 최소한의 데이터 양을 정의
- 각각의 토픽에는 메세지가 필요한 정도까지만 저장되도록 보존 설정 가능
- ex) 사용자 활동 추적 토픽: 며칠 동안 유지 가능
- ex) 애플리케이션 지표: 몇 시간 보존
- 토픽에는 로그 압착 log compaction 기능 설정 가능
- 같은 키를 갖는 메세지 중 가장 최신의 것만 보존
- 체인지로그changelog 형태의 데이터에 사용하면 좋음 (마지막 변경 값만 중요)
다중 클러스터
- 설치된 카프카 확장 → 다수의 클러스터 운영
- 장점1) 데이터 유형별 분리
- 장점2) 보안 요구사항을 충족시키기 위한 격리
- 장점3) 재해 복구를 대비한 다중 데이터 센터
- 미러메이커 MirrorMaker
- 카프카 프로젝트에서 데이터를 다른 클러스터로 복제하는 데 사용되는 툴
- 미러메이커 = 큐로 연결된 카프카 컨슈머와 프로듀서
- 집적 카프카 클러스터
3. 왜 카프카인가?
다중 프로듀서
- 카프카는 여러 프로듀서를 처리 가능
- → 프론트엔드 시스템으로부터 데이터를 수집, 일관성 유지하는 데 좋음
다중 컨슈머
- 카프카는 많은 컨슈머가 상호 간섭 없이 어떠한 메세지 스트림도 읽을 수 있도록 설계됨
- 큐 시스템과 결정적인 차이: 하나의 메세지를 하나의 클라이언트에서만 소비
- 카프카 컨슈머는 컨슈머 그룹의 일원으로 작동
- → 하나의 스트림을 여럿이서 나눠서 읽기 가능
디스크 기반 보존
- 메세지 지속성 있게 저장 가능
- = 컨슈머들이 항상 실시간으로 데이터 읽어올 필요 X
- 메세지는 디스크에 쓰여진 뒤 설정된 보유 규칙과 함께 저장됨
- 컨슈머를 정지하더라도, 메세지는 카프카 안에 남아 있음
- 컨슈머 다시 시작 시 작업 멈춘 지점에서부터 유실 없이 데이터 처리 가능
확장성
- 카프카는 유연한 확장성 가짐. 어떠한 크기의 데이터도 쉽게 처리 가능
- 하나의 브로커로 시작 → 3개의 브로커를 가진 소규모의 개발용 클러스터 → 수백 개 이상의 브로커로 구성된 대규모 클러스터로 이루어진 프로덕션 환경
- 카프카 클러스터는 작동 중에도 시스템 전체의 가용성에 영향을 주지 않으면서 확장 가능
- 동시 다발적인 장애를 견뎌야 하는 클러스터 → 더 큰 복제 팩터 설정
고성능
- 지금까지의 특징들 덕분에 고부하 아래에서도 카프카는 높은 성능을 보여주는 발행/구독 메세지 전달 시스템이다
플랫폼 기능
- 아파치 카프카의 코어 프로젝트에는 개발자들이 자주하는 작업을 훨씬 쉽게 수행할 수 있도록 해주는 플랫폼 기능이 추가되어 있음
- 탄탄한 기반, 자유로운 형태로 실행, 유연성을 갖춘 API와 라이브러리 형태로 사용 가능
- 카프카 커넥트: 소스 데이터 시스템으로부터 카프카가 데이터를 가져오거나 카프카의 데이터를 싱크 시스템으로 내보내는 작업을 도와줌
- 카프카 스트림즈: 규모 가변성 scalability과 내고장성 fault tolerance을 갖춘 스트림 처리 애플리케이션을 쉽게 개발할 수 있게 해주는 라이브러리
4. 데이터 생태계
- 데이터 생태계에 있어서 순환 시스템을 제공
- 모든 클라이언트에 대해 일관된 인터페이스 제공
- 시스템과 결합하면 프로듀서와 컨슈머는 더 이상 어떤 형태로 밀접하게 결합되거나 연결된 필요 X
이용 사례
- 활동 추적
- 링크드인에서 처음 의도했던 카프카의 원래 용도: 사용자 활동 추적
- 웹사이트의 사용자가 뭔가 행동할 때마다 이에 대한 메세지 생성하는 프론트엔드 애플리케이션 작동
- 이 메세지들은 하나 이상의 토픽으로 발행되어 백엔드에서 작동 중인 애플리케이션에 전달
- 메세지 교환
- 카프카는 메세지 교환하는 데도 사용 가능
- 사용자에게 알림을 보내야하는 애플리케이션에서 활용 가능
- 메세지 형식이나 전송 방법에 신경 쓸 필요 X
- 지표 및 로그 수집
- 카프카는 애플리케이션과 시스템의 지푯값과 로그를 수집하는 데도 이상적
- 애플리케이션이 정기적으로 지푯값을 카프카 토픽에 발행
- 모니터링과 경보를 맡고 있는 시스템이 지푯값들을 가져다 사용
- 로그 메세지 역시 같은 방식으로 발행 가능
- 커밋 로그
- 데이터베이스에 가해진 변경점들이 카프카로 발행됨 (스트림의 형태)
- 이 스트림을 통해 실시간 업데이트를 받아볼 수 있음
- 체인지로그 스트림
- 데이터베이스의 업데이트를 원격 시스템으로 복제 가능
- 다수의 어플리케이션에서 발생한 변경점을 하나의 데이터베이스 뷰로 통합 가능
- 스트림 처리
- 메세지 생성되자마자 실시간으로 데이터 처리
- 스트림 처리 프레임워크
5. 카프카의 기원
- 카프카는 링크드인 내부에서의 데이터 파이프라인 문제를 해결하기 위해 개발됨
- 다양한 종류의 데이터를 다루고 고성능 메세지 교환 시스템 역할
링크드인이 직면한 문제
- 모니터링 시스템의 결함
- 폴링 방식. 긴 지표 수집 간격. 많은 수작업. 일관성 X 등
- 사용자 활동 정보 추적 시스템의 결함
- HTTP 서비스 → XML 메세지 배치. 일관성 X. 파싱 비용 ↑
- 추적되는 사용자 활동 유형 변경하려면 프론트 엔드, 오프라인 처리시스템 추가 작업 필요
- 모니터링 시스템, 사용자 활동 추적은 같은 벡엔드 서비스 사용 불가
- 수평 확장, 규모 확장성, 신속성, 리스크 등
- → 커스텀 인프라스트럭처 자체 개발
카프카의 탄생
- 주된 목표
- 푸시-풀 모델 사용 → 프로듀서와 컨슈머를 분리
- 다수의 컨슈머가 사용할 수 있도록, 메세지 교환 시스템의 데이터를 영속적으로 저장
- 높은 메세지 처리량을 위해 최적화
- 데이터 스트림 양 증가에 따른 수평 확장 가능
오픈소스
- 깃허브에 오픈소스에 공개 → 아파치 소프트웨어 재단의 프로젝트
- 가장 큰 데이터 파이프라인에서 사용됨
상업적 제품
- 컨플루언트 Confluent
- 헤로쿠 Heroku와 같은 다른 기업과 함께 클라우드 기반 카프카 서비스 제공
- 그외 클라우드 플랫폼과 협업
'Boaz > Real-time Data and Kafka' 카테고리의 다른 글
[카프카 핵심 가이드 #3] 4장 카프카 컨슈머: 카프카에서 데이터 읽기 (0) | 2024.08.22 |
---|---|
[카프카 핵심 가이드 #2] 3장 카프카 프로듀서: 카프카에 메시지 쓰기 (0) | 2024.08.22 |
[대규모 실시간 데이터 처리 #4] 대규모 시스템 설계 기초. 12장 채팅 시스템 설계 (0) | 2024.08.04 |
[대규모 실시간 데이터 처리 #3] 대규모 시스템 설계 기초. 9장 웹 크롤러 설계 (0) | 2024.08.04 |
[대규모 실시간 데이터 처리 #2] 대규모 시스템 설계 기초. 2장~3장 개략적인 규모 추정, 시스템 설계 면접 공략법 (0) | 2024.07.28 |