Kafka ์ž…๋ฌธ

Kafka ์ž…๋ฌธ. ์„œ๋น„์Šค๊ฐ€ ์ปค์ง€๋ฉด "์ฃผ๋ฌธ์ด ์ƒ๊ธฐ๋ฉด ์•Œ๋ฆผ ๋ณด๋‚ด๊ณ , ์žฌ๊ณ  ์ค„์ด๊ณ , ํ†ต๊ณ„ ์Œ“๊ณ ..."๊ฐ€ ๊ฑฐ๋ฏธ์ค„์ฒ˜๋Ÿผ ์–ฝํžŒ๋‹ค. Kafka๋Š” ์ด ํ๋ฆ„์„ ์ด๋ฒคํŠธ๋กœ ํ’€์–ด๋‚ธ๋‹ค. Producer·Consumer·Topic·Partition ๊ฐ™์€ ํ•ต์‹ฌ ๊ฐœ๋…๋ถ€ํ„ฐ Spring ์ฝ”๋“œ๊นŒ์ง€ ์ •๋ฆฌํ•œ๋‹ค.


๋“ค์–ด๊ฐ€๋ฉฐ

๋ฐฐ์น˜์™€ ์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ ๊ธ€์—์„œ Kafka๋ฅผ ์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ์˜ ๋Œ€ํ‘œ ๋„๊ตฌ๋กœ ์ž ๊น ๋‹ค๋ค˜๋‹ค. ์ด๋ฒˆ์—” ๊ทธ Kafka๋ฅผ ์ œ๋Œ€๋กœ ๋“ค์—ฌ๋‹ค๋ณธ๋‹ค.

์„œ๋น„์Šค๊ฐ€ ์ž‘์„ ๋• ๋ชจ๋“  ๊ฑธ ์ง์ ‘ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค. "์ฃผ๋ฌธ์ด ๋“ค์–ด์˜ค๋ฉด ๊ฒฐ์ œํ•˜๊ณ , ์žฌ๊ณ  ์ค„์ด๊ณ , ์ด๋ฉ”์ผ ๋ณด๋‚ด๊ณ , ํ†ต๊ณ„ ์Œ“๋Š”๋‹ค." ๊ทธ๋Ÿฐ๋ฐ ์ด ํ›„์† ์ž‘์—…์ด ๋Š˜์–ด๋‚ ์ˆ˜๋ก ์ฃผ๋ฌธ ์ฝ”๋“œ๊ฐ€ ๋ชจ๋“  ๊ฑธ ์•Œ์•„์•ผ ํ•˜๋Š” ๊ฑฐ๋ฏธ์ค„์ด ๋œ๋‹ค. ํ•˜๋‚˜๊ฐ€ ๋А๋ ค์ง€๋ฉด ์ „์ฒด๊ฐ€ ๋А๋ ค์ง€๊ณ , ํ•˜๋‚˜๊ฐ€ ์ฃฝ์œผ๋ฉด ์ฃผ๋ฌธ๊นŒ์ง€ ์‹คํŒจํ•œ๋‹ค.

Kafka๋Š” ์ด ๋ฌธ์ œ๋ฅผ ์ด๋ฒคํŠธ(event) ๋ผ๋Š” ๋ฐœ์ƒ์œผ๋กœ ํ‘ผ๋‹ค. "์ฃผ๋ฌธ์ด ์ƒ๊ฒผ๋‹ค"๋Š” ์‚ฌ์‹ค ํ•˜๋‚˜๋งŒ ๋˜์ง€๋ฉด, ๊ทธ๊ฑธ ํ•„์š”๋กœ ํ•˜๋Š” ์‹œ์Šคํ…œ๋“ค์ด ๊ฐ์ž ์•Œ์•„์„œ ๊ฐ€์ ธ๊ฐ€ ์ฒ˜๋ฆฌํ•œ๋‹ค. ๋ณด๋‚ด๋Š” ์ชฝ๊ณผ ๋ฐ›๋Š” ์ชฝ์ด ์„œ๋กœ๋ฅผ ๋ชฐ๋ผ๋„ ๋œ๋‹ค.

Kafka์˜ ํ•ต์‹ฌ์€ "๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์ „๋‹ฌํ•˜์ง€ ์•Š๊ณ , ํ๋ฅด๋Š” ํ†ต๋กœ์— ํ˜๋ ค๋ณด๋‚ธ๋‹ค"๋Š” ๊ฒƒ์ด๋‹ค. ๋ณด๋‚ด๋Š” ์ชฝ๊ณผ ๋ฐ›๋Š” ์ชฝ์ด ๋ถ„๋ฆฌ๋˜๋ฉด ์‹œ์Šคํ…œ์ด ์œ ์—ฐํ•ด์ง„๋‹ค.

์ด ๊ธ€์—์„œ๋Š” Kafka์˜ ํ•ต์‹ฌ ๊ฐœ๋…๊ณผ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์žก๊ณ , Spring์œผ๋กœ ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณธ๋‹ค.


Kafka๋ž€

Apache Kafka๋Š” ๋ถ„์‚ฐ ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆฌ๋ฐ ํ”Œ๋žซํผ์ด๋‹ค. 2011๋…„ ๋งํฌ๋“œ์ธ์—์„œ ๋งŒ๋“ค์–ด์กŒ๊ณ , ์ง€๊ธˆ์€ ๋Œ€์šฉ๋Ÿ‰ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์˜ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€์ด๋‹ค.

์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ๊ฑฐ๋Œ€ํ•˜๊ณ  ๋น ๋ฅธ ๋ฉ”์‹œ์ง€ ํ†ต๋กœ๋‹ค. ํ•œ์ชฝ์—์„œ ๋ฐ์ดํ„ฐ(์ด๋ฒคํŠธ)๋ฅผ ํ˜๋ ค๋ณด๋‚ด๋ฉด, ๋‹ค๋ฅธ ์ชฝ์—์„œ ๊ทธ๊ฑธ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•œ๋‹ค. ํ•ต์‹ฌ ํŠน์ง•์€ ์…‹์ด๋‹ค.

  • ๊ณ ์„ฑ๋Šฅ: ์ดˆ๋‹น ์ˆ˜๋ฐฑ๋งŒ ๊ฑด์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ํ™•์žฅ์„ฑ: ์„œ๋ฒ„๋ฅผ ์—ฌ๋Ÿฌ ๋Œ€๋กœ ๋Š˜๋ ค ๋ถ€ํ•˜๋ฅผ ๋ถ„์‚ฐํ•œ๋‹ค.
  • ์˜์†์„ฑ: ๋ฉ”์‹œ์ง€๋ฅผ ๋””์Šคํฌ์— ์ €์žฅํ•ด, ์†Œ๋น„์ž๊ฐ€ ๋‚˜์ค‘์— ์ฝ์–ด๋„ ๋œ๋‹ค. (๋ฉ”์‹œ์ง€๊ฐ€ ์‚ฌ๋ผ์ง€์ง€ ์•Š์Œ)

๋งˆ์ง€๋ง‰ ํŠน์ง•์ด ์ „ํ†ต์ ์ธ ๋ฉ”์‹œ์ง€ ํ์™€์˜ ํฐ ์ฐจ์ด๋‹ค. Kafka๋Š” ์ฝ์—ˆ๋‹ค๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ์ง€์šฐ์ง€ ์•Š๋Š”๋‹ค. ์ •ํ•ด์ง„ ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ณด๊ด€ํ•ด์„œ, ์—ฌ๋Ÿฌ ์†Œ๋น„์ž๊ฐ€ ๊ฐ์ž ๋‹ค๋ฅธ ์†๋„๋กœ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.


ํ•ต์‹ฌ ๊ฐœ๋…

Kafka๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด ๋„ค ๊ฐœ๋…์„ ์žก์•„์•ผ ํ•œ๋‹ค.

๊ฐœ๋… ์—ญํ• 
Producer ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ•˜๋Š”(๋ณด๋‚ด๋Š”) ์ชฝ
Consumer ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋…ํ•˜๋Š”(๋ฐ›๋Š”) ์ชฝ
Topic ์ด๋ฒคํŠธ๊ฐ€ ์Œ“์ด๋Š” ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ํ†ต๋กœ
Partition Topic์„ ๋‚˜๋ˆˆ ๋‹จ์œ„ (๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ·ํ™•์žฅ์˜ ํ•ต์‹ฌ)

 

Kafka ์ด๋ฒคํŠธ ๊ตฌ์กฐ

ํ๋ฆ„์€ ๋‹จ์ˆœํ•˜๋‹ค. Producer๊ฐ€ Topic์— ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ•˜๋ฉด, ๊ทธ Topic์„ ๊ตฌ๋…ํ•˜๋Š” Consumer๋“ค์ด ์ด๋ฒคํŠธ๋ฅผ ๊ฐ€์ ธ๊ฐ€ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ค‘๊ฐ„์˜ Kafka๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๊ด€ํ•˜๊ณ  ์ „๋‹ฌํ•œ๋‹ค.

Topic๊ณผ Partition

Topic์€ ์ด๋ฒคํŠธ์˜ ์นดํ…Œ๊ณ ๋ฆฌ๋‹ค. "orders", "payments", "user-signups"์ฒ˜๋Ÿผ ์ข…๋ฅ˜๋ณ„๋กœ ํ†ต๋กœ๋ฅผ ๋‚˜๋ˆˆ๋‹ค.

Partition์€ ํ•˜๋‚˜์˜ Topic์„ ์—ฌ๋Ÿฌ ์กฐ๊ฐ์œผ๋กœ ๋‚˜๋ˆˆ ๊ฒƒ์ด๋‹ค. ์ด๊ฒŒ Kafka ์„ฑ๋Šฅ์˜ ํ•ต์‹ฌ์ด๋‹ค. Topic์„ ํŒŒํ‹ฐ์…˜ 3๊ฐœ๋กœ ๋‚˜๋ˆ„๋ฉด, 3๊ฐœ์˜ Consumer๊ฐ€ ๋™์‹œ์— ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ํŒŒํ‹ฐ์…˜์„ ๋Š˜๋ฆฌ๋ฉด ์ฒ˜๋ฆฌ๋Ÿ‰์ด ๋Š˜์–ด๋‚œ๋‹ค.

Topic: orders
 โ”œ Partition 0 → Consumer A
 โ”œ Partition 1 → Consumer B
 โ”” Partition 2 → Consumer C   (3๋ฐฐ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ)

๊ฐ™์€ ํ‚ค(์˜ˆ: user_id)๋ฅผ ๊ฐ€์ง„ ์ด๋ฒคํŠธ๋Š” ํ•ญ์ƒ ๊ฐ™์€ ํŒŒํ‹ฐ์…˜์œผ๋กœ ๊ฐ€์„œ, ์ˆœ์„œ๊ฐ€ ๋ณด์žฅ๋œ๋‹ค. ํ•œ ์‚ฌ์šฉ์ž์˜ ์ฃผ๋ฌธ ์ˆœ์„œ๊ฐ€ ๋’ค๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค.

Consumer Group

์—ฌ๋Ÿฌ Consumer๋ฅผ ๋ฌถ์€ ๊ฒŒ Consumer Group์ด๋‹ค. ๊ฐ™์€ ๊ทธ๋ฃน ์•ˆ์—์„œ๋Š” ํŒŒํ‹ฐ์…˜์„ ๋‚˜๋ˆ  ๊ฐ€์ ธ์„œ ๋ถ€ํ•˜๋ฅผ ๋ถ„์‚ฐํ•˜๊ณ , ๋‹ค๋ฅธ ๊ทธ๋ฃน๋ผ๋ฆฌ๋Š” ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ž ๋…๋ฆฝ์ ์œผ๋กœ ๋ฐ›๋Š”๋‹ค.

Topic: orders
 โ”œ Group "์žฌ๊ณ ๊ด€๋ฆฌ"  → ์žฌ๊ณ  ์ฐจ๊ฐ (orders๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌ)
 โ”” Group "ํ†ต๊ณ„"      → ํ†ต๊ณ„ ์ง‘๊ณ„ (๊ฐ™์€ orders๋ฅผ ๋˜ ๋ฐ›์•„ ์ฒ˜๋ฆฌ)

orders ํ† ํ”ฝ ํ•˜๋‚˜๋ฅผ ์žฌ๊ณ ํŒ€๊ณผ ํ†ต๊ณ„ํŒ€์ด ์„œ๋กœ ์˜ํ–ฅ ์—†์ด ๊ฐ์ž ์†Œ๋น„ํ•œ๋‹ค. ์ด๊ฒŒ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜์˜ ํž˜์ด๋‹ค.


Spring์œผ๋กœ Producer ๋งŒ๋“ค๊ธฐ

์ด์ œ ์ฝ”๋“œ๋กœ ๋ณด์ž. ์ฃผ๋ฌธ์ด ์ƒ๊ธธ ๋•Œ๋งˆ๋‹ค ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ•˜๋Š” Producer๋‹ค. ๋จผ์ € ์„ค์ •.

# application.yml
spring:
  kafka:
    bootstrap-servers: localhost:9092
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
    consumer:
      group-id: order-service
      auto-offset-reset: earliest
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
      properties:
        spring.json.trusted.packages: "*"

์ด๋ฒคํŠธ ๊ฐ์ฒด์™€ Producer ์ฝ”๋“œ.

// ๋ฐœํ–‰ํ•  ์ด๋ฒคํŠธ (record๋กœ ๊ฐ„๋‹จํžˆ)
public record OrderEvent(Long orderId, Long userId, int amount) {}

@Service
public class OrderEventProducer {

    private final KafkaTemplate<String, OrderEvent> kafkaTemplate;

    public OrderEventProducer(KafkaTemplate<String, OrderEvent> kafkaTemplate) {
        this.kafkaTemplate = kafkaTemplate;
    }

    public void publish(OrderEvent event) {
        // key๋ฅผ userId๋กœ → ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ด๋ฒคํŠธ๋Š” ๊ฐ™์€ ํŒŒํ‹ฐ์…˜(์ˆœ์„œ ๋ณด์žฅ)
        kafkaTemplate.send("orders", String.valueOf(event.userId()), event);
    }
}

์ฃผ๋ฌธ ์„œ๋น„์Šค๋Š” ์ด์ œ ํ›„์† ์ž‘์—…์„ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋ฒคํŠธ๋งŒ ๋ฐœํ–‰ํ•˜๊ณ  ๋์ด๋‹ค.

@Service
public class OrderService {

    private final OrderEventProducer producer;

    public void createOrder(OrderRequest req) {
        Order order = orderRepository.save(req.toEntity());

        // ํ›„์† ์ž‘์—…(์žฌ๊ณ ·์•Œ๋ฆผ·ํ†ต๊ณ„)์„ ์ง์ ‘ ๋ถ€๋ฅด์ง€ ์•Š๊ณ  ์ด๋ฒคํŠธ๋งŒ ๋ฐœํ–‰
        producer.publish(new OrderEvent(
                order.getId(), order.getUserId(), order.getAmount()));
        // ์ดํ›„ ๋ˆ„๊ฐ€ ๋ฌด์—‡์„ ํ•˜๋Š”์ง€ OrderService๋Š” ๋ชจ๋ฅธ๋‹ค
    }
}

Spring์œผ๋กœ Consumer ๋งŒ๋“ค๊ธฐ

๋ฐœํ–‰๋œ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋Š” Consumer๋“ค์ด๋‹ค. @KafkaListener ํ•˜๋‚˜๋ฉด ๋œ๋‹ค.

@Service
public class InventoryConsumer {

    // "์žฌ๊ณ ๊ด€๋ฆฌ" ๊ทธ๋ฃน์œผ๋กœ orders๋ฅผ ๊ตฌ๋…
    @KafkaListener(topics = "orders", groupId = "inventory")
    public void handle(OrderEvent event) {
        // ์žฌ๊ณ  ์ฐจ๊ฐ
        inventoryService.decrease(event.orderId());
        log.info("์žฌ๊ณ  ์ฐจ๊ฐ ์™„๋ฃŒ: order={}", event.orderId());
    }
}

@Service
public class NotificationConsumer {

    // "์•Œ๋ฆผ" ๊ทธ๋ฃน์œผ๋กœ ๊ฐ™์€ orders๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๊ตฌ๋…
    @KafkaListener(topics = "orders", groupId = "notification")
    public void handle(OrderEvent event) {
        // ์ฃผ๋ฌธ ํ™•์ธ ์•Œ๋ฆผ ๋ฐœ์†ก
        notificationService.send(event.userId(), "์ฃผ๋ฌธ์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค");
    }
}

๋‘ Consumer๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๊ทธ๋ฃน์ด๋ผ, ๊ฐ™์€ ์ฃผ๋ฌธ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ž ๋…๋ฆฝ์ ์œผ๋กœ ๋ฐ›๋Š”๋‹ค. ์žฌ๊ณ  ์ฐจ๊ฐ๊ณผ ์•Œ๋ฆผ ๋ฐœ์†ก์ด ์„œ๋กœ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ์•Œ๋ฆผ ์„œ๋ฒ„๊ฐ€ ์ž ์‹œ ์ฃฝ์–ด๋„ ์žฌ๊ณ  ์ฐจ๊ฐ์€ ๋ฉ€์ฉกํžˆ ๋Œ์•„๊ฐ€๊ณ , ์•Œ๋ฆผ ์„œ๋ฒ„๊ฐ€ ์‚ด์•„๋‚˜๋ฉด Kafka์— ๋ณด๊ด€๋œ ์ด๋ฒคํŠธ๋ฅผ ์ด์–ด์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค.

์ƒˆ ํ›„์† ์ž‘์—…์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์œผ๋ฉด? ์ƒˆ ๊ทธ๋ฃน์˜ Consumer๋ฅผ ํ•˜๋‚˜ ๋” ๋งŒ๋“ค๋ฉด ๋์ด๋‹ค. ๊ธฐ์กด ์ฝ”๋“œ๋Š” ํ•œ ์ค„๋„ ์•ˆ ๋ฐ”๊พผ๋‹ค.

@Service
public class StatsConsumer {
    @KafkaListener(topics = "orders", groupId = "stats")
    public void handle(OrderEvent event) {
        statsService.record(event);   // ํ†ต๊ณ„ ์ง‘๊ณ„ ์ถ”๊ฐ€ — ๊ธฐ์กด ์ฝ”๋“œ ๋ณ€๊ฒฝ ์—†์Œ
    }
}

์ง์ ‘ ํ˜ธ์ถœ vs Kafka

Kafka๋ฅผ ์“ฐ๋ฉด ๋ฌด์—‡์ด ๋‹ฌ๋ผ์ง€๋Š”์ง€ ๋น„๊ตํ•˜๋ฉด ๋ถ„๋ช…ํ•˜๋‹ค.

  ์ง์ ‘ ํ˜ธ์ถœ Kafka (์ด๋ฒคํŠธ)
๊ฒฐํ•ฉ๋„ ์ฃผ๋ฌธ์ด ๋ชจ๋“  ํ›„์†์„ ์•Ž ์„œ๋กœ ๋ชจ๋ฆ„ (๋А์Šจํ•จ)
ํ›„์† ์ถ”๊ฐ€ ์ฃผ๋ฌธ ์ฝ”๋“œ ์ˆ˜์ • Consumer๋งŒ ์ถ”๊ฐ€
์žฅ์•  ์ „ํŒŒ ํ•˜๋‚˜ ์ฃฝ์œผ๋ฉด ์ฃผ๋ฌธ ์‹คํŒจ ๊ฒฉ๋ฆฌ๋จ (๋…๋ฆฝ)
๋ถ€ํ•˜ ๋™๊ธฐ ์ฒ˜๋ฆฌ๋กœ ๋А๋ ค์ง ๋น„๋™๊ธฐ๋กœ ํ˜๋ ค๋ณด๋ƒ„
์žฌ์ฒ˜๋ฆฌ ์–ด๋ ค์›€ ๋ณด๊ด€๋œ ์ด๋ฒคํŠธ ์žฌ์†Œ๋น„

๋””์ž์ธ ํŒจํ„ด ๊ธ€์—์„œ ๋‹ค๋ฃฌ ์˜ต์ €๋ฒ„ ํŒจํ„ด์„, ์‹œ์Šคํ…œ ๋ ˆ๋ฒจ๋กœ ํ™•์žฅํ•œ ๊ฒƒ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋ฐœํ–‰์ž์™€ ๊ตฌ๋…์ž๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ทธ ๋ฐœ์ƒ์ด Kafka์—์„œ๋Š” ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹ ์œผ๋กœ ์ปค์ง„๋‹ค.


์–ธ์ œ ์“ฐ๊ณ , ์–ธ์ œ ์•ˆ ์“ฐ๋‚˜

Kafka๊ฐ€ ๋งŒ๋Šฅ์€ ์•„๋‹ˆ๋‹ค. ๋„์ž…ํ•˜๋ฉด ์šด์˜ํ•  ์ธํ”„๋ผ๊ฐ€ ํ•˜๋‚˜ ๋” ์ƒ๊ธด๋‹ค.

Kafka๊ฐ€ ์–ด์šธ๋ฆฌ๋Š” ๊ฒฝ์šฐ

  • ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ์— ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ์ด ๋ฐ˜์‘ํ•ด์•ผ ํ•  ๋•Œ
  • ์„œ๋น„์Šค ๊ฐ„ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ์‹ถ์„ ๋•Œ (MSA)
  • ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ˜๋ ค๋ณด๋‚ด์•ผ ํ•  ๋•Œ
  • ๋กœ๊ทธ ์ˆ˜์ง‘, ์ด๋ฒคํŠธ ์†Œ์‹ฑ, ์‹ค์‹œ๊ฐ„ ํŒŒ์ดํ”„๋ผ์ธ

๊ตณ์ด ํ•„์š” ์—†๋Š” ๊ฒฝ์šฐ

  • ์„œ๋น„์Šค๊ฐ€ ์ž‘๊ณ  ํ›„์† ์ž‘์—…์ด ๋‹จ์ˆœํ•  ๋•Œ → ์ง์ ‘ ํ˜ธ์ถœ์ด ๋” ๊ฐ„๋‹จ
  • ์ฆ‰๊ฐ์ ์ธ ์‘๋‹ต์ด ๊ผญ ํ•„์š”ํ•  ๋•Œ (Kafka๋Š” ๋น„๋™๊ธฐ)
  • ํŠธ๋ž˜ํ”ฝ์ด ์ ์–ด ๋ฉ”์‹œ์ง€ ํ๊ฐ€ ๊ณผํ•œ ๊ฒฝ์šฐ

์ž‘์€ ์„œ๋น„์Šค์— Kafka๋ฅผ ๊น”๋ฉด ์šด์˜ ๋ณต์žก๋„๋งŒ ๋Š˜์–ด๋‚œ๋‹ค. "์ด๋ฒคํŠธ์— ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ์ด ๋ฐ˜์‘ํ•ด์•ผ ํ•˜๋Š”" ์ƒํ™ฉ์ด ๋์„ ๋•Œ๊ฐ€ ๋„์ž… ํƒ€์ด๋ฐ์ด๋‹ค.


๋งˆ์น˜๋ฉฐ

Kafka๋Š” "๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์ „๋‹ฌํ•˜๋Š”" ๋ฐฉ์‹์„ "์ด๋ฒคํŠธ๋ฅผ ํ˜๋ ค๋ณด๋‚ด๋Š”" ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๊พผ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ ๋ณด๋‚ด๋Š” ์ชฝ๊ณผ ๋ฐ›๋Š” ์ชฝ์ด ๋ถ„๋ฆฌ๋˜๊ณ , ์‹œ์Šคํ…œ์ด ์œ ์—ฐํ•ด์ง„๋‹ค. ์ฃผ๋ฌธ ์„œ๋น„์Šค๋Š” ๊ทธ์ € "์ฃผ๋ฌธ์ด ์ƒ๊ฒผ๋‹ค"๊ณ  ์™ธ์น˜๊ณ , ์žฌ๊ณ ·์•Œ๋ฆผ·ํ†ต๊ณ„๋Š” ๊ฐ์ž ์•Œ์•„์„œ ๋ฐ˜์‘ํ•œ๋‹ค.

ํ•ต์‹ฌ๋งŒ ๋‹ค์‹œ ์งš์œผ๋ฉด, Producer๊ฐ€ Topic์— ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ•˜๊ณ , Partition์œผ๋กœ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋˜๋ฉฐ, Consumer Group์ด ๊ฐ์ž ๋…๋ฆฝ์ ์œผ๋กœ ์†Œ๋น„ํ•œ๋‹ค. ์ด ๊ตฌ์กฐ ์œ„์—์„œ ๋А์Šจํ•œ ๊ฒฐํ•ฉ, ์žฅ์•  ๊ฒฉ๋ฆฌ, ์†์‰ฌ์šด ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

๋ฌผ๋ก  ๋ชจ๋“  ๊ณณ์— ํ•„์š”ํ•œ ๊ฑด ์•„๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์„œ๋น„์Šค๊ฐ€ ์ปค์ง€๊ณ  ์ด๋ฒคํŠธ์— ๋ฐ˜์‘ํ•  ์‹œ์Šคํ…œ์ด ๋Š˜์–ด๋‚  ๋•Œ, Kafka๋Š” ๊ฑฐ๋ฏธ์ค„ ๊ฐ™์€ ์ง์ ‘ ํ˜ธ์ถœ์„ ๊น”๋”ํ•œ ์ด๋ฒคํŠธ ํ๋ฆ„์œผ๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค. ๊ทธ๊ฒŒ ๋งŽ์€ ํšŒ์‚ฌ๊ฐ€ Kafka๋ฅผ ์“ฐ๋Š” ์ด์œ ๋‹ค.


์ฐธ๊ณ  ์ถœ์ฒ˜