kafka는 대량의 데이터를 높은 처리량, 낮은 지연, 안정적 운용을 위해
탄생한 시스템입니다.
Kafka란 무엇일까요?
우리는 가끔 대기업에 관련된 기사를 보면 하청업체에 일을 할당 했다는 기사를 볼 수 있습니다. 대기업은 하청업체에 일을 할당 함으로서 자신들이 집중할 수 있는 일에 더욱 집중 할 수 있게 되고 이로 인해 효율성을 확보 할 수 있습니다. 개발에도 이렇게 역할을 분리하여 일을 할당 시킴으로 효율성을 높이면 굉장히 좋지 않을까요? 이러한 일을 가능하게 만드는 시스템이 Kafka 입니다.
즉 Kafka를 한마디로 표현하면 '하청업체에 일을 할당하는 중간 관리자'라 할 수 있겠습니다.
질문 🧑💻) WebFlux도 비동기를 통해 효율성을 향상시키고 Kafka도 비동기를 통해 효율성을 향상시킨다 하는데 무슨 차이가 있나요?
- 같이 일하는 동료분이 이러한 질문을 한 적이 있습니다. Webflux는 하나의 회사에서 여러 직원들을 고용해서 효율성을 높이는 것이고 kafka는 하청업체에 일을 할당함으로서 효율성을 높이는 것입니다. 즉, 내부 인원 충원을 통해 효율성을 높이냐, 회사와 회사간의 협업으로 효율성을 높이냐의 차이가 있겠습니다.
이번 글에서는 Kafka를 사용한다면 어떻게 확장하고 성능을 개선할지, 비동기 통신으로 인한 데이터 정합성 문제를 해결하는지에 대한 사전 준비글을 작성해 보겠습니다.
- 참고
1부: 사전 지식과 청사진 공유
2부: 동영상을 통한 실전 운용 전략 설명
kafka 사전지식
- Topic
- Kafka 서버는 여러 Topic을 관리한다. 이 토픽은 Kafka 서버에 값을 보내는 기준이 된다. 값을 보낼때는 Key, Value로 값을 보낸다.
- Producer
- Topic을 기준으로 값을 보내는 주체이다. Producer가 Kafka Server에 값을 보낼때 어떠한 Topic에 어떠한 key, value값을 전달하지 값을 결정해서 보내면 된다.
- Consumer
- Kafka Sever에서 관리하는 Topic을 구독하고 그 값을 전달 받는 주체이다. Consumer 또한 Producer와 동일하게 Topic을 기준으로 Key, Value 값을 받는다.
- Consumer Group
- Kafka 서버의 Topic은 여러 Partition(데이터 파이프라인)이 관리가 된다. 여러 Consumer들은 하나의 Group으로 묶을 수 있는데 이렇게 묶인 Cosumer들은 하나의 Topic을 공유한다. 공유 한다는 말은 하나의 토픽의 여러 Partition들의 값을 Group에 묶인 Consumer들이 병렬적으로 값을 처리한다는 말이다. 이것은 kafka Server를 사용하여 성능을 높이는 중요한 척도이다.
- Kafka Cluster
- 여러 kafka Server의 집단을 kafka Cluster라 부른다. 이렇게 여러 kafka Server를 운용하면 Load Balancing을 통해 데이터 처리의 성능을 높일 수 있다. 이 또한 Kafka 서버를 운용하면서 성능과 효율성을 높이는 중요한 척도이다.
- kafka Reflication
- Topic을 생성할때 reflication 설정을 통해 여러 복제본을 운용을 할 수 있다. 예를 들어 reflication 설정을 3으로 하면 Topic의 각 Partition들의 복제본이 3개가 생성 되고 이중 한개의 파티션은 Leader Partition이 된다. 나머지 2개의 파티션은 Flow Partition이라 한다. Flow Partition은 지속적으로 Leader 데이터를 복제하여 최신 상태를 유지한다. 만약 Leader에 장애가 발생하여 운용이 불가한 상태가 된다면 내부적으로 복제본 중 리더를 선정하여 장애에 대응한다. 이는 kafka의 안정적 운용을 위한 중요한 척도이다.
kafka 효율성을 높이는 방법
-
Topic의 Partition의 개수를 늘립니다. 그리고 하나의 Group을 공유하는 여러 Consumer들이 이 Topic을 구독합니다.
-
물리적으로 Kafka 브로커 서버 여러개를 구축하여 Load Balancing을 통해 효율성을 높입니다.
비동기 통신에서 정합성을 맞추는 운용 전략
-
kafka 서버를 통한 비동기 통신 히스토리를 추적하는 하나의 서버를 준비합니다. (async-task-consumer-server)
-
Kafka Server에 Topic은 2개만 생성합니다.
- task.topic
- task.result.topic
- 비동기 통신이 필요한 각 서버는 AsyncTaskProducer를 통해 값을 전달
합니다. 값을 전달하는 규격은 아래와 같습니다.
key: {
"transactionUUID": "",
"aysncTaskCategory": Enum
},
body: {
<T: Object>
}
- async-task-consumer-server에서는 task.topic을 구독하는 AsyncTaskConsumer를 통해 이 값을 전달 받습니다. 전달 받는 값은
async_task_history라는 DB에 업데이트 하여 history를 관리합니다.
- async_task_history의 DB는 Create만 이루어 집니다.
- 이렇게 쌓인 데이터는 추후 transactionUUID를 통해서 정합성을 맞추는 중요한 데이터가 됩니다.
-
history를 DB에 저장하면 AsyncTaskResultProducer를 통해
위와 같은 값 그대로 task.result.topic에 값을 전달합니다.
-
각 서버는 각자의 관심사에 맞게 Consumer를 구축하고 task.result.topic을 구독하여 값을 전달받습니다. 전달 받은 값을 통해 특정 비지니스 로직을 수행하여 비동기 통신을 완료합니다.
-
통신의 문제가 생겨 정합성 문제가 생긴다면 async-task-consumer-server에 저장된 고유값(UUID)을 통해 정합성을 맞추는 시도를 합니다.
마무리
다음 시간에는 영상 촬영을 통해 실제 프로젝트를 구축해보면서 어떻게 성능을 높이고 정합성을 맞추는지에 대해 설명 하도록 하겠습니다. 감사합니다.