1. Kafka 란?
: Apache 재단에 등록된 오픈소스로써, 분산형 스트리밍, 대규모 트래픽처리, 대용량 데이터 처리를 원활하게 처리하기 Message Queue (https://kafka.apache.org/)
Apache Kafka
Apache Kafka: A Distributed Streaming Platform.
kafka.apache.org
2. Kafka 구조 및 흐름
: kafka 의 구성은 main 의 역할인 kafka와 헬스체크 등 보조적인 역할인 zookeeper 가있다.
(최근에 zookeeper 의 의존성을 없애기 위해 kafka 단독으로 개발하여 나온 툴이 있는데,
zookeeper 대비 개선점은 확인되지 않는다.)
1) Kafka 기본구조
2) Producer
Producer는 데이터를 파티션에 따라 특정 브로커(리더)로 전송합니다.
전송 후 리더 브로커는 데이터를 먼저 받아 저장하고 바로 팔로워들에게 복제됩니다.
(Producer가 데이터를 리더 브로커에 보냄, 리더 브로커가 해당 파티션에 대한 주 데이터 저장소로 데이터를 기록, 팔로워 브로커도 데이터를 가져옴)
복제는 리더가 데이터를 받는 즉시 발생하는 것이 아니라, 리더가 데이터를 기록한 후에 복제 프로세스가 진행됩니다.
3) Consumer
4) Kafka Topic 및 Partition 구조 (/w Offset)
5) Key
6) Kafka broker 및 replication (Confluent version)
3. Kakfa setting 방법
: Kafka 를 세팅하는 방법에는 아래와 같이 여러가지가 있다.
그 중 우리는 3번으로 세팅해 보겠다(Docker Compose 기반)
1) on premise 로 직접 설치
2) docker 로 하나씩 띄우기
3) docker compose 로 한번에 띄우기
4) K8S 내 yaml 로 띄우기
5) K8S 내 kustomise 로 띠우기
6) K8S 내 helm 으로 직접 설치하기
4. Kafka docker compose로 띄우기
(Docker compose 가 설치되어있지 않는 경우 설치부터 하자!)
brew install cask docker-compose
아래는 Docker Compose 파일이다
version: "1"
services:
zookeeper:
image: confluentinc/cp-zookeeper:latest
ports:
- "2181:2181"
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 3000
ZOOKEEPER_INIT_LIMIT: 5
ZOOKEEPER_SYNC_LIMIT: 2
ZOOKEEPER_SERVER_ID: 1
kafka-cluster1:
image: confluentinc/cp-kafka:latest
ports:
- "9092:9092"
depends_on:
- zookeeper
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka-cluster1:29092,EXTERNAL://localhost:9092
KAFKA_NUM_PARTITIONS: 3
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
kafka-cluster2:
image: confluentinc/cp-kafka:latest
ports:
- "9093:9093"
depends_on:
- zookeeper
environment:
KAFKA_BROKER_ID: 2
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka-cluster2:29093,EXTERNAL://localhost:9093
KAFKA_NUM_PARTITIONS: 3
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
kafka-cluster3:
image: confluentinc/cp-kafka:latest
ports:
- "9094:9094"
depends_on:
- zookeeper
environment:
KAFKA_BROKER_ID: 3
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka-cluster3:29094,EXTERNAL://localhost:9094
KAFKA_NUM_PARTITIONS: 3
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
위의 docker compose 파일(파일명: docker-compose-kafka.yml)을 실행하려면
docker-compose -f docker-compose-kafka.yml up -d
5. Nest 연동
yarn add @nestjs/microservices kafkajs or pnpm i @nestjs/microservices kafkajs
6. 주문로직 리펙토링
1) 리펙토링 이유?
: 리펙토링을 하지 않아도 잘 돌아가는데 왜해야하는 걸까?
- 두개의 모듈로 각각 처리함으로써 DB 트랜젝션 범위 축소
- order service 에서 cart repo 와 order repo를 직접 참조하면서 수행하던 부분을 완전한 분리(느슨한 결합)
→ 향후 micro service 분리 시에도 바로 분리 가능
(단, Kafka 이슈 또는 Consumer 가 제대로 동작하지 않았을때 대체방안이 필요
2) 분리 방법?
: Kafka를 이용한 이벤트 처리로 분리
3) 한계?
- 코드레벨에서 복잡성이 상승
- DB 트랜젝션 및 락을 직접사용할 수 없기때문에 코드레벨로써 트랜젝션기능을 수행해야함
(분산락, Saga pattern 등 - 이후과정에서 진행예정)
- producer 이후 오류 발생 시 적절한 대처가 필요(Transactional outbox pattern 등 - 이후 과정으로 진행예정)
7. Kafka Ui
Broker 현황, Topics 현황 및 저장된 Messages 정보, 각 토픽별 Offset 위치, 소비하고 있는 consumer의 group과 현황 등을 바로 알 수 있다.
version: "2"
services:
kafka-ui:
image: provectuslabs/kafka-ui
container_name: kafka-ui
ports:
- "8989:8080"
restart: always
environment:
- KAFKA_CLUSTERS_0_NAME=local
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka-cluster1::29092,kafka-cluster2:29093,kafka-cluster3:29094
- KAFKA_CLUSTERS_0_ZOOKEEPER=zookeeper:2181
'Node js > Nest js 강의 내용' 카테고리의 다른 글
(다음과정 미리보기) (번외) Nest js 기반 Test Container 구축하기 (0) | 2025.01.27 |
---|---|
(다음과정 미리보기) Graphql 사용하기 (0) | 2025.01.27 |
8. Redis 연동 (장바구니 리펙토링) (0) | 2025.01.27 |
7. Docker (Nest js 로 개발한 서버를 docker로 띄워보자) (0) | 2025.01.27 |
6-2 비관적락을 이용한 동시성 제어(with Prisma) (0) | 2025.01.27 |