λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Kafka μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μŠ€μΌ€μΌλ§: ν”„λ‘œλ“€μ„œμ™€ 컨슈머의 ν™•μž₯ 및 κ³ κ°€μš©μ„± μ „λž΅

okrestart 2024. 10. 23.

 

Apache Kafka λŠ” λŒ€κ·œλͺ¨ 데이터 슀트리밍 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ§€μ›ν•˜λŠ” κ°•λ ₯ν•œ ν”Œλž«νΌμž…λ‹ˆλ‹€. Kafka μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ„±κ³΅μ μœΌλ‘œ μŠ€μΌ€μΌλ§ν•˜λ €λ©΄ ν”„λ‘œλ“€μ„œμ™€ 컨슈머의 μˆ˜ν‰ ν™•μž₯ , ν† ν”½μ˜ νŒŒν‹°μ…”λ‹ μ „λž΅ , 컨슈머 κ·Έλ£Ή 관리 , 그리고 κ³ κ°€μš©μ„± 을 μœ„ν•œ μž₯μ•  λŒ€μ‘ μ „λž΅ 이 ν•„μˆ˜μ μž…λ‹ˆλ‹€. 이번 ν¬μŠ€νŒ…μ—μ„œλŠ” μ΄λŸ¬ν•œ μš”μ†Œλ“€μ„ μ‚΄νŽ΄λ³΄κ³ , 효과적인 Kafka μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μŠ€μΌ€μΌλ§ 방법을 μ„€λͺ…ν•©λ‹ˆλ‹€.

 


 

 

1. ν”„λ‘œλ“€μ„œμ™€ 컨슈머의 μˆ˜ν‰ ν™•μž₯

Kafka μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μˆ˜ν‰ ν™•μž₯ (Horizontal Scaling)ν•˜λ €λ©΄ ν”„λ‘œλ“€μ„œ 와 컨슈머 μΈμŠ€ν„΄μŠ€λ₯Ό λŠ˜λ¦¬λŠ” 것이 ν•΅μ‹¬μž…λ‹ˆλ‹€. μˆ˜ν‰ ν™•μž₯은 νŠΈλž˜ν”½μ΄ 증가할 λ•Œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 처리 λŠ₯λ ₯을 ν™•μž₯ν•˜λŠ” 데 μ€‘μš”ν•œ 역할을 ν•©λ‹ˆλ‹€.

ν”„λ‘œλ“€μ„œ ν™•μž₯

ν”„λ‘œλ“€μ„œ λŠ” μ—¬λŸ¬ μΈμŠ€ν„΄μŠ€λ₯Ό 톡해 λ³‘λ ¬λ‘œ 데이터λ₯Ό Kafka 브둜컀 에 전솑할 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” λ©”μ‹œμ§€λ₯Ό λΉ λ₯΄κ³  μ•ˆμ •μ μœΌλ‘œ μ „μ†‘ν•˜λŠ” 데 도움이 λ©λ‹ˆλ‹€.

컨슈머 ν™•μž₯

컨슈머 λŠ” 컨슈머 κ·Έλ£Ή 을 ν™œμš©ν•˜μ—¬ λ©”μ‹œμ§€λ₯Ό λ³‘λ ¬λ‘œ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 컨슈머 κ·Έλ£Ή λ‚΄μ˜ μ»¨μŠˆλ¨Έκ°€ νŒŒν‹°μ…˜ 을 λ‚˜λˆ μ„œ μ²˜λ¦¬ν•˜λ―€λ‘œ, 컨슈머 μΈμŠ€ν„΄μŠ€λ₯Ό 늘리면 λ™μ‹œμ— μ²˜λ¦¬ν•  수 μžˆλŠ” λ©”μ‹œμ§€ 양도 μ¦κ°€ν•©λ‹ˆλ‹€.

@KafkaListener(topics = "my_topic", groupId = "my_group", concurrency = "3")
public void consume(String message) {
    System.out.println("Consumed message: " + message);
}

μ„€λͺ…:

  • concurrency = “3” : μ„Έ 개의 컨슈머 μΈμŠ€ν„΄μŠ€κ°€ λ™μ‹œμ— λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€.
  • μˆ˜ν‰ ν™•μž₯ 을 톡해 νŠΈλž˜ν”½μ΄ 증가할 λ•Œ μ„±λŠ₯을 ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

 


 

2. ν† ν”½μ˜ νŒŒν‹°μ…”λ‹ μ „λž΅

Kafka 토픽은 νŒŒν‹°μ…˜ 으둜 λ‚˜λ‰˜λ©°, νŒŒν‹°μ…”λ‹μ€ ν™•μž₯μ„± κ³Ό λΆ€ν•˜ λΆ„μ‚° 에 맀우 μ€‘μš”ν•œ 역할을 ν•©λ‹ˆλ‹€. 각 νŒŒν‹°μ…˜μ€ λ…λ¦½μ μœΌλ‘œ 처리되기 λ•Œλ¬Έμ—, νŒŒν‹°μ…˜ 수 λ₯Ό 적절히 μ„€μ •ν•˜λŠ” 것이 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μŠ€μΌ€μΌλ§μ˜ ν•΅μ‹¬μž…λ‹ˆλ‹€.

νŒŒν‹°μ…”λ‹ μ „λž΅

  1. Round-robin 방식:
    - λ©”μ‹œμ§€κ°€ κ· λ“±ν•˜κ²Œ νŒŒν‹°μ…˜μ— λΆ„λ°°λ©λ‹ˆλ‹€. 기본적인 λ‘œλ“œ λ°ΈλŸ°μ‹± λ°©λ²•μœΌλ‘œ 주둜 μ‚¬μš©λ©λ‹ˆλ‹€.
  2. ν‚€ 기반 νŒŒν‹°μ…”λ‹ :
    - νŠΉμ • 킀에 따라 λ©”μ‹œμ§€κ°€ κ³ μ •λœ νŒŒν‹°μ…˜ 에 ν• λ‹Ήλ©λ‹ˆλ‹€. 데이터λ₯Ό μΌκ΄€λ˜κ²Œ μ²˜λ¦¬ν•˜κ±°λ‚˜ νŠΉμ • 데이터λ₯Ό νŠΉμ • νŒŒν‹°μ…˜μ—μ„œ μ²˜λ¦¬ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.

ν† ν”½ 생성 μ‹œ νŒŒν‹°μ…˜ μ„€μ •

kafka-topics --create --topic my_topic --partitions 6 --replication-factor 3 --bootstrap-server localhost:9092

μ„€λͺ…:

  • –partitions 6 : ν•΄λ‹Ή 토픽에 6개의 νŒŒν‹°μ…˜μ„ μƒμ„±ν•©λ‹ˆλ‹€. νŒŒν‹°μ…˜ 수λ₯Ό 적절히 늘리면 μ»¨μŠˆλ¨Έκ°€ λ™μ‹œμ— μ—¬λŸ¬ νŒŒν‹°μ…˜μ„ μ²˜λ¦¬ν•  수 μžˆμ–΄ ν™•μž₯μ„± 이 λ†’μ•„μ§‘λ‹ˆλ‹€.
  • νŒŒν‹°μ…”λ‹ μ „λž΅ 은 λ©”μ‹œμ§€ 처리 μ„±λŠ₯에 직접적인 영ν–₯을 λ―ΈμΉ©λ‹ˆλ‹€.

 


 

3. 컨슈머 κ·Έλ£Ή 관리

컨슈머 κ·Έλ£Ή 은 Kafkaμ—μ„œ λ™μΌν•œ λ©”μ‹œμ§€λ₯Ό 쀑볡 μ²˜λ¦¬ν•˜μ§€ μ•Šκ³  μ—¬λŸ¬ μ»¨μŠˆλ¨Έκ°€ λ©”μ‹œμ§€λ₯Ό λ³‘λ ¬λ‘œ μ²˜λ¦¬ν•  수 μžˆλ„λ‘ λ„μ™€μ€λ‹ˆλ‹€. 각 μ»¨μŠˆλ¨ΈλŠ” νŠΉμ • νŒŒν‹°μ…˜μ„ ν• λ‹Ήλ°›μ•„ λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•˜λ©°, κ·Έλ£Ή λ‚΄ 컨슈머 μˆ˜λŠ” νŒŒν‹°μ…˜ μˆ˜μ™€ 일치 ν•˜κ±°λ‚˜ 적어야 졜적의 μ„±λŠ₯을 λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

컨슈머 κ·Έλ£Ή ꡬ성 μ˜ˆμ‹œ

spring:
  kafka:
    consumer:
      group-id: "my_group"
      auto-offset-reset: "earliest"

μ„€λͺ…:

  • group-id : 컨슈머 그룹을 μ •μ˜ν•©λ‹ˆλ‹€.
  • auto-offset-reset : νŒŒν‹°μ…˜μ—μ„œ λ©”μ‹œμ§€λ₯Ό 읽기 μ‹œμž‘ν•  μœ„μΉ˜λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€. "earliest" 둜 μ„€μ •ν•˜λ©΄ μ²˜μŒλΆ€ν„° λ©”μ‹œμ§€λ₯Ό μ½μŠ΅λ‹ˆλ‹€.

 


 

4. κ³ κ°€μš©μ„±κ³Ό μž₯μ•  λŒ€μ‘ μ „λž΅

Kafka μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ—μ„œ κ³ κ°€μš©μ„±μ„ ν™•λ³΄ν•˜λ €λ©΄ 쀑단 μ—†λŠ” μ„œλΉ„μŠ€ 제곡 이 μ€‘μš”ν•©λ‹ˆλ‹€. KafkaλŠ” 브둜컀 볡제 λ₯Ό 톡해 λ°μ΄ν„°μ˜ κ³ κ°€μš©μ„± 을 보μž₯ν•˜λ©°, 이λ₯Ό μœ„ν•œ λ‹€μ–‘ν•œ μž₯μ•  λŒ€μ‘ μ „λž΅μ„ κ³ λ €ν•΄μ•Ό ν•©λ‹ˆλ‹€.

브둜컀 볡제 μ„€μ •

KafkaλŠ” 볡제 λ₯Ό 톡해 λΈŒλ‘œμ»€κ°€ μ‹€νŒ¨ν•˜λ”λΌλ„ 데이터λ₯Ό μ•ˆμ „ν•˜κ²Œ λ³΄μ‘΄ν•©λ‹ˆλ‹€. Replication Factor λ₯Ό μ‚¬μš©ν•΄ ν† ν”½ λ‚΄ λ©”μ‹œμ§€μ˜ λ³΅μ œλ³Έμ„ μ—¬λŸ¬ λΈŒλ‘œμ»€μ— λΆ„μ‚°ν•˜μ—¬ μž₯μ•  λ°œμƒ μ‹œ 데이터λ₯Ό 볡ꡬ할 수 μžˆμŠ΅λ‹ˆλ‹€.

kafka-topics --create --topic my_topic --partitions 6 --replication-factor 3 --bootstrap-server localhost:9092

μž₯μ•  λŒ€μ‘ μ „λž΅

  1. 리더-νŒ”λ‘œμ›Œ ꡬ쑰 :
    - 각 νŒŒν‹°μ…˜μ—λŠ” 리더 와 νŒ”λ‘œμ›Œ λΈŒλ‘œμ»€κ°€ μžˆμŠ΅λ‹ˆλ‹€. 리더가 μ‹€νŒ¨ν•˜λ©΄ νŒ”λ‘œμ›Œκ°€ μžλ™μœΌλ‘œ μŠΉκ²©λ˜μ–΄ μ„œλΉ„μŠ€ 쀑단 없이 λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€.
  2. 컨슈머 μ˜€ν”„μ…‹ 관리 :
    - μ»¨μŠˆλ¨ΈλŠ” μ˜€ν”„μ…‹μ„ μ»€λ°‹ν•˜μ—¬ μžμ‹ μ΄ μ²˜λ¦¬ν•œ λ§ˆμ§€λ§‰ λ©”μ‹œμ§€λ₯Ό Kafka에 κΈ°λ‘ν•©λ‹ˆλ‹€. μž₯μ•  λ°œμƒ μ‹œ λ§ˆμ§€λ§‰μœΌλ‘œ μ²˜λ¦¬ν•œ λ©”μ‹œμ§€ 이후뢀터 λ‹€μ‹œ λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•  수 μžˆμ–΄ 데이터 μœ μ‹€ 을 λ°©μ§€ν•©λ‹ˆλ‹€.
  3. μž¬μ‹œλ„ 둜직 :
    - λ©”μ‹œμ§€ 처리 쀑 λ¬Έμ œκ°€ λ°œμƒν•˜λ©΄ μž¬μ‹œλ„ 둜직 을 κ΅¬ν˜„ν•˜μ—¬ λ©”μ‹œμ§€ 손싀 없이 μ•ˆμ •μ μœΌλ‘œ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
@KafkaListener(topics = "my_topic", groupId = "my_group")
public void consume(String message) {
    try {
        // λ©”μ‹œμ§€ 처리 둜직
        processMessage(message);
    } catch (Exception e) {
        logger.error("Error processing message, retrying...", e);
        // μž¬μ‹œλ„ 둜직
        throw e;
    }
}

 


 

Kafka μŠ€μΌ€μΌλ§ νŠΈλ Œλ“œ 및 톡계

졜근 쑰사에 λ”°λ₯΄λ©΄, Kafkaλ₯Ό μ‚¬μš©ν•˜λŠ” λŒ€κ·œλͺ¨ κΈ°μ—…μ˜ 75% 이상이 νŒŒν‹°μ…”λ‹ κ³Ό 컨슈머 κ·Έλ£Ή 을 톡해 νŠΈλž˜ν”½ 증가에 효과적으둜 λŒ€μ‘ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 특히 볡제 μ „λž΅ 을 μ‚¬μš©ν•œ Kafka ν΄λŸ¬μŠ€ν„°λŠ” μž₯μ•  λ°œμƒ μ‹œμ—λ„ 99.99%의 κ°€μš©μ„± 을 보μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 


 

자주 λ¬»λŠ” 질문 (FAQ)

Q1. Kafkaμ—μ„œ ν”„λ‘œλ“€μ„œμ™€ 컨슈머λ₯Ό μ–΄λ–»κ²Œ ν™•μž₯ν•  수 μžˆλ‚˜μš”?
A1. ν”„λ‘œλ“€μ„œ λŠ” μ—¬λŸ¬ μΈμŠ€ν„΄μŠ€λ‘œ μˆ˜ν‰ ν™•μž₯이 κ°€λŠ₯ν•˜λ©°, 컨슈머 λŠ” 컨슈머 κ·Έλ£Ή 을 톡해 μ—¬λŸ¬ μΈμŠ€ν„΄μŠ€κ°€ λ³‘λ ¬λ‘œ λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ 컨슈머 κ·Έλ£Ή λ‚΄μ—μ„œ 각 μ»¨μŠˆλ¨ΈλŠ” ν• λ‹Ήλœ νŒŒν‹°μ…˜μ„ λ³‘λ ¬λ‘œ μ²˜λ¦¬ν•˜μ—¬ ν™•μž₯성을 높일 수 μžˆμŠ΅λ‹ˆλ‹€.

Q2. νŒŒν‹°μ…”λ‹μ΄ μ€‘μš”ν•œ μ΄μœ λŠ” λ¬΄μ—‡μΈκ°€μš”?
A2. νŒŒν‹°μ…”λ‹ 은 λ©”μ‹œμ§€λ₯Ό μ—¬λŸ¬ νŒŒν‹°μ…˜μœΌλ‘œ λ‚˜λˆ„μ–΄ μ²˜λ¦¬ν•¨μœΌλ‘œμ¨ λΆ€ν•˜ λΆ„μ‚° 을 κ°€λŠ₯ν•˜κ²Œ ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 ν”„λ‘œλ“€μ„œ 와 컨슈머 κ°€ λ™μ‹œμ— 더 λ§Žμ€ λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•  수 있으며, μ‹œμŠ€ν…œμ˜ ν™•μž₯성을 κ·ΉλŒ€ν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Q3. 컨슈머 κ·Έλ£Ήμ—μ„œ νŒŒν‹°μ…˜ 할당은 μ–΄λ–»κ²Œ μ΄λ£¨μ–΄μ§€λ‚˜μš”?
A3. 컨슈머 κ·Έλ£Ή λ‚΄μ˜ 각 μ»¨μŠˆλ¨ΈλŠ” νŒŒν‹°μ…˜ 을 μžλ™μœΌλ‘œ ν• λ‹Ήλ°›μ•„ λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€. 컨슈머 그룹의 크기가 νŒŒν‹°μ…˜ μˆ˜λ³΄λ‹€ 크면 일뢀 μ»¨μŠˆλ¨ΈλŠ” λŒ€κΈ° μƒνƒœκ°€ 될 수 μžˆμœΌλ―€λ‘œ, νŒŒν‹°μ…˜ 수 와 컨슈머 수 λ₯Ό 적절히 μ‘°μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

Q4. Kafka μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ κ³ κ°€μš©μ„±μ„ μ–΄λ–»κ²Œ ν™•λ³΄ν•˜λ‚˜μš”?
A4. Replication Factor λ₯Ό μ„€μ •ν•˜μ—¬ λ©”μ‹œμ§€ λ³΅μ œλ³Έμ„ μ—¬λŸ¬ λΈŒλ‘œμ»€μ— λΆ„μ‚°ν•¨μœΌλ‘œμ¨ κ³ κ°€μš©μ„± 을 확보할 수 μžˆμŠ΅λ‹ˆλ‹€. 브둜컀 쀑 ν•˜λ‚˜κ°€ μž₯μ• λ₯Ό μΌμœΌμΌœλ„, λ‹€λ₯Έ 볡제본이 μžˆλŠ” λΈŒλ‘œμ»€κ°€ 데이터λ₯Ό μ²˜λ¦¬ν•˜κ²Œ λ˜μ–΄ μ„œλΉ„μŠ€ 쀑단 없이 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μš΄μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Q5. Kafkaμ—μ„œ μž₯μ•  λ°œμƒ μ‹œ 데이터λ₯Ό μ–΄λ–»κ²Œ λ³΄ν˜Έν•˜λ‚˜μš”?
A5. KafkaλŠ” 컨슈머 μ˜€ν”„μ…‹ 관리 와 λ©”μ‹œμ§€ 볡제 λ₯Ό 톡해 μž₯μ•  λ°œμƒ μ‹œ 데이터λ₯Ό λ³΄ν˜Έν•©λ‹ˆλ‹€. μ»¨μŠˆλ¨ΈλŠ” μžμ‹ μ΄ μ²˜λ¦¬ν•œ λ©”μ‹œμ§€μ˜ μ˜€ν”„μ…‹μ„ μ €μž₯ ν•˜μ—¬, μž₯μ• κ°€ λ°œμƒν•˜λ”λΌλ„ λ§ˆμ§€λ§‰μœΌλ‘œ μ²˜λ¦¬ν•œ μœ„μΉ˜ 이후뢀터 λ©”μ‹œμ§€λ₯Ό λ‹€μ‹œ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ, Replication Factor λ₯Ό 톡해 λ°μ΄ν„°μ˜ λ³΅μ œλ³Έμ„ μ—¬λŸ¬ λΈŒλ‘œμ»€μ— μ €μž₯ν•˜μ—¬ μž₯μ•  μ‹œ 데이터 μœ μ‹€μ„ 방지할 수 μžˆμŠ΅λ‹ˆλ‹€.

λŒ“κΈ€