-
Kafka 클러스터 메세지 발행 및 문제 해결Kafka 2021. 10. 4. 01:46반응형
1) 서론
단순 공부 및 테스트 위해 local 환경에서 broker 4 + zookeeper 3개의 서버를 사용합니다. 깊이 있는 설정은 배제하고, 전체적인 흐름 파악에 집중했습니다.
이 글에서는 카프카 클러스터의 설정 방법은 설명하지 않습니다. 궁금하신 분들은 아래 글을 참고해주세요.
전체적인 구조입니다.
- 꼭 8082 포트가 controller가 되는건 아닙니다. 단순 예시입니다.
2) 설정
최소한의 설정만 합니다.
producer / consumer.properties (동일)
// 연결할 broker 주소들 bootstrap.servers=localhost:8081,localhost:8082,localhost:8083,localhost:8084
- 메시지를 주고받을 broker들의 주소만 연결해줍니다
3) 바로 Test!
사실 클러스터 구성을 했다면 producer, consumer는 별게 없습니다. 그냥 연결해서, 메시지 보내면 됩니다.
// create topic kafka-topics --create (연결) --zookeeper localhost:2181,localhost:2182,localhost:2183 (연결) --replication-factor 4 --partitions 10 --topic test
- test 토픽 만듭니다
- broker 4개를 사용하기 때문에, replication-factor 4 필요합니다
// producer kafka-console-producer (연결) --broker-list localhost:8081,localhost:8082,localhost:8083,localhost:8084 (연결) --topic test
- broker 4개에 모두 연결해야 합니다
// consuemr kafka-console-consumer --bootstrap-server (연결) localhost:8081,localhost:8082,localhost:8083,localhost:8084 (연결) --topic test
- 마찬가지로 4개의 broker 모두를 연결해야 합니다
// producer >Hello >World // consumer Hello World
- producer와 consumer가 메시지를 잘 주고받습니다
4) 1번 broker 장애 발생
장애 상황을 가정하여, 강제로 1번 broker를 종료합니다.
Topic: test2 TopicId: KZQqCJ6VSiipttfWNj9YLw PartitionCount: 10 ReplicationFactor: 4 Configs: Topic: test2 Partition: 0 Leader: 3 Replicas: 3,2,4,1 Isr: 3,2,4 Topic: test2 Partition: 1 Leader: 4 Replicas: 4,3,1,2 Isr: 4,3,2 Topic: test2 Partition: 2 Leader: 4 Replicas: 1,4,2,3 Isr: 4,2,3 Topic: test2 Partition: 3 Leader: 2 Replicas: 2,1,3,4 Isr: 2,3,4 Topic: test2 Partition: 4 Leader: 3 Replicas: 3,4,1,2 Isr: 3,4,2 ... 생략
- 1번 broker가 종료되어 새로운 리더 선출, ISR 그룹 퇴출이 되었습니다
// producer >first broker is failed // consumer first broker is failed
- 1번 broker가 종료됐지만, 여전히 메시지 전달에 문제없습니다
여기서 kafka의 장점을 볼 수 있습니다. 장애 발생 시 zookeeper가 controller borker에 알림을 주고, controller broker가 새로운 리더를 뽑아, 데이터 유실을 방지하고 메시지 큐의 안정성을 보장합니다.
5) 고려될 추가 설정
5. 1) producer
buffer.memory
- broker에 전송 전 producer가 메시지를 모아두는 buffer memory
- 한 번에 큰 메세지 혹은 메시지를 보내는 것보다 받는 것이 빠르다면, 사이즈 증가 고려
- max.blocks.ms 설정으로 send() 메서드 block 후 memory 여유까지 대기 가능
batch.size
- batch 사이즈를 조절하여, 한번에 보낼 양 결정
- 빈번한 네트워크 요청 횟수 줄여, 성능 향상 가능
- 하지만 batch 사이즈 증가 시 buffer memory 증가 고려
5. 2) consumer
fetch.min.bytes
- consumer가 return 할 최소의 크기
- 해당 크기보다 작다면, 보내지 않음
- batch.size()처럼 네트워크 요청 횟수 감소하여, 성능 향상 가능
6) NotLeaderOrFollowerException
클러스터를 구성하여 파티션의 개수를 늘린다면, 위와 같은 에러를 만날 수 있습니다.
log를 보면 특정 파티션의 리더에게 메시지를 보내지 않아서 발생한다고 합니다.
하지만 잘 생각해보면 말이 안 됩니다. 특정 파티션에게만 메시지를 보낸다면, 결국 파티션을 나누는 게 의미가 없습니다. 하나의 파티션으로 모든 메시지를 처리해야 하는데요.
정확한 해결 방법은 찾지 못했지만, 메모리 부족이 이유라고 추측합니다. 왜냐하면 파티션을 많이 나누려면, 그만큼 각 파티션마다 차지하는 메모리가 필요합니다. 그래서 모든 파티션이 메모리에서 사용되지 못 하기 때문이라고 추측합니다.
test 환경의 스펙은 8기가 램입니다. 추가로 IDE, 카톡 등 많은 프로세스가 사용 중에 있었습니다. 최대한 많은 프로세스를 종료시켜, 메모리 확보 후 문제 해결했습니다.
만약 사용하는 환경의 메모리가 부족한 경우에는 파티션의 개수를 1개로 줄인다면, 문제없이 사용 가능합니다. 하지만 토픽 생성 후 파티션의 개수를 줄이는 것은 불가능하기 때문에, 생성 전 메모리의 상태를 먼저 파악해야 합니다.
해당 에러 경험 후 kafka를 실제 production level에서 사용하기에는 메모리 관리에 큰 노력을 해야 할 것 같다는 생각이 듭니다.
반응형'Kafka' 카테고리의 다른 글
Zookeeper 클러스터 및 컨트롤러 선출 (0) 2021.09.19 Kafka 클러스터 구성 및 장애 해결 (0) 2021.09.12 (Kafka) 객체를 JSON 타입으로 넘겨보자 (0) 2021.09.01 Kafka, @Async 비동기 처리 맛보기 (4) 2021.08.16