Blog

[Spring][258] 웹 서비스 카프카 적용 주간 정리

Category
Author
Tags
PinOnMain
1 more property

이번주 동안 카프카를 진행한 내용

초기

Kafka를 시도하는 이유

→ kafka를 사용하면 데이터 베이스나 애플리케이션에 을 걸지 않고 전송 속도를 제어해서 동시성 문제가 발생하지 않는 속도로 순차적으로 전달한다면 락보다 속도가 빠를것입니다.
→ 서비스가 계속 성장하고 더 많은 트래픽을 처리해야 할 경우, Kafka는 쉽게 확장할 수 있는 구조를 가지고 있어 미래의 성장에 대비할 수 있습니다.
→ Kafka는 분산 시스템으로 설계되어 있어 노드 하나가 실패하더라도 서비스의 가용성을 유지할 수 있습니다.
즉 저희 서비스의 확장성과 안정성, 서버 과부하 방지, 동시성 문제를 성능 저하하는 락없이 해결하기 위해 카프카가 필요합니다.
일반서비스와 대용량 서비스를 카프카를 통해 분리해서 처리하는 측면에서도 필요합니다.

Kafka 구현 방식에 대한 고찰

1.
데이터베이스 저장 처리 결과를 데이터베이스에 저장하고, 컨트롤러에서 해당 데이터를 조회하여 사용하는 방법입니다. 하지만 이 방식은 실시간 대규모 트래픽 처리를 필요하는 저희 프로젝트에 적합하지 않다고 판단됩니다.
2.
WebSocket을 이용 프론트 서버와 벡엔드 서버 간에 실시간 연결을 연결하는 방법입니다. 실시간으로 연결을 유지해야 하기에 특정 기간 동안만 대규모 트래픽을 처리하는 저희 프로젝트에는 적합하지 않는 걸로 보입니다.
3.
비동기적 처리 컨슈머에서 요청에 대한 결과가 온다면 비동기적으로 해당 컨트롤러에서 받아서 사용하는 방식입니다. 비동기적으로 사용자에게 신속한 응답을 줄 수 있다는 점과 DB에 따로 저장할 필요가 없다는 점에서 매리트가 있다고 보여집니다. 현재로선 이 방법이 적합해 보입니다.
4.
Polling 방식 사용 클라이언트가 주기적으로 프론트 서버에 결과가 준비되었는지 확인하는 요청을 보내는 방식입니다. 결과가 준비되었으면 서버는 결과를 클라이언트에게 반환하고, 그렇지 않으면 클라이언트는 일정 시간 후에 다시 요청을 보냅니다. 저희는 실시간 적인 처리를 원하며 특정 시간 이외에는 주기적으로 확인할 필요 값 없습니다. 현재 저희 프로젝트에는 적합하지 않다고 여겨집니다.
5.
임시 저장소 사용 결과 데이터를 캐시나 임시 DB에 저장하고, 클라이언트에게 결과를 조회할 수 있는 고유한 키나 ID를 반환합니다. 클라이언트는 이 키를 사용해 프론트 서버에 결과를 요청하며, 프론트 서버는 임시 저장소에서 결과를 조회해 반환합니다. 이 방법은 저장소에 부하를 줄 수 있지만, 결과 데이터가 크지 않고 빠르게 만료될 수 있다면 효과적일 수 있습니다. 하지만 저장한 다는 점 자체가 성능 저하를 야기하기에 저희 프로젝트에는 맞지 않는 것 같습니다.
6.
상태 저장소 사용 Kafka Streams나 Apache Flink와 같은 스트림 처리 라이브러리를 사용하여 상태 저장소에 처리 결과를 저장하고, 클라이언트에게 상태를 조회할 수 있는 엔드포인트를 제공할 수 있습니다. -> 이것 역시 처리 결과를 저장한다는 측면이 걸립니다.
비동기적 처리가 저희 프로젝트에 적합하다고 판단 했습니다.

중기

카프카 구현 하며 고찰

하나의 파티션 ( 다른 그룹 ) 한계 동시성 문제를 구조적으로 해결할 수 있지만 카프카 서버 자체에 부하를 줄 수 있습니다. 카프카 서비스의 장점 중 하나인 파티션을 병렬적으로 처리하는 방법을 사용하지 못합니다 또한 동일한 Kafka 토픽의 파티션여러 컨슈머가 존재하고, 이들이 동일한 데이터베이스에 접근하여 비즈니스 로직을 처리하는 경우 동시성 문제가 발생할 수 있습니다. 즉 단 하나의 파티션과 단 하나의 컨슈머가 DB의 비즈니스 로직을 처리하는 경우를 제외하고는 동시성 문제가 발생 할 수 있습니다.
카프카를 모든 서비스에 적용해야 될까? Kafka는 뛰어난 메시지 처리 능력과 확장성을 제공하지만, 이를 모든 서비스에 무조건 적용하는 것은 비효율적일 수 있다는 생각이 들었습니다. 서비스의 특성과 요구사항을 고려하여, Kafka 적용이 필요한 서비스그렇지 않은 서비스를 명확히 구분한다면 좀 더 나은 성능을 낼 수 있지 않을까? 라는 생각이 들었습니다. 이를 통해 리소스의 효율적인 활용과 빠른 서비스 응답 시간을 동시에 달성할 수 있지 않을까? 라는 생각이 들었습니다. 대용량 트래픽을 주는 서비스는 카프카를 통해 트래픽 서버에서 처리하고 그 외 서비스는 메인 서버에서 처리하는 것이 바람직하다고 판단했습니다.

후기

다중 파티션 ( 컨슈머 그룹 적용 ) 고찰 Kafka는 메시지를 파티션 단위로 관리하며, 각 파티션은 순서를 가진 로그로 구성되어 있습니다. 따라서 단일 파티션과 단일 컨슈머 서버에 대해서는 동시성 문제가 크게 발생하지 않습니다. 그러나 Kafka 환경이 확장되면 여러 파티션이 생성되고, 각각의 파티션에 대해 병렬 처리가 필요해지기 시작하면서 동시성 문제가 구조적으로 해결되지 않는다는 것을 알게 되었습니다. 이러한 문제를 해결하기 위해 방법을 찾던 도중 분산 락이라는 것을 알게 되었습니다. redisZooKeeper와 같은 분산 락 서비스를 사용한다면 카프카의 병렬처리라는 장점을 살려 성능을 높이면서 동시성 문제 역시 해결 할 수 있다는 생각이 들었습니다. 현재는 카프카를 다중 파티션, 다중 그룹으로 진행하는 것 까지는 완료하였고 분산락 구현을 시도하고 있습니다.
성능 테스트