Além da resposta aceita muito útil, gostaria de adicionar mais alguns detalhes
Particionamento
Por padrão, o Kafka usa a chave da mensagem para selecionar a partição do tópico em que grava. Isso é feito por algo como
hash(key) % number_of_partitions
Se nenhuma chave for fornecida, o Kafka irá particionar os dados aleatoriamente em rodízio.
Encomenda
Conforme afirmado na resposta fornecida, Kafka tem garantias sobre a ordem das mensagens apenas no nível de partição.
Digamos que você queira armazenar transações financeiras para seus clientes em um tópico Kafka com duas partições. As mensagens podem ser semelhantes a (chave: valor)
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}
Como não definimos uma chave, as duas partições provavelmente se parecerão
// 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}
O seu consumidor ao ler esse tópico pode acabar dizendo que o saldo da conta é 600 em um determinado momento, embora esse nunca tenha sido o caso! Só porque estava lendo todas as mensagens na partição 0 antes das mensagens na partição 1.
Com uma chave sensata (como customerId), isso poderia ser evitado, pois o particionamento seria assim:
// 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}
Compactação de toras
Sem uma chave como parte de suas mensagens, você não poderá definir a configuração do tópico cleanup.policy
como compacted
. De acordo com a documentação, "a compactação do log garante que o Kafka sempre manterá pelo menos o último valor conhecido para cada chave de mensagem dentro do log de dados para uma única partição de tópico.".
Esta configuração agradável e útil não estará disponível sem qualquer chave.
Uso de chaves
Em casos de uso da vida real, a chave de uma mensagem Kafka pode ter uma grande influência em seu desempenho e clareza de sua lógica de negócios.
Uma chave pode, por exemplo, ser usada naturalmente para particionar seus dados. Como você pode controlar seus consumidores para lerem de partições específicas, isso pode servir como um filtro eficiente. Além disso, a chave pode incluir alguns metadados no valor real da mensagem que ajuda a controlar o processamento subsequente. As chaves são geralmente menores do que os valores e, portanto, é mais conveniente analisar uma chave em vez de todo o valor. Ao mesmo tempo, você pode aplicar todas as serializações e registro de esquema como feito com seu valor também com a chave.
Como observação, existe também o conceito de Cabeçalho que pode ser usado para armazenar informações, consulte a documentação .