Open kmg28801 opened 1 year ago
vi /home/ec2-user/producer.config
enable.idempotence=true
max.in.flight.requests.per.connection=5
retries=5
akcs=all
/user/local/kafka/bin/kafka-console-producer.sh --bootstrap-server peter-kafka01.foo.bar:9092 --topic peter-test04 --producer.config /home/ec2-user/producer.config
cd /data/kafka-logs/peter-test04-0
ls
/user/local/kafka/bin/kafka-topics.sh --bootstrap-server peter-kafka01.foo.bar:9092 --create --topic peter-test05 --partitions 1 --replication-factor 3
sudo yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
java -version
cd kafka2/chapter5/
java -jar ExactlyOnceProducer.jar
/user/local/kafka/bin/kafka-topics.sh --bootstrap-server peter-kafka01.foo.bar:9092 --list
vi /home/ec2-user/consumer.config
exclude.internal.topics=false
/user/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server peter-kafka01.foo.bar:9092 --topic __transaction_state --consumer.config /home/ec2-user/consumer.config --formatter "kafka.coordinator.transaction.TransactionLog\$TransactionLogMessageFormatter" --from-beginning
/user/local/kafka/bin/kafka-dump-log.sh --print-data-log--files /data/kafka-logs/peter-test05-0/00000000000000000000.log
5장 프로듀서의 내부 동작 원리와 구현
파티셔너
파티션 수가 변경될때는 키와 매핑된 해시 테이블도 변경되므로 파티션의 수가 늘때는 다른 파티션으로 전송될 수 있음
파티셔닝 전략
라운드 로빈 전략
delivery.timeout.ms
) default 값은 2분(12,000ms), 하지만 이렇게 처리 할 경우 배치와 압축의 효과를 얻지 못하므로 매우 비효율적이 됨.스티키 파티셔닝 전략
프로듀서의 배치
프로듀서의 배치 전송을 위한 옵션
배치전송의 장단점
일반적인 경우 처리량을 높이려면
batch.size
⬆️linger.ms
⬆️ , 압축 포맷: gzip, zstd 권장(높은 압축률)일반적인 경우 지연 없는 전송 =>
batch.size
⬇️linger.ms
⬇️, 압축 포맷: lz4, snappy 권장(낮은 지연시간)상황(환경)에 따라 달라질 수 있음
중복 없는 전송
메시지 전송 방식
at-least-once
(적어도 한번), 브로커가 준 ack를 확인할때까지 계속 보낼 수 있음.at-most-once
(최대 한번), ack없이 재전송x, 메시지 유실 가능, 높은 처리량을 요하는 로그 수집이나 IoT에서 사용exactly-once
(정확히 한번), 브로커가 Producer Id와 메시지번호를 기록하며 ack응답, ack를 받지 못한다면 프로듀서는 재전송. 즉 메시지의 번호와 producer Id를 통해 메시지의 중복을 피함.중복없는 전송을 위한 프로듀서 설정
enable.idempotence
프로듀서가 중복없는 전송을 허용할지 결정하는 옵션, 기본 값은 false이므로 true로 변경해야 함.max.in.flight.requests.per.connection
ack를 받지 않은 상태에서 하나의 커넥션에서 보낼 수 있는 최대 요청 수, 기본값은 5, 5이하로 설정해야 함.acks
, 기본값은 1이며 all로 설정해야 함.retries
ack를 받지 못한 경우 재시도를 해야 하므로 0보다 큰 값으로 설정기본적으로 retries 값은 0으로 설정되어 있으며, 이 경우 프로듀서는 한 번의 전송 시도를 하고 ACK를 기다립니다. 만약 ACK를 받지 못하면 프로듀서는 해당 메시지를 실패로 처리하고 에러를 반환합니다.
만약 retries 값을 1 이상의 값으로 설정한 경우, 프로듀서는 초기 전송 실패 후 최대 retries 번의 재시도를 시도합니다. 재시도는 일정한 지연(delay) 간격으로 수행됩니다. 그러나 재시도를 통해도 여전히 ACK를 받지 못한다면 해당 메시지는 재시도 횟수를 초과하게 되며, 이 경우 메시지가 유실될 수 있습니다.
메시지의 유실을 방지하려면 다음과 같은 점을 고려해야 합니다:
retries 값을 적절히 설정해야 합니다. 메시지 전송을 안정적으로 보장하기 위해 재시도 횟수를 충분히 설정하고, 네트워크 지연 등을 고려하여 적절한 재시도 간격을 설정해야 합니다.
acks 옵션을 적절히 설정해야 합니다. acks 옵션은 프로듀서가 ACK를 기다리는 방식을 결정합니다. 모든 복제본에 ACK를 받아야하는 경우, 또는 최소한 하나의 복제본에 ACK를 받으면 충분한 경우 등을 설정할 수 있습니다.
메시지의 중요성에 따라 추가적인 보장을 위해 리더 파티션에 메시지를 전송하는 설정인 min.insync.replicas 등을 고려할 수 있습니다.
따라서 메시지의 안전한 전달을 위해서는 retries 값 뿐만 아니라 acks 옵션 및 클러스터 구성과 운영 정책을 종합적으로 고려하여 적절한 설정을 수행해야 합니다.
내부적으로 트랜잭션 코디네이터(Transaction Coordinator)와 함께 카프카 프로듀서의 트랜잭션 동작을 설명하겠습니다:
트랜잭션 시작(Transaction Begin): 프로듀서는 트랜잭션을 시작하려면 beginTransaction() 메서드를 호출합니다. 이때, 프로듀서는 트랜잭션 ID를 생성하고 트랜잭션 코디네이터에게 해당 트랜잭션의 시작을 알립니다.
메시지 전송(Send Messages): 프로듀서는 트랜잭션 내에서 보내고자 하는 메시지를 일반적인 방법으로 전송합니다. 이때, 트랜잭션 ID를 메시지에 포함하여 트랜잭션 코디네이터가 해당 메시지를 트랜잭션에 속한 것으로 인식할 수 있도록 합니다.
ACK 확인 및 트랜잭션 코디네이터와 통신: 프로듀서는 메시지의 전송 결과인 ACK(응답 확인)를 받게 되면, 해당 ACK 정보를 트랜잭션 코디네이터에게 보고합니다. 이를 통해 트랜잭션 코디네이터는 프로듀서의 트랜잭션 진행 상태를 추적할 수 있습니다.
커밋 또는 롤백(Commit or Rollback): 트랜잭션의 모든 메시지 전송이 완료되면, 프로듀서는 commitTransaction() 메서드를 호출하여 트랜잭션을 커밋하거나, abortTransaction() 메서드를 호출하여 트랜잭션을 롤백합니다. 이때, 트랜잭션 코디네이터에게 해당 트랜잭션의 커밋 또는 롤백을 알리게 됩니다.