Direcione eventos Kafka com chaves e partições

Big DataBeginner
Pratique Agora

Introdução

Vários eventos podem descrever o mesmo pedido: created, paid e shipped. Se os registros relacionados forem direcionados de forma consistente, um consumidor poderá acompanhar a sequência desse pedido dentro de uma partição. Uma chave de registro fornece uma entrada estável para o direcionamento; ela é diferente de event_id, que identifica uma ocorrência de evento.

Você publicará eventos intercalados de três pedidos em um tópico com três partições, exibirá suas chaves e posições reais e acrescentará mais um evento para um pedido existente. Um offset é a posição de um registro dentro de uma partição. Offsets não são números globais de linhas do tópico, e registros de partições diferentes não têm uma única ordenação global garantida.

O broker e os dados de entrada são independentes. Conhecimentos básicos de terminal bastam. Os valores dos eventos usam texto JSON legível; não é necessário programar em Python ou JSON, configurar clusters ou depender do estado anterior de tópicos. Mantenha a quantidade de partições e a estratégia de direcionamento do cliente fixas durante todo o experimento. Use o Terminal.

Publique eventos intercalados com uma chave de pedido

Nesta etapa, você enviará um identificador estável de pedido como chave, mantendo o evento completo como valor. Inspecione o lote fornecido com cinco registros:

cd /home/labex/project
cat /home/labex/project/data/keyed-orders.txt

Cada linha tem o formato key|value. A chave é um identificador de pedido. O valor JSON usa campos nomeados entre chaves: event_id é único, order_id corresponde à chave, sequence é a sequência de negócio desse pedido e event_type descreve a ocorrência. O texto JSON é o formato do valor; o Kafka não o interpreta automaticamente como um esquema de tabela.

Crie um tópico com três partições e uma réplica:

kafka-topics.sh --bootstrap-server localhost:9092 --create --topic orders-keyed --partitions 3 --replication-factor 1

As opções --reader-property do produtor configuram como ele interpreta as linhas de entrada. parse.key=true e key.separator=| dividem cada linha no separador. O separador em si não faz parte da chave nem do valor. O operador < do shell fornece o arquivo como entrada padrão, e o produtor encerra após enviar sua entrada finita:

kafka-console-producer.sh --bootstrap-server localhost:9092 --topic orders-keyed --reader-property parse.key=true --reader-property 'key.separator=|' < /home/labex/project/data/keyed-orders.txt

O arquivo intercala pedidos, portanto os eventos de order-2001 não são adjacentes na entrada. Com a mesma estratégia de direcionamento por chave e a quantidade de partições inalterada, chaves iguais vão para a mesma partição. Chaves diferentes podem compartilhar uma partição; três pedidos não garantem três números de partição diferentes.

Publique este lote fornecido de cinco registros apenas uma vez. Repetir uma leitura do consumidor é uma inspeção; repetir este comando do produtor acrescenta mais cinco registros. Se você estiver retomando após a publicação, continue com a inspeção pelo consumidor em vez de reenviar o arquivo.

Você forneceu a entrada para o direcionamento em vez de selecionar manualmente um número de partição. A seguir, lerá as decisões reais de direcionamento em vez de tentar adivinhá-las.

Inspecione chaves, partições e offsets juntos

Nesta etapa, você exibirá metadados do registro junto com cada valor. As opções --formatter-property do consumidor de console controlam a exibição, acrescentando a chave, a partição e o offset à saída comum. Elas não alteram o conteúdo armazenado dos eventos. A opção de início para um novo consumidor, o limite de cinco mensagens e o tempo limite sem mensagens tornam esta inspeção finita e repetível. Salve a saída localmente:

kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic orders-keyed --from-beginning --max-messages 5 --timeout-ms 30000 --formatter-property print.key=true --formatter-property print.partition=true --formatter-property print.offset=true > /home/labex/project/output/keyed-first.txt
cat /home/labex/project/output/keyed-first.txt

Cada linha de dados deve mostrar campos com esta estrutura geral, usando números reais e um valor JSON completo:

Partition:...    Offset:...    order-...    {"event_id":"...",...}

Os separadores são tabulações. Localize k1 e k3: ambos têm a chave order-2001 e devem compartilhar uma partição, com k3 em um offset maior. Da mesma forma, k2 e k4 devem compartilhar a partição de order-2002. Não exija que esses dois pedidos usem partições diferentes.

Offsets pertencem à partição, não à chave. Se outras chaves compartilharem essa partição, os offsets sucessivos de um pedido podem ter intervalos. O campo sequence do conteúdo é um valor da aplicação; o Kafka não o gerou como offset.

O consumidor pode intercalar registros de partições diferentes, portanto sua ordem global de exibição não precisa corresponder à do arquivo do produtor. Confira os eventos relacionados pela chave, pela partição e pelos offsets crescentes em vez de tratar a saída como uma única lista globalmente ordenada.

Acrescente outro evento para um pedido existente

Nesta etapa, você testará a mesma regra de direcionamento com outra execução do produtor. Preveja o resultado para o evento shipped de order-2001: ele deve ir para a partição já usada por esse pedido e vir depois dos registros anteriores nela. Seu offset exato depende dos outros registros que compartilham essa partição.

O padrão com printf do primeiro laboratório de Kafka envia uma linha completa com chave para o produtor de console com as mesmas configurações:

printf '%s\n' 'order-2001|{"event_id":"k6","order_id":"order-2001","sequence":3,"event_type":"shipped"}' | kafka-console-producer.sh --bootstrap-server localhost:9092 --topic orders-keyed --reader-property parse.key=true --reader-property 'key.separator=|'

Leia os seis registros retidos para uma nova observação:

kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic orders-keyed --from-beginning --max-messages 6 --timeout-ms 30000 --formatter-property print.key=true --formatter-property print.partition=true --formatter-property print.offset=true > /home/labex/project/output/keyed-with-shipped.txt
cat /home/labex/project/output/keyed-with-shipped.txt

Localize k6 com order-2001 e sequence 3. Compare sua partição com a de k1 e k3 e seu offset com os offsets deles. A sequência do pedido deve continuar sendo created, paid, shipped quando vista na ordem dos offsets da partição. Nenhum número fixo de partição é exigido.

A observação original de cinco registros permanece em keyed-first.txt. O novo produtor acrescentou um evento em vez de substituir os anteriores. A quantidade de partições do tópico e a estratégia de direcionamento podem afetar o destino, por isso este experimento não altera nenhuma delas. Clientes posteriores devem escolher uma estratégia compatível se precisarem do mesmo mapeamento entre implementações.

Agora você tem evidências de direcionamento estável por chave e de ordenação local à partição, sem presumir uma ordem global de eventos ou uma partição por pedido. O próximo desafio aplica essas mesmas técnicas de tópicos, retenção e publicação com chaves a um novo lote.

Resumo

Você forneceu chaves de pedidos, inspecionou partições e offsets reais e verificou que um evento acrescentado veio depois dos registros anteriores de seu pedido sob a mesma regra de direcionamento. Você distinguiu IDs de eventos, chaves de pedidos, a sequência no conteúdo e offsets de partição, sem presumir uma ordem global. A seguir, um desafio com um novo lote combina essas técnicas com a configuração de retenção de tópicos.