์นดํ”„์นด๋Š” ์–ด๋–ป๊ฒŒ ํ˜„์‹ค์ด ๋˜์—ˆ๋‚˜

์นดํ”„์นด๋Š” ์–ด๋–ป๊ฒŒ ํ˜„์‹ค์ด ๋˜์—ˆ๋‚˜

ํ—ค์ด ํ•˜๋ธŒ๋ฅด!

์ €๋Š” Tinkoff ํŒ€์—์„œ ์ผํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์ด ํŒ€์€ ์ž์ฒด ์•Œ๋ฆผ ์„ผํ„ฐ๋ฅผ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์ฃผ๋กœ Spring boot๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Java๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ํ”„๋กœ์ ํŠธ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ์ˆ ์  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋Š” ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค๋ฅผ ํ†ตํ•ด ๋น„๋™๊ธฐ์ ์œผ๋กœ ์„œ๋กœ ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ „์—๋Š” IBM MQ๋ฅผ ๋ธŒ๋กœ์ปค๋กœ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์ด๋Š” ๋” ์ด์ƒ ๋ถ€ํ•˜๋ฅผ ๊ฐ๋‹นํ•  ์ˆ˜ ์—†์—ˆ์ง€๋งŒ ๋™์‹œ์— ๋†’์€ ์ „๋‹ฌ ๋ณด์žฅ์€ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

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

๋ณด์žฅ๋œ ๋ฐฐ์†ก ๋ฐ ๊ธฐํƒ€

์•„๋ž˜์— ์„ค๋ช…๋œ ์„ค์ •์€ ๊ธฐ๋ณธ ์—ฐ๊ฒฐ ์„ค์ •์œผ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ๋Ÿฌ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋จผ์ € ๋””๋ฒ„๊น…์„ ์šฉ์ดํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ๊ฐ€์ง€ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค ํด๋ผ์ด์–ธํŠธ.์•„์ด๋”” ์ƒ์‚ฐ์ž์™€ ์†Œ๋น„์ž๋ฅผ ์œ„ํ•ด. ์ฒ˜์Œ์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฆ„์„ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฉฐ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์—ฌ๋Ÿฌ Consumer๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ด๋ฅผ ๋™์ผํ•œ client.id๋กœ ์„ค์ •ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

org.apache.kafka.common.utils.AppInfoParser โ€” Error registering AppInfo mbean javax.management.InstanceAlreadyExistsException: kafka.consumer:type=app-info,id=kafka.test-0

Kafka๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ JMX๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฆ„๊ณผ ์ฃผ์ œ ์ด๋ฆ„ ๋“ฑ์„ ์กฐํ•ฉํ•˜์—ฌ client.id ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ๊ฒฐ๊ณผ๋Š” ๋ช…๋ น ์ถœ๋ ฅ์—์„œ โ€‹โ€‹ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์นดํ”„์นด-์†Œ๋น„์ž-๊ทธ๋ฃน Confluent ์œ ํ‹ธ๋ฆฌํ‹ฐ์—์„œ:

์นดํ”„์นด๋Š” ์–ด๋–ป๊ฒŒ ํ˜„์‹ค์ด ๋˜์—ˆ๋‚˜

์ด์ œ ๋ณด์žฅ๋œ ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. Kafka Producer์—๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. Acks์ด๋ฅผ ํ†ตํ•ด ํด๋Ÿฌ์Šคํ„ฐ ๋ฆฌ๋”๊ฐ€ ๋ฉ”์‹œ์ง€๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ๋‹ค๊ณ  ๊ฐ„์ฃผํ•ด์•ผ ํ•˜๋Š” ํ™•์ธ ํšŸ์ˆ˜๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋‹ค์Œ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • 0 - ํ™•์ธ์ด ๊ณ ๋ ค๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • 1์€ ๊ธฐ๋ณธ ๋งค๊ฐœ๋ณ€์ˆ˜์ด๊ณ , 1๊ฐœ์˜ ๋ณต์ œ๋ณธ๋งŒ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
  • -1 โ€” ๋ชจ๋“  ๋™๊ธฐํ™”๋œ ๋ณต์ œ๋ณธ์˜ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(ํด๋Ÿฌ์Šคํ„ฐ ์„ค์ •) min.insync.replicas).

๋‚˜์—ด๋œ ๊ฐ’์„ ๋ณด๋ฉด acks๊ฐ€ -1์ผ ๋•Œ ๋ฉ”์‹œ์ง€๊ฐ€ ์†์‹ค๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ๋ณด์žฅ์ด ์ œ๊ณต๋œ๋‹ค๋Š” ๊ฒƒ์ด ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ ๋ชจ๋‘ ์•Œ๋‹ค์‹œํ”ผ, ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์€ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ผ์‹œ์ ์ธ ์‹คํŒจ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด Kafka Producer๋Š” ๋‹ค์Œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์žฌ์‹œ๋„์ด๋ฅผ ํ†ตํ•ด ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฐ๋‹ฌ.์‹œ๊ฐ„ ์ดˆ๊ณผ.ms. retries ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ธฐ๋ณธ๊ฐ’์€ Integer.MAX_VALUE(2147483647)์ด๋ฏ€๋กœ delivery.timeout.ms๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ฉ”์‹œ์ง€ ์žฌ์ „์†ก ํšŸ์ˆ˜๋ฅผ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ •ํ™•ํžˆ ํ•œ ๋ฒˆ ๋ฐฐ๋‹ฌ๋กœ ์ „ํ™˜

๋‚˜์—ด๋œ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋ฉด ์ œ์ž‘์ž๊ฐ€ ๋†’์€ ๋ณด์žฅ์„ฑ์„ ๊ฐ–์ถ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ Kafka ํ† ํ”ฝ์— ๋‹จ ํ•˜๋‚˜์˜ ๋ฉ”์‹œ์ง€ ์‚ฌ๋ณธ๋งŒ ๊ธฐ๋ก๋˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ์—๋Š” Producer์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. enable.idempotence ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ๋ฉฑ๋“ฑ์„ฑ์€ ๋‹จ์ผ ์ฃผ์ œ์˜ ํŠน์ • ํŒŒํ‹ฐ์…˜์— ๋‹จ ํ•˜๋‚˜์˜ ๋ฉ”์‹œ์ง€๋งŒ ๊ธฐ๋ก๋จ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฉฑ๋“ฑ์„ฑ์„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์ „์ œ ์กฐ๊ฑด์€ ๊ฐ’์ž…๋‹ˆ๋‹ค. acks = all, ์žฌ์‹œ๋„ > 0, ์—ฐ๊ฒฐ๋‹น ์ตœ๋Œ€ ๋น„ํ–‰ ์ค‘ ์š”์ฒญ ์ˆ˜ โ‰ค 5. ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๋Ÿฌํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์œ„์— ์ง€์ •๋œ ๊ฐ’์ด ์ž๋™์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

๋ฉฑ๋“ฑ์„ฑ์ด ๊ตฌ์„ฑ๋˜๋ฉด ํ•ญ์ƒ ๋™์ผํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ๋™์ผํ•œ ํŒŒํ‹ฐ์…˜์— ์ €์žฅ๋˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์€ Producer์—์„œ partitioner.class ํ‚ค์™€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ด์‡ ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ ๋ฐฐ์†ก๋งˆ๋‹ค ๋™์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์›๋ณธ ๋ฉ”์‹œ์ง€์˜ ๋น„์ฆˆ๋‹ˆ์Šค ์‹๋ณ„์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. partitioner.class ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ธฐ๋ณธ๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํŒŒํ‹ฐ์…”๋„ˆ. ์ด ๊ธฐ๋ณธ ๋ถ„ํ•  ์ „๋žต์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

  • ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ๋•Œ ํŒŒํ‹ฐ์…˜์ด ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •๋˜๋ฉด ํ•ด๋‹น ํŒŒํ‹ฐ์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ํŒŒํ‹ฐ์…˜์ด ์ง€์ •๋˜์ง€ ์•Š์•˜์ง€๋งŒ ํ‚ค๊ฐ€ ์ง€์ •๋œ ๊ฒฝ์šฐ ํ‚ค์˜ ํ•ด์‹œ๋กœ ํŒŒํ‹ฐ์…˜์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  • ํŒŒํ‹ฐ์…˜๊ณผ ํ‚ค๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์œผ๋ฉด ํŒŒํ‹ฐ์…˜์„ ํ•˜๋‚˜์”ฉ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค(๋ผ์šด๋“œ ๋กœ๋นˆ).

๋˜ํ•œ ํ‚ค์™€ ๋ฉฑ๋“ฑ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ๋‹น ์ตœ๋Œ€ ๋น„ํ–‰ ์ค‘ ์š”์ฒญ ์ˆ˜ = 1 ์†Œ๋น„์ž์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•ด ์ค๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ์— ์•ก์„ธ์Šค ์ œ์–ด๊ฐ€ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ ํ•ด๋‹น ์ฃผ์ œ์— ๋Œ€ํ•œ ๋ฉฑ๋“ฑ ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์ ๋„ ๊ธฐ์–ตํ•ด ๋‘๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๊ฐ‘์ž๊ธฐ ํ‚ค์— ์˜ํ•œ ๋ฉฑ๋“ฑ ์ „์†ก ๊ธฐ๋Šฅ์ด ๋ถ€์กฑํ•ด์ง€๊ฑฐ๋‚˜ ์ƒ์‚ฐ์ž ์ธก์˜ ๋กœ์ง์ด ์„œ๋กœ ๋‹ค๋ฅธ ํŒŒํ‹ฐ์…˜ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ํŠธ๋žœ์žญ์…˜์ด ํ•ด๊ฒฐ์ฑ…์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ฒด์ธ ํŠธ๋žœ์žญ์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด Kafka์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ ˆ์ฝ”๋“œ์™€ ์กฐ๊ฑด๋ถ€๋กœ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์‚ฐ์ž์—๊ฒŒ ํŠธ๋žœ์žญ์…˜ ์ „์†ก์„ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด ๋ฉฑ๋“ฑ์„ฑ์„ ๊ฐ€์ ธ์•ผ ํ•˜๋ฉฐ ์ถ”๊ฐ€๋กœ ๋‹ค์Œ์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. transactional.id. Kafka ํด๋Ÿฌ์Šคํ„ฐ์— ์•ก์„ธ์Šค ์ œ์–ด๊ฐ€ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ ๋ฉฑ๋“ฑ ์“ฐ๊ธฐ์™€ ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์“ฐ๊ธฐ์—๋Š” ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ํ•„์š”ํ•˜๋ฉฐ, ์ด ๊ถŒํ•œ์€ transactional.id์— ์ €์žฅ๋œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งˆ์Šคํฌ๋ฅผ ํ†ตํ•ด ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณต์‹์ ์œผ๋กœ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฆ„๊ณผ ๊ฐ™์€ ๋ชจ๋“  ๋ฌธ์ž์—ด์„ ํŠธ๋žœ์žญ์…˜ ์‹๋ณ„์ž๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋™์ผํ•œ transactional.id๋กœ ๋™์ผํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹œ์ž‘ํ•˜๋ฉด Kafka๊ฐ€ ์ฒ˜์Œ ์‹คํ–‰ํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ข€๋น„ ํ”„๋กœ์„ธ์Šค๋กœ ๊ฐ„์ฃผํ•˜์—ฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด์„œ ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค.

org.apache.kafka.common.errors.ProducerFencedException: Producer attempted an operation with an old epoch. Either there is a newer producer with the same transactionalId, or the producer's transaction has been expired by the broker.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ ์–ป์€ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฆ„์— ์ ‘๋ฏธ์‚ฌ๋กœ ๋ถ™์ž…๋‹ˆ๋‹ค.

ํ”„๋กœ๋“€์„œ๋Š” ๊ตฌ์„ฑ๋˜์—ˆ์ง€๋งŒ, Kafka์˜ ํŠธ๋žœ์žญ์…˜์€ ๋ฉ”์‹œ์ง€ ๋ฒ”์œ„๋งŒ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ฑฐ๋ž˜ ์ƒํƒœ์™€ ๊ด€๊ณ„์—†์ด ๋ฉ”์‹œ์ง€๋Š” ์ฆ‰์‹œ ์ฃผ์ œ๋กœ ์ „์†ก๋˜์ง€๋งŒ ์ถ”๊ฐ€์ ์ธ ์‹œ์Šคํ…œ ์†์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ์†Œ๋น„์ž์—๊ฒŒ ๋ฏธ๋ฆฌ ์ฝํžˆ์ง€ ์•Š๋„๋ก ํ•˜๋ ค๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ read_committed ๊ฐ’์œผ๋กœ. ์ด๋Ÿฌํ•œ ์†Œ๋น„์ž๋Š” ์ด์ „๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋น„ํŠธ๋žœ์žญ์…˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ปค๋ฐ‹ ์ดํ›„์—๋งŒ ํŠธ๋žœ์žญ์…˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์œ„์— ๋‚˜์—ด๋œ ๋ชจ๋“  ์„ค์ •์„ ์™„๋ฃŒํ–ˆ๋‹ค๋ฉด, ์ •ํ™•ํžˆ ํ•œ ๋ฒˆ ๋ฐฐ์†ก์ด ์„ค์ •๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ถ•ํ•˜ํ•ด์š”!

ํ•˜์ง€๋งŒ ํ•œ ๊ฐ€์ง€ ๋” ์ค‘์š”ํ•œ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์—์„œ ๊ตฌ์„ฑํ•œ Transactional.id๋Š” ์‹ค์ œ๋กœ๋Š” ํŠธ๋žœ์žญ์…˜ ์ ‘๋‘์‚ฌ์ž…๋‹ˆ๋‹ค. ๊ฑฐ๋ž˜ ๊ด€๋ฆฌ์ž์— ์ผ๋ จ๋ฒˆํ˜ธ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ˆ˜์‹ ๋œ ์‹๋ณ„์ž๋Š” ๋‹ค์Œ์— ๋ฐœ๊ธ‰๋ฉ๋‹ˆ๋‹ค. transactional.id.expiration.msKafka ํด๋Ÿฌ์Šคํ„ฐ์— ๊ตฌ์„ฑ๋˜๊ณ  ๊ธฐ๋ณธ๊ฐ’์€ "7์ผ"์ž…๋‹ˆ๋‹ค. ์ด ์‹œ๊ฐ„ ๋™์•ˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•˜์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ ๋‹ค์Œ ๊ฑฐ๋ž˜๋ฅผ ๋ณด๋‚ด๋ ค๊ณ  ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. InvalidPidMappingException. ์ดํ›„, ๊ฑฐ๋ž˜ ์กฐ์ •์ž๋Š” ๋‹ค์Œ ๊ฑฐ๋ž˜์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ์ผ๋ จ๋ฒˆํ˜ธ๋ฅผ ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ InvalidPidMappingException์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์œผ๋ฉด ๋ฉ”์‹œ์ง€๊ฐ€ ์†์‹ค๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ฉ๊ณ„ ๋Œ€์‹ 

๋ณด์‹œ๋‹ค์‹œํ”ผ, ๋‹จ์ˆœํžˆ ์นดํ”„์นด์— ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ์„ ํƒํ•ด์•ผ ํ•˜๋ฉฐ, ๋น ๋ฅธ ๋ณ€๊ฒฝ์— ๋Œ€๋น„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ์ •ํ™•ํžˆ ํ•œ ๋ฒˆ ์ „๋‹ฌ ์„ค์ •์„ ์ž์„ธํžˆ ๋ณด์—ฌ๋“œ๋ฆฌ๊ณ , ์šฐ๋ฆฌ๊ฐ€ ๊ฒช์€ ๋ช‡ ๊ฐ€์ง€ client.id์™€ transactional.id ๊ตฌ์„ฑ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ณ ์ž ํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ์ƒ์‚ฐ์ž ๋ฐ ์†Œ๋น„์ž ์„ค์ •์— ๋Œ€ํ•œ ์š”์•ฝ์ž…๋‹ˆ๋‹ค.

ํ”„๋กœ๋“€์„œ :

  1. acks = ๋ชจ๋‘
  2. ์žฌ์‹œ๋„ > 0
  3. enable.idempotence = true
  4. ์—ฐ๊ฒฐ๋‹น ์ตœ๋Œ€ ๋น„ํ–‰ ์ค‘ ์š”์ฒญ ์ˆ˜ โ‰ค 5(1 - ์ฃผ๋ฌธ๋œ ์ „์†ก์˜ ๊ฒฝ์šฐ)
  5. transactional.id = ${application-name}-${hostname}

์†Œ๋น„์ž:

  1. ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ = ์ฝ๊ธฐ ์ปค๋ฐ‹๋จ

ํ–ฅํ›„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์˜ค๋ฅ˜๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด, ์šฐ๋ฆฌ๋Š” ์Šคํ”„๋ง ๊ตฌ์„ฑ์— ์ž์ฒด ๋ž˜ํผ๋ฅผ ๋งŒ๋“ค์—ˆ์œผ๋ฉฐ, ์—ฌ๊ธฐ์— ๋‚˜์—ด๋œ ์ผ๋ถ€ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ์ด๋ฏธ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ์ž์œจ ํ•™์Šต์„ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ž๋ฃŒ์ž…๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€