카프카(Kafka) 설치 및 클러스터 구성
DatalakeKafka를 설치하고 간단하게 클러스터 환경을 구성하여 Producer 및 Consumer 테스트를 해보자. 먼저 가상머신을 이용해 다음 그림과 같이 클러스터 환경을 구성하여 테스트를 진행할 것이다. !img 이 글에서는 3대의 서버를 생성하였지만 1대의 서버로 포트를 다르게 하여 구성할 수도 있다. 또한 Kafka와 Zookeeper서버를 동일한 장비에 구축하였지만 실무에서는 별도로 구축하는 것이 좋다. Kafka 다운로드 및 설치 다운로드(각 버전에 대해서는 https://kafka.apache.org/downloads를 참고하자.) 압축해제 및 경로이동 Kafka의 동작은 Zookeeper에 의해 관리가 되기 때문에 Zookeeper 없이는 Kafka를 구동할 수 없다. 이 때문에 Kafka를 다운로드 하면 Zookeeper도 함께 들어있다. 물론 별도로 최신버전의 Zookeeper를 다운받아 사용해도 되지만, Kafka에 들어있는 Zookeeper는 Kafka버전과 잘 동작하는 검증된 버전이므로 패키지 안에 있는 Zookeeper의 사용을 권장한다. Zookeeper 설정 각 인스턴스에 설치된 Kafka의 config/zookeeper.properties 파일은 하나의 Zookeeper를 실행하는데 쓰이는 설정 파일이다. 이 말은 zookeeper1.properties, zookeeper2.properties, zookeeper3.properties 이런식으로 여러개의 설정파일을 만들고 하나의 장비에서 다중으로 실행할 수 있다는 의미이다. 설정파일을 다음과 같이 3대의 서버에 동일하게 추가하자. 새로 추가한 설정값은 클러스터를 구성하는데 필요한 설정 값들안데 여기서 주의할 점은 모든 Zookeeper 서버들은 동일한 변수 값을 가지고 있어야 한다. initLimit 팔로워가 리더와 초기에 연결하는 시간에 대한 타임아웃 syncLimit 팔로워가 리더와 동기화 하는데에 대한 타임아웃. 즉 이 틱 시간안에 팔로워가 리더와 동기화가 되지 않는다면 제거 된다. 이 두값은 dafault 기본값이 없기 때문에 반드시 설정해야 하는 값이다. 그리고 server.1,2,3의 숫자는 인스턴스 ID이다. ID는 dataDir=/tmp/zookeeper 폴더에 myid파일에 명시가 되어야 한다. /tmp/zookeeper 디렉토리가 없다면 생성하고 myid 파일을 생성하여 각각 서버의 고유 ID값을 부여해야 한다. (그 외 자세한 설정정보를 알고 싶다면 주키퍼 가이드문서를 참고하자.) 1 서버 (192.168.137.101) 2 서버 (192.168.137.102) 3 서버 (192.168.137.103) 이제 Zookeeper를 구동하기 위한 설정은 끝~ Kafka 설정 Kafka의 config/server.properties 파일은 하나의 Kafka를 실행하는데 쓰이는 설정 파일이다. Zookeeper와 마찬가지로 여러개의 설정파일을 만들고 다중 실행을 할 수 있다. 설정파일 config/server.properties에 3대 서버 각 환경에 맞는 정보를 입력해 준다. 1 서버 (192.168.137.101) 2 서버 (192.168.137.102) 3 서버 (192.168.137.103) 별도 파일(/tmp/zookeeper/myid)에 인스턴스 ID를 명시해야 하는 Zookeeper와는 달리 Kafka는 설정파일안에 broker.id라는 항목이 있다. 그리고 zookeeper.connet라는 항목에는 Zookeeper인스턴스들의 정보를 입력해준다. Kafka를 구동하기 위한 설정은 끝났다. 클러스터 구성을 위한 인스턴스들의 정보를 입력해 주는것이 거의 대부분의 설정이다. 그외 설정 파일에 대한 상세한 내용은 공식 홈페이지의 Broker Configs를 참고하길 바란다. default설정값을 확인하고 변경하고자 하는 값들은 설정파일에 명시를 해주면 된다. Zookeeper 및 Kafka 서버 구동 Kafka를 구동하기 위해 먼저 Zookeeper를 구동 한다음 이후 Kafka를 구동해야 한다. 3대의 서버에 Zookeeper와 Kafka가 정상적으로 구동이 되었다면 다음과 같이 starting 메시지를 확인할 수 있을 것이다. *starting (kafka.server.KafkaServer) 이제 기본적인 클러스터 환경을 구성하고 서버를 구동시켰다. Kafka에서는 bin폴더 아래 제공되는 스크립트 파일을 이용해 Topic을 관리하고 Producer,Consumer를 테스트 해볼수 있다. 기본적인 몇가지 스크립트 명령을 이용해 Topic을 생성해 보고 Producer 메시지를 저장하고 Consumer 메시지를 읽어오는것을 확인해 보도록 하자. Topic 관리 1. Topic생성 GameLog, GameLog2, GameLog3 세개의 Topic을 생성해보자.(replication-factor:3, partitions : 1) 출력 Created topic "GameLog" 2. Topic 리스트 확인 출력 GameLog GameLog2 GameLog3 3. Topic 삭제 출력 Topic GameLog3 is marked for deletion 4. Topic 상세 정보 확인 출력 PartitionCount:1 ReplicationFactor:3.. 토픽을 생성했으면 해당 토픽에 메시지를 생산하고 소비하는것을 직접 확인해보자. 메시지 생산 및 소비 1.Producer 메시지 생산하기 !img 2.Consumer 메시지 소비하기 !img from-beginning 옵션은 해당 topic의 맨 처음 메시지부터 소비하겠다는 의미이다. 그림에서 보는 것과 같이 Producer에서 메시지를 입력하면 Consumer에서 해당 메시지를 읽어오는 것을 확인 할 수 있다. 지금까지 Kafka 클러스터를 직접 구축하여 메시지 생산하고 소비하는 것을 간단하게 해보았다.
2019년 02월 14일8분카프카(Kafka)의 이해
Datalake대용량 게임로그 수집을 위해 Elastic Stack을 도입하게 되었는데, 중간에 버퍼역할(메시지큐)을 하는 Kafka에 대서 알아보려고 한다. !img 메시지큐? 메시지 지향 미들웨어(Message Oriented Middleware: MOM)은 비동기 메시지를 사용하는 다른 응용프로그램 사이의 데이터 송수신을 의미하는데 MOM을 구현한 시스템을 메시지큐(Message Queue:MQ)라 한다. 카프카란? 분산형 스트리밍 플랫폼(A distributed streaming platform)이다. LinkedIn에서 여러 구직 및 채용 정보들을 한곳에서 처리(발행/구독)할 수 있는 플래폼으로 개발이 시작 되었다고 한다. (발행/구독: pub-sub은 메시지를 특정 수신자에게 직접적으로 보내주는 시스템이 아니고, 메시지를 받기를 원하는 사람이 해당 토픽(topic)을 구독함으로써 메시지를 읽어 올 수 있다.) 카프카의 특징 대용량 실시간 로그처리에 특화되어 설계된 메시징 시스템으로 TPS가 매우 우수하고, 메시지를 메모리에 저장하는 기존 메시징 시스템과는 달리 파일에 저장을 하는데 그로 인해 카프카를 재시작해도 메시지 유실 우려가 감소된다. 기본 메시징 시스템(rabbitMQ, ActiveMQ)에서는 브로커(Broker)가 컨슈머(consumer)에게 메시지를 push해 주는 방식인데, 카프카는 컨슈머(Consumer)가 브로커(Broker)로부터 메시지를 직접 가져가는 PULL 방식으로 동작하기 때문에 컨슈머는 자신의 처리 능력만큼의 메시지만 가져와 최적의 성능을 낼 수 있다. 대용량처리에 특화 되었다는 것은 아마도 이러한 구조로 설계가 되어 가능하게 된게 아닌가 싶다. !img 여기서 한가지 의문이 든다. 일반적으로 파일보다 메모리가 성능이 우수한데 왜 카프카가 성능이 좋은 것일까? 그 이유는 카프카의 파일 시스템을 활용한 고성능 디자인에 있다. 일반적으로 하드디스크는 메모리보다 수백배 느리지만 하드디스크의 순차적 읽기에 대한 성능은 메모리보다 크게 떨어지지 않는다고 한다. 컨슈머(Consumer)와 브로커(Broker)에 대해서는 카프카 구성요소에 대한 설명에서 좀 더 자세히 알아보자. 카프카의 구성요소 카프카에는 다음과 같이 여러 구성요소가 있다. topic, partition, offset producer, consumer, consumer group broker, zookeeper replication 구성요소 하나씩 살펴보도록 하자. Topic, Partition : 카프카에 저장되는 메시지는 topic으로 분류되고, topic은 여러개의 patition으로 나눠질수 있다. partition안에는 message의 상대적 위치를 내타내는 offset이 있는데 이 offet정보를 이용해 이전에 가져간 메시지의 위치 정보를 알 수 있고 동시에 들어오는 많은 데이터를 여러개의 파티션에 나누어 저장하기 때문에 병렬로 빠르게 처리할 수 있다. !img Producer, Consumer : 말대로 Producer는 생산(메시지를 Write)하는 주체, Consumer는 소비(메시지를 Read)하는 주체이다. Producer와 Consumer간에는 상호 존재 여부를 알지 못한채 자신에게 주어진 역할만 처리 하게 된다. (위 그림에서 보면 Writes가 Producer) Consumer Group : Producer에서 생산(Write)한 메시지는 여러개의 파티션에 저장을 하는데, 그렇다면 소비하는(Consumer)하는 쪽에서도 여러 소비자가 메시지를 읽어가는것이 훨씬 효율적일 것이다. 하나의 목표를 위해 소비를 하는 그룹, 즉 하나의 토픽을 읽어가기 위한 Counsumer들을 Consumer Group라고 한다. 하지만 이 Consumer Group에는 한가지 룰이 있다. Topic의 파티션은 그 Consumer Group과 1:n 매칭. 즉, 자신이 읽고 있는 파티션에는 같은 그룹내 다른 컨슈머가 읽을 수 없다. (파티션에는 동일한 Consumer Group을 위한 하나의 구멍이 있고, Consumer는 그 구멍에 빨대를 꽂아 읽어간다고 생각하면 쉽게 상상이 될지도….^^;) !img 위 그림과 같이 하나의 토픽에 4개의 파티션이 있고 컨슈머그룹내 3개의 컨슈머가 있다면 컨슈머1,2,3은 각 파티션 1,2,3에 순차적으로 배치가 될 것이고, offset정보를 이용해 순차적으로 데이터를 읽게 된다. 문제는 파티션4인데 컨슈머 갯수가 파티션 갯수보다 작다면 컨슈머 1,2,3중 하나가 파티션4에 접근하여 데이터를 읽게 된다. 만약 파티션 갯수와 컨슈머 갯수가 동일하개 4개씩이라면 각 컨슈머들은 하나의 파티션에서 데이터를 읽게 될것 이고, 파티션갯수가 4개고 컨슈머 갯수가 5개이면 컨슈머5는 그냥 아무일도 안하게 된다.(일반적으로 파티션 갯수와 컨슈머 갯수는 동일하게 구성하는 것을 추천한다고 함.) !img 컨슈머그룹이 존재하는 또 다른 이유가 있다. 물론 이러한 구조로 데이터를 병렬로 읽게 되어 빠른처리가 가능하다는 부분도 있겠지만, 특정 컨슈머에 문제가 생겼을 경우 다른 그룹내 컨슈머가 대신 읽을 수 있게 리벨런싱이 되어 장애 상황에서도 문제 없이 대처할 수 있게 된다. Broker, Zookeeper : broker는 카프카 서버를 칭한다. 동일한 노드내에서 여러개의 broker서버를 띄울 수 있고, Zookeeper는 이러한 분산 메시지큐의 정보를 관리해주는 역할을 한다. 카프카를 띄우기 위해서는 반드시 주키퍼가 실행되어야 한다. Replication : 카프카에서는 replication 수를 임의로 지정하여 topic를 만들 수 있다. replication-factor에 지정하는데 만약 3으로 하면 replication 수가 3이 된다. Kafka Cluster에 3개의 broker가 있고 3개의 Topic이 있다고 가정해보자. Topic-1은 replication-factor 1, Topic-2은 replication-factor 2, Topic-3은 replication-factor 3인 경우이다. !img 그렇다면 replication은 왜 필요할까? 단지 데이터의 복제 용도라기 보다는 특정 borker에 문제가 생겼을 경우 해당 broker의 역할을 다른 broker에서 즉각적으로 대신 수행 할 수 있게 하기 위한 용도 일 것이다. Replication - leader & follower replication을 좀더 자세히 들여다보면, 복제요소중 대표인 leader, 그외 요소인 follower로 나누어진다. topic으로 통하는 모든 데이터의 read/write는 오직 leader에서 이루어지고 follower는 leader와 sync를 유지함으로써 leader에 문제가 생겼을 경우 follower들 중 하나가 leader역할을 하게 되는 것이다. !img 만약 카프카 클러스터내 broker 2에서 장애가 발생되었다면, broker 2에 있던 Topic-2(leader)의 역할을 대신 수행하기 위해 아래 그림과 같이 broker 1에 있는 Topic(follower)가 leader역할을 하게 될 것이다. !img 복제된 데이터가 follower들에게 있으니, 메시지의 유실이 없다는 장점이 있지만, 복제를 하기 위한 시간과 네트워크 비용이 들기 때문에 데이터의 중요도에 따라 ack옵션으로 성능과 데이터의 중요도에 따라 다음과 같이 세부설정이 가능하다. ack (default:1) > - 0 : 프로듀서는 서버로부터 어떠한 ack도 기다리지 않음. 유실율 높으나 높은 처리량 > - 1 : 리더는 데이터를 기록, 모든 팔로워는 확인하지 않음 > - -1(또는 all) : 모든 ISR 확인. 무손실 ack값을 설정하여 데이터의 무손실에 더 중요성을 둘 것인지 또는 유실을 어느정도 감수 하더라고 속도에 중요성을 둘 것인지를 셋팅할 수 있다. 지금까지 설명한 모든 구성요소를 그림으로 표현하면 아래 그림과 같다. !img Producer에서는 메시지를 입력하고, Consumer에서 메시지를 읽어갈때 Zookeeper에서 broker 및 offset정보를 관리하기 때문에 분산처리가 가능하게 된다. 카프카를 운영하기에 앞서 기본적인 구성요소나 매커니즘에 대해 충분히 이해를 하면 운영 하는데 많은 도움이 될 것이다. 참고자료 공식홈 문서 : (http://kafka.apache.org/documentation/)
2019년 01월 18일12분