LabHub
배우기 러닝패스 코스

注文が二度届き、一度は消えた

同じキーは同じパーティションへ — ログを実際に操作する

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

이 실습은 VM 에서 돕니다

우분투 VM 에 Apache Kafka 4.3.1 이 KRaft 단일 노드로 떠 있습니다(systemd kafka 서비스, localhost:9092). /opt/kafka/bin 이 PATH 에 있어 kafka-topics.sh 같은 도구를 바로 쓸 수 있습니다. 처음 뜨는 데 4분쯤 걸립니다.

목표

토픽을 만들고 키가 있는 이벤트를 넣어, 같은 키가 같은 파티션으로 가고 파티션 안에서 순서가 지켜지는 것을 봅니다. 컨슈머 그룹의 오프셋과 지연(lag)을 읽고, 두 그룹이 서로 독립적으로 읽는 것을 확인한 뒤, 파티션 수를 늘리면 키 배치가 바뀌는 것을 직접 관찰합니다.

왜 중요한가

"주문이 두 번 도착했고 한 번은 사라졌다" 는 사고를 읽으려면 먼저 Kafka 가 무엇을 약속하고 무엇을 약속하지 않는지 알아야 합니다. Kafka 는 파티션 안의 순서만 약속합니다. 같은 키가 같은 파티션으로 가기 때문에 주문 하나의 이벤트 순서는 지켜지지만, 다른 주문끼리는 아닙니다. 그리고 소비된 메시지는 지워지지 않습니다 — 컨슈머 그룹마다 "어디까지 읽었나" 하는 정수 하나(오프셋)를 따로 갖기 때문에, 한 그룹이 놓친 것을 다른 그룹은 처음부터 다시 읽을 수 있습니다. 이 두 가지가 뒤 모듈의 중복·유실 이야기의 바탕입니다.

단계

  1. 토픽 orders파티션 3개로 만드세요.
  2. /root/kafka/orders.txt 의 아홉 줄(키:값 형식)을 kafka-console-producer.sh키를 파싱해서 넣으세요. 여러 파티션에 나뉘어 들어가야 합니다.
  3. 파티션·오프셋·키가 보이게 처음부터 전부 읽어 /root/kafka/keyed.txt 에 저장하세요. 같은 키는 한 파티션에만 있어야 합니다.
  4. 컨슈머 그룹 order-svc 로 처음부터 아홉 건을 읽고, 그 그룹을 describe 한 결과를 /root/kafka/group.txt 에 저장하세요.
  5. /root/kafka/more.txt 의 세 줄을 더 넣고(읽지는 말고) order-svc 를 다시 describe 해 /root/kafka/lag.txt 에 저장하세요. LAG 이 보여야 합니다.
  6. 두 번째 그룹 analytics 로 처음부터 열두 건을 읽으세요. order-svc 의 오프셋은 그대로여야 합니다.
  7. orders파티션 6개로 늘리고 order-1:refunded 를 넣은 뒤 처음부터 읽어 /root/kafka/repartition.txt 에 저장하세요. 그리고 /root/kafka/repartition-report.txtpartitions_before=3, partitions_after=6, order1_before=<3단계에서 order-1 이 있던 파티션>, order1_after=<refunded 가 들어간 파티션> 네 줄을 쓰세요.

참고

파티션 3개짜리 토픽

토픽 orders파티션 3개로 만드세요.

kafka-topics.sh --bootstrap-server localhost:9092 --create --topic ... --partitions 3. 만든 뒤 --describe 로 PartitionCount 를 확인하세요.

키가 있는 이벤트를 넣는다

/root/kafka/orders.txt 의 아홉 줄(키:값 형식)을 kafka-console-producer.sh키를 파싱해서 넣으세요. 여러 파티션에 나뉘어 들어가야 합니다.

--reader-property parse.key=true --reader-property key.separator=: 를 주고 파일을 표준 입력으로 넘기세요. 키를 파싱하지 않으면 한 줄 전체가 값이 되고 키가 null 이라 파티션이 키와 무관하게 정해집니다.

파티션과 오프셋을 눈으로 본다

파티션·오프셋·키가 보이게 처음부터 전부 읽어 /root/kafka/keyed.txt 에 저장하세요. 같은 키는 한 파티션에만 있어야 합니다.

--from-beginning --max-messages 9 --timeout-ms 8000--formatter-property print.key=true --formatter-property print.partition=true --formatter-property print.offset=true 를 더하고 출력을 파일로 보내세요. 파티션끼리는 순서가 섞여 나오지만 한 파티션 안에서는 오프셋이 오릅니다.

컨슈머 그룹의 오프셋

컨슈머 그룹 order-svc 로 처음부터 아홉 건을 읽고, 그 그룹을 describe 한 결과를 /root/kafka/group.txt 에 저장하세요.

--group order-svc 를 주면 읽은 위치가 브로커에 커밋됩니다. 끝난 뒤 kafka-consumer-groups.sh --describe --group order-svc 의 CURRENT-OFFSET 이 파티션마다 LOG-END-OFFSET 과 같고 LAG 이 0 이어야 합니다.

읽지 않으면 지연이 쌓인다

/root/kafka/more.txt 의 세 줄을 더 넣고(읽지는 말고) order-svc 를 다시 describe 해 /root/kafka/lag.txt 에 저장하세요. LAG 이 보여야 합니다.

2단계와 같은 방법으로 넣되 컨슈머는 돌리지 마세요. LOG-END-OFFSET 은 오르고 CURRENT-OFFSET 은 그대로라 그 차이가 LAG 입니다.

그룹은 서로 독립이다

두 번째 그룹 analytics 로 처음부터 열두 건을 읽으세요. order-svc 의 오프셋은 그대로여야 합니다.

--group analytics --from-beginning --max-messages 12. 소비된 메시지는 지워지지 않으므로 새 그룹은 처음부터 전부 읽을 수 있고, 다른 그룹의 오프셋에는 아무 영향이 없습니다.

파티션을 늘리면 키 배치가 바뀐다

orders파티션 6개로 늘리고 order-1:refunded 를 넣은 뒤 처음부터 읽어 /root/kafka/repartition.txt 에 저장하세요. 그리고 /root/kafka/repartition-report.txtpartitions_before=3, partitions_after=6, order1_before=<3단계에서 order-1 이 있던 파티션>, order1_after=<refunded 가 들어간 파티션> 네 줄을 쓰세요.

--alter --topic orders --partitions 6 뒤에 키 파싱으로 한 줄을 넣고, 3단계처럼 --max-messages 13 으로 읽으세요. 운영 문서가 말하듯 기본 파티셔너는 hash(key) % 파티션 수 라서 파티션 수가 바뀌면 같은 키가 다른 파티션으로 갈 수 있고, 기존 데이터는 옮겨지지 않습니다.