매우 유용한 답변 외에도 몇 가지 세부 정보를 추가하고 싶습니다.
파티셔닝
기본적으로 Kafka는 메시지의 키를 사용하여 기록하는 주제의 파티션을 선택합니다. 이것은에 DefaultPartitioner
의해 수행 됩니다
kafka.common.utils.Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
제공된 키가 없으면 Kafka는 데이터를 라운드 로빈 방식으로 무작위로 분할합니다.
Kafka에서는 Partitioner
클래스 를 확장하여 자신 만의 Partitioner를 만들 수 있습니다 . 이를 위해 partition
서명이있는 메서드 를 재정의해야합니다 .
int partition(String topic,
Object key,
byte[] keyBytes,
Object value,
byte[] valueBytes,
Cluster cluster)
일반적으로 Kafka 메시지 의 키 는 파티션을 선택하는 데 사용됩니다. 키가 없으면 처리하기 훨씬 더 복잡한 값에 의존해야합니다.
주문
주어진 답변에서 언급했듯이 Kafka는 파티션 수준에서만 메시지 순서를 보장합니다.
두 개의 파티션이있는 Kafka 주제에 고객의 금융 거래를 저장한다고 가정 해 보겠습니다. 메시지는 다음과 같을 수 있습니다 (key : value).
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 2, "changeInBankAccount": +100}
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 1, "changeInBankAccount": -1337}
null:{"customerId": 1, "changeInBankAccount": +200}
키를 정의하지 않았으므로 두 파티션은 아마도 다음과 같이 보일 것입니다.
// partition 0
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 1, "changeInBankAccount": +200}
// partition 1
null:{"customerId": 2, "changeInBankAccount": +100}
null:{"customerId": 1, "changeInBankAccount": -1337}
해당 주제를 읽는 소비자가 특정 시간에 계정 잔액이 600이라고 말할 수 있습니다. 파티션 1의 메시지 이전에 파티션 0의 모든 메시지를 읽었 기 때문입니다.
의미있는 키 (예 : customerId)를 사용하면 분할이 다음과 같으므로 피할 수 있습니다.
// partition 0
1:{"customerId": 1, "changeInBankAccount": +200}
1:{"customerId": 1, "changeInBankAccount": +200}
1:{"customerId": 1, "changeInBankAccount": -1337}
1:{"customerId": 1, "changeInBankAccount": +200}
// partition 1
2:{"customerId": 2, "changeInBankAccount": +100}
로그 압축
메시지의 일부로 키가 없으면 주제 구성 cleanup.policy
을 로 설정할 수 없습니다 compacted
. 문서 에 따르면 "로그 압축은 Kafka가 항상 단일 토픽 파티션에 대한 데이터 로그 내의 각 메시지 키에 대해 마지막으로 알려진 값을 유지하도록합니다."
이 멋지고 유용한 설정은 키 없이는 사용할 수 없습니다.
키 사용
실제 사용 사례에서 Kafka 메시지의 키는 비즈니스 로직의 성능과 명확성에 큰 영향을 미칠 수 있습니다.
예를 들어 키는 데이터 분할에 자연스럽게 사용될 수 있습니다. 소비자가 특정 파티션에서 읽도록 제어 할 수 있으므로 이는 효율적인 필터 역할을 할 수 있습니다. 또한 키에는 후속 처리를 제어하는 데 도움이되는 메시지의 실제 값에 대한 일부 메타 데이터가 포함될 수 있습니다. 키는 일반적으로 값보다 작으므로 전체 값 대신 키를 구문 분석하는 것이 더 편리합니다. 동시에 모든 직렬화 및 스키마 등록을 키를 사용하여 값에 적용 할 수 있습니다.
참고로 정보를 저장하는 데 사용할 수있는 헤더 개념도 있습니다 . 문서를 참조하십시오 .