Procurando entender melhor o Kafka, fiz um resumo de como o Kafka garante a ordenação das mensagens entregues a ele.
O que é?
Caso não saiba o que é o Kafka, a primeira resposta é muito mais do que você imagina. Alguns imaginam ele ser um broker de mensagens, o que no fundo ele é, mas as funcionalidades feitas em cima disso dão infinitas possibilidades.
Assim, defini-lo apenas como um broker de mensagens é errado. Ele é uma plataforma de Streaming. Podendo atuar como broker, base de dados e muito mais.
Ele garante ordenação de mensagens?
Sim e não!
Dependendo do uso que você faz dele, você pode ter a ordenação garantida. Para isso você tem que entender sua arquitetura.
Arquitetura do Kafka
Para começar, o Kafka é um cluster. São vario servidores a fim de garantir que não haja um Ponto Único de Falha. Caso você esteja construindo um cluster na nuvem, escola regiões diferentes para cada nó do cluster.
Outro ponto do Kafka, é que ele escreve as mensagens em arquivos de Log. Cada mensagem é simplesmente escrita em um arquivo e lida dele, sem muito processamento. A leitura dela é feita com base em um offset.
Como é um cluster, não existe somente um arquivo de Log, eles são divididos em partitions. Assim a mensagem é enviada para um log especifico dentro de uma Partition.
Um tópico seria composto por uma ou mais partição de um arquivo de log.
Como é escolhido qual mensagem vai para qual partition?
Cada mensagem pode ser associada a uma chave. Quando a mensagem é associada a uma chave, a partição é escolhida de acordo com a chave. Quando nenhuma chave é associada, a mensagem é distribuída pelas partições disponíveis.
Simples?
Garantindo a Ordenação
Voltemos a pergunta: como garantir a ordenação? Na verdade, a pergunta é: Que tipo de ordenação você precisa?
Ordenação Relativa
Se seu sistema precisa de uma ordenação relativa, por exemplo, todas as mensagens relacionadas a um produto devem vir ordenadas, então você pode criar um tópico com várias partições e usar o productId
como chave.
./bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 10 --topic product
Properties configProperties = new Properties();
configProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
configProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.LongSerializer");
configProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.vepo.MySerializer");
Producer<Long, Product> producer = new KafkaProducer<>(configProperties);
ProducerRecord<Long, Product> rec = new ProducerRecord<>("product", product.getId(), product);
producer.send(rec);
in.close();
producer.close();
No exemplo acima, criei um tópico com 10 partições e 3 replicas cada partição e garanto que as mensagens são entregues na ordem, para cada produto.
Ordenação Absoluta
Caso queira garantir uma ordenação absoluta. A garantia de ordenação está na configuração do Tópico. Nesse caso você terá que criar um tópico com uma única partição.
./bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic users
Assim, quando o cliente se conectar ao tópico, a leitura da partição terá sua ordem garantida.
Não ordenado
Caso ordenação não seja um requisito, você pode criar quantas partições quiser, mas se for usar chaves, garanta que elas serão igualmente distribuídas entre as partições. Para garantir isso, basta não usar chaves sempre iguais.