본문 바로가기

빅데이터/Kafka

카프카 프로듀서의 acks=all 옵션은 사실(?) 느리지 않다!

카프카 3.0 부터는 카프카 프로듀서의 acks 옵션이 all로 지정됩니다. acks=all이 기본값으로 지정된 이유 중 하나는 프로듀서와 브로커 간 통신을 멱등성(idempotence)있게 만들기 위함입니다. 프로듀서와 브로커는 acks를 통해 레코드가 전송되었는지 확인합니다. 문제는 acks가 유실되었을 경우입니다. 네트워크 상태, 브로커 상태에 따라서 언제든 유실될 수 있는 acks를 정상적으로 전송하기 위해서는 acks를 위한 acks(!)를 만들어야만 합니다. 이는 두 장군 문제 알고리즘과 동일하다고 볼 수 있습니다.

 

결과적으로 프로듀서의 중복 전달을 제거하기 위해 카프카 3.0부터는 enable.idempotence가 true로 변경되었고 이에 딸려오는 추가 옵션인 acks가 all로 설정되게 되었습니다. 프로듀서가 여러번 브로커로 전송하더라도 결과적으로 하나의 레코드만 적재하는 전략을 취했습니다.

 

프로듀서의 옵션 중 acks는 all로 설정할 경우 min.insync.replicas 개수 만큼 리더/팔로워 파티션에 레코드가 분산 저장되었는지 확인하는 역할을 합니다. 당연하게도 acks=0(적재를 확인하지 않음), acks=1(리더에 적재 확인)보다도 더 느릴 수 밖에 없습니다. 그렇다면 이렇게 느릴 수 있는 acks=all 옵션을 왜 카프카 프로듀서에 기본 값으로 적용하게 되었던걸까요?

 

이유는 max.inflight.requests.per.connection과 관련 있습니다. An analysis of the impact of max.in.flight.requests.per.connection and acks on Producer performance 에 따르면 acks=all로 설정하더라도 max.in.flight.requests.per.connection를 3으로 설정하고 비동기 프로듀서(Asynchronous producer)를 사용하면 acks=1과 동일한 성능을 낼 수 있음을 증명하였습니다. 비동기 프로듀서란 브로커로부터의 응답을 동기로 받지 않는 것을 뜻합니다. 즉, 프로듀서의 샌더가 max.in.flight.requests.per.connection 개수만큼 병렬로 레코드를 전송하면 되는 것이죠. 당연하게도 동기 프로듀서(Synchronous producer)를 사용하게 되면 속도는 매우느립니다.

 

Asynchronous producer

KafkaProducer<String, String> producer = new KafkaProducer<>(configs);
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC_NAME, messageValue);
producer.send(record); // 비동기 프로듀서 코드 #1
========
producer.send(record, new ProducerCallback()); // 비동기 프로듀서 코드 #2

Synchronous producer

ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC_NAME, messageValue);
try {
    RecordMetadata metadata = producer.send(record).get();
    logger.info(metadata.toString());
} catch (Exception e) {
    logger.error(e.getMessage(),e);
} finally {
    producer.flush();
    producer.close();
}

이런 특징으로 인해 KIP-679에서는 프로듀서와 브로커간 통신에서 레코드를 단 한번만 전송(Exactly-once)하기 위해 enable.idempotence를 true와 변경함과 동시에 acks를 all로 설정하게 되었습니다. 이를 통해 카프카 클라이언트 3.0 이후 버전에서 프로듀서는 브로커로 단 한번만 레코드를 전송할 수 있게 되었죠.

 

결론

  • 카프카 클라이언트 프로듀서 3.0 이후에는 acks가 all로 기본값으로 설정됨
  • acks=all로 성능이 유지되기 위해서는 비동기 프로듀서를 사용해야 함
  • 만약 카프카 클라이언트 3.0 미만 버전을 사용하고 있다가 3.0 이상으로 올려야 할 경우 acks 옵션의 기본값이 변경되므로 성능 및 동작에 차이에 대해 파악해야 함
반응형