sns

대규모 트래픽을 대응하는 과정(kafka)

로드존슨 2023. 4. 9. 21:35
728x90

대규모 트래픽일시 현 archtecture의 문제점 분석 및 해결

 

대규모 트래픽일시 현 archtecture의 문제점 분석 및 해결

현재 개발한 서비스 sns 어플리케이션 경우에는 기능만 집중하여 개발하였다. 대규모트랙픽이랑 코드의 최적화 되어있지 않고 기능구현중점으로 서비스 개발하였다. 그렇다면 대규모 트래픽일

hohojavis.tistory.com

AlarmList API를 호출해야만 갱신되는 알람 목록 

문제 상황

-알람페이지는 매번 새로고침을 해야 갱신된다. 이를 비동기처리로 새로고침없이 자동으로 할수 있는 방법이 뭐있는지 확인해보고 kafka를 적용하기로 했다. 

문제의 페이지는 이전에 콘텐츠를 업데이트하기 위해 수동 새로 고침이 필요했습니다. 이는 Kafka를 사용하여 비동기 처리를 구현하여 개선되었습니다. 즉, 수동 새로 고침에 의존하는 대신 새 데이터를 사용할 수 있게 되면 페이지가 실시간으로 콘텐츠를 자동으로 업데이트합니다. Kafka는 비동기 처리를 처리하는 메시지 브로커로 사용되어 데이터를 효율적이고 안정적으로 처리할 수 있습니다. 결과적으로 사용자는 더 이상 페이지를 수동으로 새로 고칠 필요가 없으므로 사용자 경험이 향상되고 중요한 업데이트를 놓칠 가능성이 줄어듭니다.

 

 

Kafka란?

Kafka는 데이터를 비동기처리 , kalka 는 메세징 큐이며 Pub-Sub 모델의 메시지 큐입니다. 분산환경에 특화되어있는 특징을 가지고 있습니다. 이 글의 Kafka의 주요개념 에서 Kafka의 개념들과 이들의 특징을 더 자세히 알아보도록 하겠습니다.

 

 

 

kafka

Producer

Producer는 kafka에 이벤트를 게시(post)하는 클라이언트 어플리케이션을 의미합니다.

 

-producer는 메시지(=event) 를 생성한다.

-key 라는 값을 설정해줘야한다.key는 값은 그 메시지가 어떻게 partition이 될지 정하는 값이다.

-producer가 메시지를 생성할 때 나는 " 나는 이 Topic 에다 생성을 할래" 그 뜻은 topic을 중심으로 메세지가 생성이 되고 그런구조다. 

poducer에서 생성된 메세지는 partition에 저장이 된다. 

 

Topic

이벤트가 쓰이는 곳입니다. Producer는 이 Topic에 이벤트를 게시합니다. 그리고 Consumer는 Topic으로 부터 이벤트를 가져와 처리합니다. Topic은 파일시스템의 폴더와 유사하며, 이벤트는 폴더안의 파일과 유사합니다.

Topic에 저장된 이벤트는 필요한 만큼 다시 읽을 수 있습니다.

Broker 

broker 에서 파일로 작성한다.

 -partition  producer에서 생성된 토픽은 일련의 순서 대기열로 세분화된다. 

-Topic는 여러 Broker에 분산되어 저장되며, 이렇게 분산된 Topic을 Partition이라고 합니다

-어떤 이벤트가 Partition에 저장될지는 이벤트의 key(키)에 의해 정해지며, 같은 키를 가지는 이벤트는 항상 같은 Partition에 저장됩니다

 

Consumer

-Consumer는 이러한 Topic을 구독하고 이로부터 얻어낸 이벤트를 처리하는 클라이언트 어플리케이션 입니다.

-consumer 는 이 파일을 읽어온다.하나의 topic에 여러개의 consumer가 각각 다른 목적으로 존대한다. 일단 topic에 입력된 데이터는 여러 consumer 가 서로 다른 처리를 하기 위해 여러번 가져올 수 있고 이것이 바로 Pub / Sub라고 불리는 데이터 분포모델이다. 

 

*key값을 설정하는게 중요하다. key값의 업데이트가 많으면 여러개 partition이 부여되는데 이는 하나의 key값으로 인식되며 이는 하나의 consumer로 파일을 읽는다

 

Kafka의 주요 개념

Producer와 Consumer의 분리

 

Kafka의 Producer와 Consumer는 완전 별개로 동작을 합니다. Producer는 Broker의 Topic에 메시지를 게시하기만 하면되며, Consumer는 Broker의 특정 Topic에서 메시지를 가져와 처리를 하기만 합니다.

이 덕분에 높은 Kafka는 높은 확장성을 제공합니다. 즉, Producer 또는 Consumer를 필요에 의해 스케일 인 아웃하기에 용이한 구조입니다. 만약, Producer와 Consumer가 직접적으로 연관을 가지고 있다면, 확장 또는 축소시 이들을 모두 연결 또는 해제를 하기가 매우 번거럽고 어려웠을 것입니다.

 

Push 와 Pull 모델

kafka의 Consumer Pull 모델을 기반으로 메시지 처리를 진행합니다. 즉, Broker가 Consumer에게 메시지를 전달하는 것이 아닌, Consumer가 필요할때, Broker로 부터 메시지를 가져와 처리하는 형태

 

 

다양한 소비자의 처리 형태와 속도를 고려하지 않아도 된다.

-반대의 경우인 Push모델에서는, Broker가 데이터 전송 속도를 제어하기 때문에, 다양한 메시지 스트림의 소비자를 다루기가 어렵지만, Pull 모델은 Consumer가 처리 가능한 때에 메시지를 가져와 처리하기 때문에 다양한 소비자를 다루기가 쉽습니다.

 

불필요한 지연없이 일괄처리를 통해 성능향상 도모.

-Push 모델의 경우에는, 요청을 즉시 보내거나, 더 많은 메시지를 한번에 처리하도록 하기 위해 Buffering을 할 수 있습니다. 하지만 이런 경우, Consumer가 현재 메시지를 처리할 수 있음에도, 대기를 해야합니다. 그렇다고 전송 지연시간을 최소로 변경하면, 한번에 하나의 메시지만을 보내도록 하는것과 같으므로 매우 비효율적입니다. pull 모델의 경우, 마지막으로 처리된 메시지 이후의 메시지를 Consumer가 처리가능한 때에 모두 가져오기 때문에, 이 문제를 해결합니다. 따라서 불필요한 지연 없이 최적의 일괄처리를 할 수 있습니다.

 

Consumer Group

Consumer Group은 하나의 Topic을 구독하는 여러 Consumer들의 모음

Topic을 구독하는 Consumer들을 Group화 하는 이유는, 가용성 때문입니다. 하나의 Topic을 처리하는 Consumer가 1개인 것보다 여러개라면 당연히 가용성은 증가할 것이다.

 

KEY값을 잘 설정해야 한다.!!

KEY값을 설정할때 유효식별키로 지정이 되는데 KEY값을 가지고 PARTITION이 나눠지게 된다. 같은 키를 가지고 있으면같은 파티션에 적재된다. 그렇게 되면 하나의  CONSUMER 가 하나의 PARTITION을 처리하게 되면서 절대적으로 메시지 순서가 바뀔일이 없다. 

 

 CONSUMER에서 메세지를 다 읽고나면 처리했다는걸 표시하기 위해 ACK를 날린다.ACK를 날리는 방법은 단위별날리는 배치성, 개별, 코드상 ACK의 시점을 결정하는 등.. 으로 할 수가 있다. 

 

https://galid1.tistory.com/793

 

Kafka - Kafka란? (Kafka의 구조와, 주요개념)

Apache Kafka Apache Kafka의 각 구성요소와 구성요소들의 주요 개념을 알아보도록 하겠습니다. 어떤 기술의 특성을 이해하고, 구성요소를 이해하는것은, 해당 기술을 이용해 특정 기능을 구현할때 매

galid1.tistory.com

 

Kafka 적용하기 

 

build.gradle 추가

	implementation 'org.springframework.kafka:spring-kafka'

 

yaml 파일 수정

spring:  
  kafka:
    bootstrap-servers:
      - 192.168.0.4:9092
    consumer:
      # consumer bootstrap servers가 따로 존재하면 설정
      # bootstrap-servers: 192.168.0.4:9092

      # 식별 가능한 Consumer Group Id
      group-id: testgroup
      # Kafka 서버에 초기 offset이 없거나, 서버에 현재 offset이 더 이상 존재하지 않을 경우 수행할 작업을 설정
      # latest: 가장 최근에 생산된 메시지로 offeset reset
      # earliest: 가장 오래된 메시지로 offeset reset
      # none: offset 정보가 없으면 Exception 발생
      auto-offset-reset: earliest
      # 데이터를 받아올 때, key/value를 역직렬화
      # JSON 데이터를 받아올 것이라면 JsonDeserializer
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
    producer:
      # producer bootstrap servers가 따로 존재하면 설정
      # bootstrap-servers: 3.34.97.97:9092

      # 데이터를 보낼 때, key/value를 직렬화
      # JSON 데이터를 보낼 것이라면 JsonDeserializer
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
1) spring.kafka.consumer
bootstrap-servers
kafka 클러스터에 대한 초기 연결에 사용할 IP 목록, 쉼표로 구분
group-id
Consumer는 Consumer Group이 존재하고, 유일하게 식별할 수 있는 Consumer Group ID
auto-offset-reset
Kafka 서버에 초기 offset이 없거나, 서버에 현재 offset이 더 이상 없는 경우 수행할 작업을 작성
Consumer Group의 Consumer는 메시지를 소비할 때 Topic 내에 Partition에서 다음에 소비할 offset이 어디인지 공유하고 있다. 그런데 오류 등으로 인해 offset 정보가 없어졌을 때 어떻게 offset을 reset 할 것인지를 명시
latest : 가장 최근에 생산된 메시지로 offset reset
earliest : 가장 오래된 메시지로 offset reset
none : offset 정보가 없으면 Exception 발생
key-deserializer / value-deserializer
Kafka에서 데이터를 받아올 때 key/value를 역직렬화 한다.
key, value는 KafkaTemplate의 key, value를 의미한다.
메시지가 문자열 데이터이면 StringDeserializer를 사용하고, JSON 데이터면 JsonDeserializer도 가능하다.
2) spring.kafka.producer
bootstrap-servers
consumer.bootstrap-server와 동일하지만 producer 전용으로 오버라이딩 하려면 작성한다.
key-serializer / value-serializer
Kafka에 데이터를 보낼때 key/value를 직렬화 한다.

producer 생성하기

consumer생성하기

 

기존의 sse의 코드를 수정한다.

 

https://velog.io/@taehodot/SpringBoot-%EC%B9%B4%ED%94%84%EC%B9%B4%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%97%B0%EB%8F%99

 

[SpringBoot] 카프카와 스프링부트 연동

아파치 카프가 공식 홈페이지 에서 다운로드 (https://kafka.apache.org/downloads)나는 리눅스에서 wget으로 다운로드, 설치는 압축을 풀면 끝wget https://downloads.apache.org/kafka/3.2.0/

velog.io

 

728x90