하둡 에코시스템 정리 첫번 째 kfka

++아래 내용은 카프카 도큐먼테이션을 자의적으로 해석한 내용임으로 오류가 있을 수 있습니다. (http://kafka.apache.org/intro)++

kfka 도큐먼트 에서 카프카는 분산 스트리밍 플랫폼이라 정의 하고 있다.

카프카에서 정의하는 분산 스트리밍은 크게 3가지 key 포인트를 가지고 있다.

  1. 스트림 레코드를 생성(publish)하고 소비(subscribe) 하며, 이러한 점들은 메세지 큐 또는 엔터프라이즈 메시징 시스템과 유사하다.

  2. 결함없는 스트림 데이터의 저장 [장애 대응력(?)]

  3. 레코드의 스크트림 처리

그렇다면 카프카는 어디에 좋을까?

카프카는 다음과 같이 광범위한 두가지 어플리케이션에 사용되기 좋다.

  1. 시스템이나 어플리케이션 사이에서 신뢰성 있는 데이터를 얻기 위한 실시간 데이터 파이프라인의 구축

  2. 스트림 데이터에 반응 하거나 변환하는 실시간 스트리밍 어플리케이션의 구축

카프카는 이러한 일들을 어떻게 수행 할까?

첫번째 컨셉
  • 카프카는 하나 또는 여러대의 클러스터 서버에서 동작 합니다.

  • 카프카 클러스터는 스트림을 topic으로 분류하여 저장 합니다.

  • 각각의 레코드는 키, 값, 타임스탬프로 이루어져 있습니다.

카프카는 4개의 핵심 API를 가지고 있습니다.
  • Producer API : 어플리케이션에서 하나 또는 그 이상의 topic 스트림을 발행 할 수 있게 한다. (생산)

  • Consumer API : 어플리케이션이 하나 또는 그 이상의 주제를 구독하여 생산된 스트림 데이터를 처리 할 수 있게 한다.

  • Streams API : 어플리케이션이 스트림 프로세서로 동작하게 할 수 있다. 하나 이상의 토픽으로부터 입력된 스트림을 소비하고, 하나 이상의 토픽으로 아웃풋 스트림을 생성 할 수 있고 인풋 스트림을 아웃풋 스트림으로 변환 할 수 있다.

  • Connector API : 커넥터 API는 기존의 어플리케이션이나 데이터 시스템을 카프카 토픽으로 연결하여 재사용 가능한 생산자와 소비자를 구축하고 실행 할 수 있다. 예를 들어 관계형 데이터베이스에 연결된 커넥터는 모든 테이블의 변경 사항을 캡쳐 할 수 있다.

카프카의 기본 구성 요소와 동작

카프카는 발행-구독 모델을 기반으로 동작하며 0.8.1 에서는 크게 producer, consumer, broker로 구성되었으나 현재(0.10.2)는 카프카 스트림이 추가 되었다.

0.8.1 0.10.2

|——–|——–|

</img> </img>

[ 카프카의 브로커는 토픽을 기준으로 메시지를 관리한다. 프로듀서는 특정 토픽의 메시지를 생성한 뒤 해당 메세지를 브로커에 전달한다. 브로커가 전달받은 메시지를 토픽별로 분류하여 쌓아 놓으면, 해당 토픽을 구독하는 컨슈머들이 메시지를 가져가서 처리하게 된다.

카프카의 브로커는 고가용성과 확장성을 위해 클러스터로 구성되며 1개의 브로커만 존재 할 경우에도 클러스터로 동작한다. 브로커의 분산 처리는 ZooKeeper가 담당한다.

출처: http://epicdevs.com/17 [Epic Developer] ]

</img>

(이미지 출처: http://blog.mmlac.com/log-transport-with-apache-kafka)

카프카의 특징
  1. 분산 시스템을 기본으로 설계되어 있어 분산 및 복제 구성이 쉽다.

  2. AMQP, JMS API등을 사용하지 않고 TCP 프로토콜을 사용하여 프로토콜 오버 헤드가 적다

  3. 프로듀서에서 생산자로 메세지를 전송 할 때 각 메세지를 개별적으로 하지 않고 다수의 메세지를 batch로 전송 가능하다 (TCP/IP 트립 감소)

  4. 메세지를 파일시스템에 저장한다.

    • 파일 시스템을 사용하기 때문에 영속성이 보장되고

    • 메세지를 많이 쌓아 두어도 메모리 소비가 적어 성능이 크게 저하되지 않으며

    • 많은 메세지를 쌓아 둘 수 있어 batch작업이 가능하다.

    • 처리된 메세지는 설정된 수명까지 남아 있어 메세지 처리중 문제가 발생 했을경우 메세지 재상용하여 다시 처리 할 수 있다.

    • push방식이 아닌 pull 방식이라 컨슈머는 자신이 처리 가능한 만큼의 메세지를 선택적으로 가져와 처리 하거나, 주기적으로 batch처리가 가능하다.

Topics and Logs

Topic은 발행된 레코드의 네임피드 또는 카테고리를 의미한다.

Topic은 파티션 단위로 쪼개어 클러스터에 각 서버에 분산 저장 된다. 복제시에도 파티션 단위로 복제되고 파티션 단위로 fail over가 수행된다.

각각의 파티션은 0부터 1씩 증가사는 시퀀스 값을 부여하는데 이 값은 각 파티션 내에서 메시지를 식별하는 ID로 사용된다. Offset 값은 파티션 마다 별도로 관리 되며 토픽 내에서 메시지를 식별할 때는 파티션 번호와 오프셋 값을 함께 사용한다.

발행된 메세지는 사용 여부와 관계없이 설정된 유지기간 동안 계속 유지되어 사용 할 수 있으며 설정 기간 이후에 삭제 된다. 데이터를 오래동안 쌓아 두어도 카프카 성능에는 큰 영향이 없다.

파티션 분산과 복제

로그(수집 데이터)는 카프카 클러스터의 서버에 분산 되어 저장되고 각각의 파티션들 장애 대응을 위해 교차 복제를 하여 저장 합니다.

각 파티션은 “리더”와 0개 또는 다수의 “팔로워”를 가지고 있습니다.

모든 읽기, 쓰기 작업은 리더 파티션에서 발생하며 팔로워는 리더를 계속 복제 합니다.

만약 리더에 장애가 발생하면 하나의 다른 팔로워가 자동으로 새로운 리더가 됩니다.

***아래 섹션은 카프카 파티션 복제에 대해 잘 정리된 글을 옮겨왔다.

[출처: http://epicdevs.com/17 [Epic Developer]]***


파티션 분산

위의 그림에서는 3개의 broker로 이루어진 클러스터에서 하나의 topic이 3개의 partition P0, P1, P2로 분산되어 저장되어 있다.

Producer가 메시지를 실제로 어떤 partition으로 전송할지는 사용자가 구현한 partition 분배 알고리즘에 의해 결정된다. 예를 들어 라운드-로빈 방식의 partition 분배 알고리즘을 구현하여 각 partition에 메시지를 균등하게 분배하도록 하거나, 메시지의 키를 활용하여 알파벳 A로 시작하는 키를 가진 메시지는 P0에만 전송하고, B로 시작하는 키를 가진 메시지는 P1에만 전송하는 형태의 구성도 가능하다.

좀 더 복잡한 예로써 사용자 ID의 CRC32값을 partition의 수로 modulo 연산을 수행하여(CRC32(ID) % partition의 수) 동일한 ID에 대한 메시지는 동일한 partition에 할당되도록 구성할 수도 있다.

Partition의 복제와 분산

Kafka에서는 고가용성을 위하여 각 partition을 복제하여 클러스터에 분산시킬 수 있다. 아래의 그림은 해당 topic의 replication factor를 3으로 설정한 상태의 클러스터이다. 각 partition들은 3개의 replica를 가지며 각 replica는 R0, R1, R2로 표시되어 있다.

파티션 복제

Replication factor를 N으로 설정할 경우 N개의 replica는 1개의 leader와 N-1개의 follower로 구성된다. 위의 그림에서는 각 partition마다 하나의 leader(붉은색)가 존재하며 2개의 follower(푸른색)가 존재한다.

각 partition에 대한 읽기와 쓰기는 모두 leader에서 이루어지며, follower는 단순히 leader를 복제하기만 한다. 만약 leader에 장애가 발생할 경우 follower 중 하나가 새로운 leader가 된다. Kafka의 복제 모델인 ISR 모델은 f+1개의 replica를 가진 topic이 f개의 장애까지 버틸 수 있도록 한다.

Leader에서만 읽기와 쓰기를 수행한다고 하면 부하 분산이 되지 않는다고 생각할 수 있는데, 각 partition의 leader가 클러스터 내의 broker들에 균등하게 분배되도록 알고리즘이 설계되어 있기 때문에 부하는 자연스럽게 분산이 된다. 위의 그림처럼 3개의 broker에 P0, P1, P2의 leader가 균등하게 분배되므로 부하 또한 자연스럽게 분산되게 된다.

출처: http://epicdevs.com/17 [Epic Developer]


Consumers

메세징 모델은 크게 큐 모델과 발행-구독 모델로 나뉜다.

큐 모델은 큐의 메세지를 consumer pool에 있는 consumer에 할당 하는 방식.

발행-구독 모델은 topic을 구독하는 모든 consumer에게 브로드캐그팅 하는 방식이다.

kafa카는 consumer group이라는 개념을 통해 두 모델을 모두 발행-구독 모델로 일반화 시킨다. 카프카의 파티션은 컨슈머 그룹당 하나의 컨슈머의 접근만을 허용하며 해당 컨슈머를 파티션 오너라고 부른다. (동일한 그룹의 컨슈머 끼리는 동일한 파티션에 접근이 불가능)

한번 정해진 파티션 오너는 boker나 consumer 구성이 변하지 않는한 유지된다.

consumer가 추가/제거 되면 해당 그룹의 파티션이 재분배 되고 broker가 변경되면 전체 consumer group에서 파티션 재분배가 발생한다.

Consumer group을 구성하는 consumer가 파티션 수보다 작으면 하나의 consumer가 여러개의 파티션을 소유 하게 되고, 반대로 consumer의 수가 파티션의 수보다 많으면 여분의 consumer는 메세지를 처리하지 않게 되므로 파티션 과 컨슈머 수의 적절한 설정이 필요하다

  1. 큐 모델로 구성

그림처럼 다수의 컨슈머 그룹을 생성하면 컨슈머 마다 각기 다른 파티션으로 메세지를 받아오기 때문에 컨슈머 그룹은 큐 모델로 동작한다(메세지가 각 파티션에 균등 하게 분대 되어 있다고 가정 할 경우 , 동일 그룹의 컨슈머는 같은 파티션에 접근이 불가능)

  1. 발행 구독 모델로 구성

단일 컨슈머로 이루어진 컨슈머 그룹을 다수 생성하면 동일한 파티션에 다수의 컨슈머가 접근 하여 메세지를 엑세스 하기 때문에 발행 구독 모델을 구성 할 수 있다.

하나의 컨슈머에 의해 독점덕으로 파티션이 엑세스 되기 때문에 동일 파티션 내의 메세지는 파티션에 저장된 순서대로 처리 된다. 만약 특정 키를 지닌 메세지를 발생 시간 순으로 처리 하고자 하면 특정키를 지닌 메세지를 한 파티션에 저장 하도록 분배 알고리즘을 구현함녀 된다.

각 파티션 마다 메세지의 순차 처리는 보장 되지 않기 때문에 특정 토픽의 전체 메시지를 시간순으로 처리 해야 할 경우는 해당 토픽이 하나의 파티션 만을 가지도록 설정해야 한다.