본문 바로가기

빅데이터/Kafka

Reactive를 품은 스프링 카프카 시청 정리 자료

아래 영상자료를 보고 정리한 글입니다.

 

1. 카프카 그리고 스프링

카프카는 현대의 메시지드리븐아키텍처의 핵심 플랫폼. 다양한 종류로 사용 가능

스프링에서 카프카를 사용하는 방법은 아주 쉬워졌음

마치 webMVC에서 request패턴 사용한것처럼 사용. 하지만 동시성문제는 어떻게 해결할까? 파티션을 나눠서 병렬처리는 가능.

스트리밍 플랫폼의 본질

리액티브프로그래밍의 본질은 어떤 대상을 Async하게 다루는 것. Async하게 다루는것을 스트림으로 처리하겠다. Flux<T>로 비동기 처리하는 것이 핵심.

리액터 카프카 디펜던시 추가

프로듀서를 생성한 코드

1건씩 들어오는 mono 또는 flux를 통해 전달하는 것도 가능

컨슈머 코드

ReceiverRecord를 통해 받은 데이터를 처리하는 것만 생성하면됨
스프링2.3.3부터는 리액터를 사용할 수 있음

스프링카프카에서 리액트 사용 방법

토픽과 어떤 메시지를 보낼것이다 라는 것을 보여줌
ReceiverRecord를 Flux로 받을 수 있음

2. 적용 프로젝트

NHN의 모니터링 적재, 이벤트 적재 및 알람

관찰대상 서버가 다수가 되면서 모든 데이터를 처리하는 것이 중요

 

NHN의 VM개수

최악의 경우를 고민해야함..

- 1,000대이상의 서버에서 동시다발적으로 이벤트 감지된다면?

- 이벤트가 수차례 반복된다면?

 

그럼에도 부룩하고

- 통지에 지연이 발생하면안되고

- 각 이벤트는 상호 독립성이 보장되어야함

3. 기본 기능 구현

이벤트가 발생하면 디텍터는 메시지로 만들고 스트림으로 발행, 처리기는 이벤트 정보를 DB에 기록하고 담당자에게 통지를 발송하는 프로세스를 만드는게 주요 목표.

 

발표자가 생각한 컨슈머코드

컨슘 이후 데이터처리

4. 메시지 중복 제거

최초 설계시는 매우 간단해서 어려움이 없음

디텍터 = 애플리케이션
HA를 위해 여러개 디텍터를 놔둘 수 있음
디텍터가 여러번 오면 이벤트 프로세스는 다음 들어온 데이터는 무시하자.

이를 해결하기 위해 리액트 sampleFirst()메서드를 사용함

추가로 groupBy연산자를 사용하여서 FLUX여러 갈래를 만들어줌

비슷한 이벤트를 갈라줌

해결한 코드 

5. 데이터 모아서 처리

메시지 양이 늘어난다면?

사용자에게 여러건 발송하면 안됨. 

특정 기준시간동안 모아서 통지하고 싶을때, FLUX의 buffer(), bufferTimeout() 메서드 사용

해결한 코드

6. 정해진만큼 처리

지금까지 프로세스 도표

의존성 있는 시스템(SMS발송같은거)을 위해 이벤트 프로세서가 처리량을 제어해야함.

Java9의 flow사용

하나의 아이템을 처리하고 나면 처리를 하도록..하지만 스레드를 1개만 있는거랑 별다를게 없음 하지만 request(10)을 사용해서 워커가 10개 사용하는 것 처럼 가능.

7. 시간을 달리는 메시지

컨슈머는 데이터를 처리할때마다 오프셋 커밋을 딱 찍어주는데...

그런데 비동기로 데이터를 처리하기 때문에 커밋이 순서가 완전 꼬일 수 있다. 

커밋 순서가 꼬여버림

그래서 NHN에서는 offset이 증가할때만 커밋하도록 하자는게 해결방안이라고 생각함.

 

이것을 해결하기 위해 레코드를 처리완료할 때마다 커밋을 하는것이 아니라 오프셋 관리 Flux를 만듦.

가장 마지막 커밋한 오프셋과 다음 커밋 오프셋의 차이를 확인하여 커밋을 시도함. 이를 통해 커밋하는 오프셋이 무조건 커지는 것을 보장함.

8. 결론

깊이 알고 제대로 쓰려는 노력이 중요함. 

 


데브원영의 의견

카프카 컨슈머와 프로듀서를 복합적으로 사용하면서 최대의 성능을 이끌어내기 위해 reactive 프로그래밍을 활용했다는점이 인상적이였다. 그리고 스프링 카프카 2.3.3부터는 관련 코드가 적용되었음을 확인할 수 있었다.

마지막 챕터에서 아쉬운점은 커밋시점인데 만약 [2,5,4,3]순서대로 데이터 처리가 되서 2와 5까지 데이터를 처리하고 커밋을 한 상태에서 애플리케이션이 장애가 나면 3과 4번 오프셋은 유실이 된다는 점이 있다. 이런 유실되는 상황을 어떻게 처리할 것인지에 대한 내용이 없다는 점이다. 과연 유실이 일어나는 상황을 어떻게 대처하는 코드를 사용했을지 궁금하다.