λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ“¨ Apache Kafka

[μ•„νŒŒμΉ˜ μΉ΄ν”„μΉ΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ν”„λ‘œκ·Έλž˜λ° with μžλ°”] 4-2μž₯ μΉ΄ν”„μΉ΄ ν”„λ‘œλ“€μ„œ

by GroovyArea 2023. 5. 7.

μΉ΄ν”„μΉ΄ ν”„λ‘œλ“€μ„œ

  • μΉ΄ν”„μΉ΄ ν”„λ‘œλ“€μ„œλŠ” 토픽에 데이터λ₯Ό μ €μž₯ν•˜λŠ” 첫 단계!

acks μ˜΅μ…˜

  • ν”„λ‘œλ“€μ„œμ˜ μ˜΅μ…˜μœΌλ‘œ acks μ˜΅μ…˜
  • ν”„λ‘œλ“€μ„œκ°€ μ „μ†‘ν•œ 데이터λ₯Ό ν΄λŸ¬μŠ€ν„°μ— μ–Όλ§ˆλ‚˜ μ‹ λ’°μ„± 있게 μ €μž₯ν•  지 지정 κ°€λŠ₯
  • μ˜΅μ…˜μ— 따라 μ„±λŠ₯이 λ‹¬λΌμ§ˆ 수 μžˆλ‹€.

acks = 0

  • ν”„λ‘œλ“€μ„œκ°€ 리더 νŒŒν‹°μ…˜μœΌλ‘œ 데이터λ₯Ό μ „μ†‘ν–ˆμ„ λ•Œ 리더 νŒŒν‹°μ…˜μœΌλ‘œ 데이터가 μ €μž₯λ˜μ—ˆλŠ”μ§€ 확인 ν•˜μ§€ μ•ŠλŠ”λ‹€
  • 리더 νŒŒν‹°μ…˜μ€ 데이터가 μ €μž₯된 이후, λͺ‡ 번째 μ˜€ν”„μ…‹μ— μ €μž₯λ˜μ—ˆλŠ”μ§€ return
  • 이 κ²½μš°μ—λŠ” 데이터가 μ €μž₯된 여뢀에 λ”°λ₯Έ 응닡을 받지 μ•ŠμŒ.

  • ν”„λ‘œλ“€μ„œλŠ” 데이터 전솑 μ‹€νŒ¨μ‹œ, μž¬μ‹œλ„ν•  수 있게, retries μ˜΅μ…˜ μ„€μ • κ°€λŠ₯
  • ν•˜μ§€λ§Œ acks = 0 일 경우, 데이터 전솑을 무쑰건 μ„±κ³΅μœΌλ‘œ κ°„μ£Ό, ν•΄λ‹Ή μ˜΅μ…˜μ€ λ¬΄μ˜λ―Έν•˜λ‹€.
  • ν”„λ‘œλ“€μ„œμ™€ 브둜컀 μ‚¬μ΄μ˜ λ„€νŠΈμ›Œν¬ 였λ₯˜λ‚˜ 브둜컀의 이슈 등을 μΈν•˜μ—¬ 데이터가 μœ μ‹€ λ˜λ”λΌλ„, ν”„λ‘œλ“€μ„œλŠ” 리더 νŒŒν‹°μ…˜μœΌλ‘œλΆ€ν„° 응닡 값을 받지 μ•ŠμŒ
    • μ§€μ†μ μœΌλ‘œ λ‹€μŒ 데이터λ₯Ό 보낸닀.
    • 1, -1 일 κ²½μš°λ³΄λ‹€ 데이터 전솑 속도가 훨씬 빠름.
  • 데이터가 일뢀 μœ μ‹€ λ˜μ–΄λ„ ok? => acks = 0

acks = 1

  • ν”„λ‘œλ“€μ„œλŠ” 보낸 데이터가 리더 νŒŒν‹°μ…˜μ— μ •μƒμ μœΌλ‘œ μ μž¬λ˜μ—ˆλŠ”μ§€ 확인
  • μ •μƒμ μœΌλ‘œ μ μž¬λ˜μ§€ μ•Šμ•˜μ„ 경우, 적재될 λ•ŒκΉŒμ§€ μž¬μ‹œλ„
  • μ μž¬λ˜μ—ˆλ”λΌλ„, 데이터 μœ μ‹€ λ°œμƒ κ°€λŠ₯μ„±
    • 볡제 개수λ₯Ό 2개 μ΄μƒμœΌλ‘œ 운영 μ‹œ, νŒ”λ‘œμ›Œ νŒŒν‹°μ…˜μ΄ 리더 νŒŒν‹°μ…˜μœΌλ‘œλΆ€ν„° λ³΅μ œν•˜κΈ° 직전, 리더 νŒŒν‹°μ…˜μ— μžˆλŠ” λΈŒλ‘œμ»€μ— μž₯μ•  λ°œμƒ κ°€λŠ₯
    • λ™κΈ°ν™”λ˜μ§€ λͺ»ν•œ 일뢀 데이터가 μœ μ‹€λ  κ°€λŠ₯성이 μžˆλ‹€.

  • 이 κ²½μš°μ—λŠ”, 리더 νŒŒν‹°μ…˜μ— 데이터가 적재될 λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦° λ’€ 응닡을 λ°›μŒ
  • acks = 0 일 κ²½μš°λ³΄λ‹€ 전솑 속도가 느림.

acks = all || acks = -1

  • ν”„λ‘œλ“€μ„œλŠ” 보낸 데이터가 리더 νŒŒν‹°μ…˜κ³Ό νŒ”λ‘œμ›Œ νŒŒν‹°μ…˜μ— λͺ¨λ‘ 정상 μ μž¬λ˜μ—ˆλŠ”μ§€ 확인
  • λͺ¨λ‘ ν™•μΈν•˜λ―€λ‘œ, λ‹€λ₯Έ μ˜΅μ…˜ 값듀보닀 데이터 전솑 속도가 느림.
  • λͺ¨λ‘ μ μž¬λ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜λ―€λ‘œ, 일뢀 λΈŒλ‘œμ»€μ— μž₯μ• κ°€ λ°œμƒν•΄λ„, μ•ˆμ „ν•˜κ²Œ 데이터λ₯Ό μ „μ†‘ν•˜κ³  μ €μž₯ν•˜λŠ” 것을 보μž₯ κ°€λŠ₯함.

  • acks = all
  • ν† ν”½ λ‹¨μœ„λ‘œ μ„€μ • κ°€λŠ₯ν•œ min.insync.replicas μ˜΅μ…˜ 값에 따라 λ°μ΄ν„°μ˜ μ•ˆμ •μ„±μ΄ 달라짐
  • 이 μ˜΅μ…˜μ€ ν”„λ‘œλ“€μ„œκ°€ 리더, νŒ”λ‘œμ›Œ νŒŒν‹°μ…˜μ— 데이터가 정상 μ μž¬λ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜κΈ° μœ„ν•œ μ΅œμ†Œ ISR 그룹의 νŒŒν‹°μ…˜ 개수
  • 예둜, 1 이라면, ISR 쀑 μ΅œμ†Œ 1개 μ΄μƒμ˜ νŒŒν‹°μ…˜μ— 데이터가 μ μž¬λ˜μ—ˆμŒμ„ 확인 ν•˜λŠ” 것.


  • μƒμš© ν™˜κ²½μ—μ„œ 일반적으둜 브둜컀λ₯Ό 3λŒ€ μ΄μƒμœΌλ‘œ λ¬Άμ–΄ ν΄λŸ¬μŠ€ν„°λ₯Ό 운영
  • 이 점을 κ³ λ €ν•˜μ—¬ 데이터λ₯Ό μ•ˆμ •μ μœΌλ‘œ 보내고 μ‹ΆμœΌλ©΄, ν† ν”½μ˜ μ΅œλŒ€ 개수 = 3, min.insync,replicas = 2 μ„€μ •
  • acks = all 둜 μ„€μ •ν•΄λ³΄μž~

λ©±λ“±μ„± (idempotence) ν”„λ‘œλ“€μ„œ

  • λ©±λ“±μ„± ν”„λ‘œλ“€μ„œ = 동일 데이터λ₯Ό μ—¬λŸ¬ 번 전솑해도, μΉ΄ν”„μΉ΄ ν΄λŸ¬μŠ€ν„°μ— 단 ν•œλ²ˆ μ €μž₯
  • κΈ°λ³Έ ν”„λ‘œλ“€μ„œμ˜ λ™μž‘ 방식은 At Least Once λ₯Ό 지원
  • 이 방식은, ν”„λ‘œλ“€μ„œκ°€ ν΄λŸ¬μŠ€ν„°μ— 데이터λ₯Ό μ „μ†‘ν•˜μ—¬ μ €μž₯ν•  λ•Œ, 적어도 ν•œλ²ˆ 이상 데이터λ₯Ό μ μž¬ν•  수 있고, 데이터가 μœ μ‹€λ˜μ§€ μ•ŠμŒμ„ μΌμ»«λŠ”λ‹€.
  • λ‘λ²ˆ 이상 적재 κ°€λŠ₯μ„± => λ°μ΄ν„°μ˜ 쀑볡 λ°œμƒ

  • enable.idempotence μ˜΅μ…˜ κ°’ true μ„€μ •μœΌλ‘œ μ‚¬μš© κ°€λŠ₯
  • κΈ°λ³Έ ν”„λ‘œλ“€μ„œμ™€ λ‹€λ₯΄κ²Œ, 브둜컀둜 데이터 전달 μ‹œ, ν”„λ‘œλ“€μ„œ PID(Producer unique ID) 와 μ‹œν€€μŠ€ λ„˜λ²„ (sequence number) 둜 ν•¨κ»˜ 전달
  • λΈŒλ‘œμ»€λŠ” PID, Sequence Number λ₯Ό 확인 ν›„, 동일 λ©”μ‹œμ§€μ˜ 적재 μš”μ²­μ΄ 와도, 단 ν•œλ²ˆλ§Œ 데이터λ₯Ό μ μž¬ν•¨.
    • ν”„λ‘œλ“€μ„œμ˜ λ°μ΄ν„°λŠ” μ •ν™•νžˆ ν•œλ²ˆ λΈŒλ‘œμ»€μ— μ μž¬λ˜λ„λ‘ λ™μž‘ (exactly once)


  • μ•žμ„œ λ§ν–ˆλ‹€μ‹Άμ΄, λ™μΌν•œ μ„Έμ…˜μ—μ„œλ§Œ μ •ν™•νžˆ ν•œλ²ˆ 전달을 보μž₯
  • μ„Έμ…˜ = PID 의 생λͺ…μ£ΌκΈ°
  • λ©±λ“±μ„± ν”„λ‘œλ“€μ„œλ‘œ λ™μž‘ν•˜λŠ” ν”„λ‘œλ“€μ„œ 앱에 λ¬Έμ œκ°€ λ°œμƒν•˜μ—¬ μ’…λ£Œλ˜κ³ , μž¬μ‹œμž‘ν•˜λ©΄ PID κ°€ 달라짐!
  • 동일 데이터λ₯Ό 보내더라도, PID κ°€ λ‹€λ₯΄λ―€λ‘œ, 브둜컀 μž…μž₯μ—μ„œ λ‹€λ₯Έ ν”„λ‘œλ“€μ„œ 앱이 λ‹€λ₯Έ 데이터λ₯Ό λ³΄λƒˆλ‹€κ³  νŒλ‹¨, μž₯μ• κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ” μƒν™©μ—μ„œλ§Œ exactly once λ₯Ό 보μž₯ν•œλ‹€λŠ” 점을 κ³ λ €ν•˜μž.

  • enable.idempotence λ₯Ό true 둜 μ„€μ •ν•˜λ©΄ μ •ν™•νžˆ ν•œλ²ˆ μ μž¬λ˜λŠ” 둜직이 μ„±λ¦½λ˜κΈ° μœ„ν•΄ ν”„λ‘œλ“€μ„œμ˜ 일뢀 μ˜΅μ…˜λ“€μ΄ κ°•μ œλ‘œ μ„€μ •
  • ν”„λ‘œλ“€μ„œμ˜ 데이터 전솑 횟수λ₯Ό μ •ν•˜λŠ” retries λŠ” 기본적으둜 Integer.MAX_VALUE κ°€ 됨, acks = all 둜 μ„€μ •
  • μ΄μœ λŠ”, ν”„λ‘œλ“€μ„œκ°€ 적어도 ν•œ 번 이상 λΈŒλ‘œμ»€μ— 데이터λ₯Ό λ³΄λ‚΄λ―€λ‘œ, 단 ν•œ 번만 데이터가 μ μž¬λ˜λŠ” 것을 보μž₯ν•˜κΈ° μœ„ν•¨μ΄λ‹€.

νŠΈλžœμž­μ…˜ (transaction) ν”„λ‘œλ“€μ„œ

  • μΉ΄ν”„μΉ΄ νŠΈλžœμž­μ…˜ ν”„λ‘œλ“€μ„œλŠ” λ‹€μˆ˜μ˜ νŒŒν‹°μ…˜μ— 데이터λ₯Ό μ €μž₯ν•  경우, λͺ¨λ“  데이터에 λŒ€ν•΄ λ™μΌν•œ μ›μžμ„± (atomic) 을 λ§Œμ‘±ν•˜κΈ° μœ„ν•΄ μ‚¬μš©
  • 이 μ˜λ―ΈλŠ”, λ‹€μˆ˜μ˜ 데이터λ₯Ό 동일 νŠΈλžœμž­μ…˜μœΌλ‘œ 묢음, 전체 데이터λ₯Ό μ²˜λ¦¬ν•˜κ±°λ‚˜, μ²˜λ¦¬ν•˜μ§€ μ•Šλ„λ‘ ν•˜λŠ” κ²ƒμž„
  • μ»¨μŠˆλ¨ΈλŠ” 기본적으둜 ν”„λ‘œλ“€μ„œκ°€ λ³΄λ‚΄λŠ” 데이터λ₯Ό νŒŒν‹°μ…˜μ— μŒ“μ΄λŠ” λŒ€λ‘œ λͺ¨λ‘ κ°€μ Έκ°€μ„œ μ²˜λ¦¬ν•¨.
  • νŠΈλžœμž­μ…˜μœΌλ‘œ 묢인 데이터λ₯Ό κ°€μ Έκ°ˆ λ•ŒλŠ” λ‹€λ₯΄κ²Œ λ™μž‘ν•˜λ„λ‘ μ„€μ • κ°€λŠ₯

  • νŠΈλžœμž­μ…˜ ν”„λ‘œλ“€μ„œλ₯Ό μ‚¬μš©ν•˜λ €λ©΄ enable.idempotence = true μ„€μ •
  • transactional.id λ₯Ό μž„μ˜ string κ°’μœΌλ‘œ μ •μ˜
  • 컨슈머의 isolation.level 을 read_committed 둜 μ„€μ •ν•˜λ©΄, ν”„λ‘œλ“€μ„œμ™€ μ»¨μŠˆλ¨ΈλŠ” νŠΈλžœμž­μ…˜ 처리 된 λ°μ΄ν„°λ§Œ μ“°κ³  μ½λŠ”λ‹€.

  • νŠΈλžœμž­μ…˜μ€ νŒŒν‹°μ…˜μ˜ λ ˆμ½”λ“œλ‘œ ꡬ뢄 됨.
  • νŠΈλžœμž­μ…˜ ν”„λ‘œλ“€μ„œλŠ” μ‚¬μš©μžκ°€ 보낸 데이터λ₯Ό λ ˆμ½”λ“œλ‘œ νŒŒν‹°μ…˜μ— μ €μž₯
  • νŠΈλžœμž­μ…˜μ˜ μ‹œμž‘κ³Ό 끝을 ν‘œν˜„ν•˜λŠ” λ ˆμ½”λ“œλ₯Ό ν•œ 개 더 보냄.
  • νŠΈλžœμž­μ…˜ μ»¨μŠˆλ¨ΈλŠ” νŒŒν‹°μ…˜μ— μ €μž₯된 νŠΈλžœμž­μ…˜ λ ˆμ½”λ“œλ₯Ό 보고, μ™„λ£Œ 됨을 확인 ν›„ 데이터λ₯Ό κ°€μ Έκ°„λ‹€.
  • λ§Œμ•½ 데이터가 μ‘΄μž¬ν•˜κ³  νŠΈλžœμž­μ…˜ λ ˆμ½”λ“œκ°€ μ—†μœΌλ©΄, μ™„λ£Œλ˜μ§€ μ•Šμ•˜μŒμœΌλ‘œ νŒλ‹¨, 데이터λ₯Ό 가져가지 μ•ŠμŒ!

λ°˜μ‘ν˜•