Kafka는 뭐람

문해피와 제육볶음·2023년 9월 9일
0

Kafka

목록 보기
2/4

프로젝트를 진행하면서 카프카를 처음공부하고 적용해보면서 흥미로웠습니다.
배울때는 유튜브에 데브원영님이 완전 상세하고 친절하게 설명해주셔서 어렵지는 않았습니다.
🔗 https://www.youtube.com/channel/UCPdTFQUHzAzFobngtw1sFKg

🦦 개발배경

처음에는 소스어플리케이션과 타겟어플리케이션이 단방향으로 많이 진행이 되었습니다.
하지만 소스어플리케이션과 타겟어플리케이션이 증가하면서 데이터들을 전송하는 라인이 많아지면서 복잡해져
관리가 필요했습니다.

  • 데이터의 전송라인이 많아지면 배포와 장애에 대응이 어렵다
  • 데이터를 전송할때 프로토콜과 포멧의 파편화가 심해졌습니다. → 추후 포멧의 변경시 유지보수에 어려움

위와같은 이유로 카프카가 개발되었습니다.
즉, 소스어플리케이션과 타겟어플리케이션의 커플링을 약하게 하기 위해서 나왔습니다.

🧑‍💻 카프카란

Apache Kafka는 실시간 데이터 스트림 처리를 위한 오픈소스 플랫폼입니다. LinkedIn에서 개발되었습니다.

카프카에는 크게 5가지의 기능을 제공합니다.

  1. Publish-Subscribe 모델: Kafka는 메시지를 주제(topic)별로 분류하고, 생산자(producer)가 메시지를 생성하여 특정 주제에 게시(publish)하면, 그 주제를 구독(subscribe)하는 소비자(consumer)들이 메시지를 받아 처리하는 방식을 지원합니다.

  2. 분산처리: Kafka는 클러스터 형태로 구성될 수 있으며, 여러 서버에 걸쳐 데이터 스트림을 분산 저장하고 처리할 수 있습니다. 이를 통해 높은 확장성과 내구성을 보장합니다.

  3. 실시간 처리: Kafka는 대용량의 실시간 데이터 스트림을 빠르게 처리할 수 있습니다. 따라서 로그 수집, 실시간 분석 등 다양한 사용 사례에서 활용됩니다.

  4. 내결함성(Fault-tolerance): Kafka 클러스터 내에서 각 메세지와 상태들은 복제(replication)되어 저장되므로, 한 노드가 실패해도 데이터 손실 없이 운영이 가능합니다.

  5. 영속성(Persistence): Kafka에서 모든 메세지는 디스크에 영속적으로 저장되며, 사용자 설정에 따라 일정 시간 동안(또는 용량이 충분한 한 계속해서) 보관됩니다.

💡 Kafka의 이러한 특징들 때문에 많은 기업들이 실시간 로그처리나 스트리밍 데이터 처리 등의 목적으로 Kafka를 활용하고 있습니다.

카프카에는 각종 데이터를 닮는 토픽이라는 개념이 있는데 쉽게 이야기해서 큐라고 생각하면 좋습니다.

  • 프로듀서 : 카프카의 토픽에 데이터를 넣는역할
  • 컨슈머 : 카프카의 토픽에서 데이터를 가져가는 역할

이 둘은 라이브러리로 되어있어 어플리케이션에서 구현 가능


🧑‍💻 토픽과 파티션

카프카에서 토픽은 메시지(이벤트)를 구분하는 단위입니다.
하나의 토픽은 여러 개의 파티션으로 구성될 수 있으며, 각 파티션은 메시지를 저장하는 물리적인 파일입니다. 카프카 프로듀서는 토픽에 메시지를 발행하고, 카프카 소비자는 토픽에서 메시지를 소비합니다.

파티션이 하나일때

하나의 토픽은 여러개의 파티션으로 구성이 가능합니다.
첫번째 파티션은 0번부터 시작하고 하나의 파티션은 큐와같이 내부의 데이터가 파티션의 끝부터 쌓이게 됩니다.

이때 컨슈머는 메세지가 오래된 순서대로 가져가게 됩니다.
그리고 카프카는 이벤트 브로커 이기때문에 컨슈머가 메세지를 가져가도 사라지지 않습니다.

남은 메세지는 또 다른 컨슈머가 붙었을때 그 컨슈머가 가져갈 수 있습니다.

  • 이때 새로 붙은 컨슈머는 원래의 컨슈머와 그룹이 달라야하고, auto.offset.reset=earliest여야한다

파티션이 두개일때

  • 키값이 없고, 기본 파티셔너를 사용할 경우 RR(라운드 로빈)방식으로 파티션에 할당되게 됩니다.
  • 키를 있다면, 기본 파티셔너를 사용할 경우 키의 해시값을 구하고, 특정 파티션에 할당 됩니다.

파티션을 생성할때 고려해야하는 사항들

  1. 파티션을 늘리는것은 가능하지만 줄이는것은 불가능합니다.
  2. 파티션당 저장할 수 있는 메시지의 파티션 크기 제한에 의해 결정됩니다.
    파티션 크기 제한을 초과하는 메시지는 해당 파티션에 저장되지 않습니다.
  3. 예상 트래픽을 처리할 수 있을 만큼 충분히 커야합니다.
    만약 파티션 수가 적으면 각 파티션에 너무 많은 메세지가 전송되어 성능이 저하될 수 있습니다.
  4. 파티션당 메세지 보유 기간을 고려해야합니다.

🧑‍💻 프로듀서

  • 프로듀서는 토픽에 해당하는 메세지를 생성하는 역할을 합니다.
  • 특정 토픽에 메세지를 Publish
  • 만약 생성에 실패하더라도 재시도 하는 기능이 있습니다.
public class Producer {
	public static void main(String[] args) throws I0Exception {
	Properties configs = new Properties( );
	configs.put("bootstrap.servers", "localhost: 9092");
	configs.put("key .serializer","org .apache.kafka.common.serialization.StringSerializer");
	configs.put("value.serializer","org. apache.kafka.common.serialization.StringSerializer");
    
	KafkaProducer < String, String > producer = new KafkaProducer < String, String > (configs) ;
    
	ProducerRecord record = new ProducerRecord < String, String > ("click_ log", "Login");
    
	producer. send (record);
    
	producer. close();
    }
}

위의 예제에서는 click_log라는 토픽에 login이라는 메세지만 선언을 해주었지만
사이에 파티션의 키를 설정하여 파티션 지정이 가능하게 됩니다.
이때 따로 설정을 하지 않고 파라미터의 개수에 따라서 자동으로 오버로딩되어 인스턴스를 생성하게 됩니다.

토픽에서 설명했듯이 파티션의 키값을 설정하지 않았다면 round robin방식으로 균일하게 파티션에 저장이되지만 따로 설정을 하였다면 카프카는 키를 특정한 hash값으로 변경시켜 파티션과 1:1 매칭을 시켜줍니다.

하지만 메세지를 보내는 도중 파티션의 수를 늘리게 된다면 매칭을 깨지게 되면서 키와 파티션의 연결은 보장되지 않습니다.(키-파티션의 일관성 보장 X)


🧑‍💻 브로커

  • 카프카가 설치되어있는 서버를 이야기 합니다.
  • 대부분의 클러스터는 3개의 브로커로 구성합니다.

그리고 토픽을 생성할때 partition과 replication의 수를 설정하게 됩니다.

  • partition의 수는 생성될 파티션의 수이고
  • replication의 수는 몇개의 서버에 파티션을 복제할것인지의 수이고 브로커의 수를 넘어갈 수 없습니다.

즉, partition1, replication3이면 세개의 서버에 같은 파티션 하나가 생성되게 됩니다.

그리고 토픽을 만들때 하나의 브로커에 들어가서 만들게 되는데 그곳의 partition이 leader partition이 되고, 나머지 두개의 파티션은 follower partition이라고 합니다.

  • 리더와 팔로우 파티션을 합쳐서 ISR(In Sync Replica)라고 볼수 있습니다.

replication을 사용하는이유

  • partition의 고가용성을 위해 사용합니다.
  • 1개만 만들게 된다 어떠한 장애로인해 브로커가 사용이 안된다면 해당 파티션은 복구할수 없습니다.
  • 2개를 만들게 되었다면 하나의 브로커가 터지더라고 팔로우 파티션이 리더를 계승합니다.

하지만 무작정많으면 좋지않습니다
⇒ 1 partition, 6 replication은 많아서 좋지만 브로커의 리소스 사용량도 늘어나게 됩니다.

파티션의 ack의 의미

  • 리더 : 프로듀서가 토픽의 파티션에 데이터를 전달할때 전달받는 주체
    • 프로듀서에는 ack라는 상세옵션 존재
    • ack를 통해 고가용성을 유지, partition의 replication에 관련
    • ack는 0,1,all 중 하나를 골라 사용
    • 0 : 프로듀서는 leader partition에 데이터를 전송하고 응답값 X, 데이터가 잘갔는지, 나머지 파티션에 복제가 되었는지 모른다. 즉, 속도는 빠르지만 데이터의 유실 가능성이 있다
    • 1 : 응답값 O, 하지만 나머지 파티션에 복제 되었는지 알수 없다. 하지만 이것도 다른데이터에 복제가 안되었는데 리더 파티션이 터지게 된다면 데이터의 유실가능성이 있다.
    • all : 모든 응답값 O, 데이터 유실 X, 속도가 현저히 느리다

🧑‍💻 컨슈머

  • 카프카 컨슈머는 기본적으로 토픽의 데이터를 가져옵니다.
  • 즉 파티션에 저장된 데이터를 가져오게 됩니다.
  • 데이터를 가져오는것을 폴링이라고 합니다.

컨슈머의 역할

  • Topic의 partition으로 부터 polling합니다.
  • Partition offset의 위치를 기록합니다.(commit)
    • offset : 파티션에 있는 데이터의 번호를 뜻합니다.
  • Consumer group을 통해 병렬처리 합니다.

컨슈머는 몇개까지 가능한가

  • 만약 두개의 파티션이 존재하고 하나의 컨슈머가 있다면 하나의 컨슈머가 두개의 파티션을 할당하여 데이터를 가져올수 있습니다.

  • 컨슈머가 두개라면 각각의 파티션 하나를 할당하여 데이터를 가져올수 있습니다.

  • 하지만 파티션의 수보다 컨슈머 그룹에 컨슈머가 많다면 즉, 2개의 파티션에 3개의 컨슈머가 있다면 하나의 컨슈머는 동작하지않습니다.

컨슈머는 파티션의 수보다 같거나 적어야 합니다.

컨슈머의 그룹이 다르다면

  • 컨슈머 그룹마다 파티션의 수보다 같거나 적고, 그룹이 다르다면 정상적으로 실행이 됩니다.
  • 각 파티션에 특정 offset을 읽고 있어도 다른 컨슈머 그룹에는 영향이 없습니다.

__consumer_offset토픽에는 컨슈머 그룹별로 토픽별로 offset을 나누어 저장하기 때문입니다.

0개의 댓글