À medida que os aplicativos e os requisitos de dados mudam, a estrutura das mensagens do Kafka também precisa se adaptar. O gerenciamento eficaz do ciclo de vida do esquema é fundamental para lidar com essas mudanças sem problemas e manter a integridade dos dados. Esse processo envolve não apenas a mudança de esquemas, mas também o controle sistemático dos tipos de mudanças que são seguras ou suficientemente compatíveis para os aplicativos que dependem deles.
O registro de esquema do Serviço gerenciado para Apache Kafka oferece suporte ao ciclo de vida completo do gerenciamento de esquemas e inclui os seguintes recursos:
Defina e aplique regras de compatibilidade (tipo de compatibilidade) para gerenciar a evolução do esquema quando novas versões são introduzidas. Essas regras garantem que produtores e consumidores continuem operando corretamente.
Configure controles operacionais (modos de esquema) para gerenciar a mutabilidade de esquemas em diferentes níveis, protegendo seus pipelines de processamento de dados.
Gerencie referências de esquema para promover a reutilização e a consistência em todos os seus esquemas.
Como a evolução do esquema funciona
Você modifica a definição do esquema. Por exemplo, adicione um campo opcional ao arquivo
.protoou.avsc.Um produtor configurado com
auto.register.schemas=trueenvia uma mensagem usando o novo esquema, ou você tenta registrar explicitamente o novo esquema usando a API ou as bibliotecas de cliente.Quando uma solicitação de registro para uma nova versão chega ao registro de esquema, ele recupera a regra de compatibilidade configurada para o assunto de destino. Ele compara o novo esquema proposto com as versões anteriores necessárias de acordo com essa regra.
Se a versão do esquema for compatível, o novo esquema será registrado como a próxima versão no assunto, receberá um novo número de versão e, possivelmente, um novo
schema_idse a definição for única.O produtor (se aplicável) recebe o
schema_idpara incluir nas mensagens.Se a versão do esquema for incompatível, a tentativa de registro vai falhar e um erro será retornado.
Sobre o tipo de compatibilidade
Com a compatibilidade de esquema, é possível definir como o registro de esquema processa as verificações de compatibilidade entre diferentes versões de esquema. É possível aplicar essas configurações em vários níveis na hierarquia do registro de esquema, conforme indicado pelas seguintes opções de padrão de recurso:
No nível do registro:define a configuração padrão para todo o registro de esquema.
- Caminho:
projects/project/locations/location/schemaRegistries/schema_registry/config
- Caminho:
No nível do assunto no contexto padrão:define uma configuração específica para um assunto no contexto padrão do registro.
- Caminho:
projects/project/locations/location/schemaRegistries/schema_registry/config/subject
- Caminho:
No nível do assunto em um contexto específico:define uma configuração específica para um assunto em um contexto nomeado.
- Caminho:
projects/project/locations/location/schemaRegistries/schema_registry/contexts/context/config/subject
- Caminho:
As configurações definidas no nível do assunto substituem as definidas no nível do registro.
Se uma configuração não for especificada no nível do assunto, ela vai herdar o valor do nível do registro. Se não estiver definido explicitamente no nível do registro,
o padrão será Backward.
Os seguintes tipos disponíveis determinam como o registro de esquema compara uma nova versão de esquema com as anteriores:
None:nenhuma verificação de compatibilidade é realizada. Permite qualquer mudança, mas tem um alto risco de quebrar clientes.Backward(padrão): os aplicativos do consumidor que usam o novo esquema podem decodificar dados produzidos apenas com o esquema registrado anteriormente. Isso permite adicionar campos opcionais e excluir campos. Os consumidores precisam ser atualizados antes dos produtores.Backward_transitive:os aplicativos do consumidor que usam o novo esquema podem decodificar dados produzidos com todas as versões anteriores do esquema nesse assunto. Essa configuração é mais restrita queBackward.Forward:os dados produzidos com o novo esquema precisam ser legíveis por clientes que usam o esquema registrado anteriormente. Os produtores precisam ser atualizados primeiro, mas os consumidores que usam o novo esquema talvez não consigam ler dados produzidos com esquemas ainda mais antigos. Essa configuração permite excluir campos opcionais e adicionar campos.Forward_transitive:os dados produzidos com o novo esquema precisam ser legíveis usando todas as versões anteriores do esquema. Essa configuração é mais restritiva do queForward.Full:o novo esquema é compatível com versões anteriores e futuras da versão do esquema registrada anteriormente. Os clientes podem ser atualizados em qualquer ordem em relação ao produtor usando o novo esquema. Permite adicionar ou excluir campos opcionais.Full_transitive:o novo esquema é compatível com versões anteriores e futuras de todos os esquemas anteriores nesse assunto. Essa configuração é mais restrita queFull.
Exemplo de tipo de compatibilidade
Suponha que você tenha um registro de esquema com o tipo de compatibilidade Backward. Você também
cria vários assuntos dentro desse registro, e eles herdam a compatibilidade Backward do registro.
Para um assunto específico chamado user-events, você precisa de regras de compatibilidade mais rígidas. Você atualiza o nível de compatibilidade do esquema para o assunto
user-events para Full.
Nessa situação, as seguintes regras se aplicam:
Qualquer nova versão de esquema registrada no assunto
user-eventsprecisa ser compatível com versões anteriores e futuras da versão de esquema registrada anteriormente para esse assunto.Outros assuntos no registro de esquema ainda obedecem à configuração de compatibilidade
Backwardno nível do registro, a menos que a compatibilidade deles tenha sido configurada explicitamente.
Se você mudar o nível de compatibilidade do registro de esquema para Forward, essa mudança vai afetar a compatibilidade padrão de todos os novos assuntos criados no registro. No entanto, o assunto user-events manterá a compatibilidade Full definida explicitamente, já que as configurações no nível do assunto substituem as configurações no nível do registro.
Isso demonstra como ter um nível de compatibilidade padrão para todo o registro e, ao mesmo tempo, a flexibilidade de definir requisitos de compatibilidade específicos para assuntos individuais com base nas necessidades do aplicativo.
Para mais informações, consulte Atualizar tipo de compatibilidade.
Práticas recomendadas para o modo de compatibilidade
Não use
Nonecomo uma estratégia de tipo de compatibilidade porque você corre o risco de quebrar clientes com mudanças de esquema.Escolha uma estratégia com base em encaminhamento, como
ForwardouForward-transitive, se quiser atualizar os produtores primeiro. Escolha uma estratégia baseada em versões anteriores, comoBackwardouBackward-transitive, se quiser atualizar os consumidores primeiro.Escolha uma estratégia transitiva se quiser manter a compatibilidade com várias versões anteriores do esquema. Se você quiser maximizar a compatibilidade e minimizar o risco de quebrar clientes ao atualizar versões de esquema, use a estratégia
Full-transitive.
Sobre referências de esquema
Com as referências de esquema, é possível definir estruturas comuns uma vez e fazer referência a elas em vários esquemas. Por exemplo, um esquema Address pode ser usado como parte de um esquema Customer e um Supplier.
Essa abordagem promove a reutilização e a consistência em todos os seus esquemas. Além disso, o uso de referências de esquema cria dependências claras, rastreando explicitamente quais esquemas dependem de outros. Isso melhora a capacidade de manutenção da arquitetura do esquema.
Quando um esquema precisa usar outro esquema comum, ele inclui uma referência a esse esquema. Essa relação é definida formalmente por uma estrutura SchemaReference.
Um SchemaReference tem os seguintes componentes:
name(string): o nome totalmente qualificado do esquema referenciado para formatos Avro ou o nome do arquivo de um tipo importado para formatos Protobuf, conforme usado na própria definição do esquema.subject(string): o nome do assunto em que o esquema referenciado está registrado no registro de esquema.version(int32): o número de versão específico do esquema referenciado.
Um esquema que usa outros esquemas declara essas dependências em um campo references. Esse campo contém uma lista de objetos SchemaReference.
Exemplo de referências de esquema
Suponha que você precise definir esquemas para dados de Customer e Supplier, e ambos precisem incluir um endereço. Com referências de esquema, é possível definir a estrutura de endereço uma vez e reutilizá-la.
Para seguir este exemplo, consulte Criar um assunto.
Crie um assunto chamado
address_schemae registre a definição de um endereço padrão. Ao criar um assunto pela primeira vez, você também cria a versão 1 do esquema para esse assunto.Avro
Crie e armazene isso como assunto
address_schema_avroversão 1.{ "type": "record", "name": "Address", "namespace": "com.example.common", "fields": [ {"name": "street", "type": "string"}, {"name": "city", "type": "string"}, {"name": "zipCode", "type": "string"}, {"name": "country", "type": "string", "default": "USA"} ] }Protobuf
Crie e armazene isso como assunto
address_schema_protoversão 1.syntax = "proto3"; package com.example.common; message Address { string street = 1; string city = 2; string zip_code = 3; string country = 4; }Crie o esquema
customer_schema. Em vez de repetir os campos de endereço, você faz referência ao esquemaaddress_schema.Avro
O tipo
com.example.common.Addressdo campobillingAddressse refere ao esquemaAddressdefinido na etapa anterior.{ "type": "record", "name": "Customer", "namespace": "com.example.crm", "fields": [ {"name": "customerId", "type": "long"}, {"name": "customerName", "type": "string"}, // This field's type refers to the Address schema {"name": "billingAddress", "type": "com.example.common.Address"} ] }Ao registrar
customer_schema_avro, os metadados dele incluiriam uma referência de esquema:// Conceptual metadata for customer_schema_avro "references": [ { "name": "com.example.common.Address", "subject": "address_schema_avro", "version": 1 } ]Protobuf
O arquivo
customer.protoimportaaddress.protoe usacom.example.common.Addresspara o campobilling_address.syntax = "proto3"; package com.example.crm; import "address.proto"; message Customer { int64 customer_id = 1; string customer_name = 2; // This field's type refers to the imported Address message com.example.common.Address billing_address = 3; }Ao registrar
customer_schema_proto, os metadados dele incluiriam uma referência de esquema:// Conceptual metadata for customer_schema_proto "references": [ { "name": "address.proto", "subject": "address_schema_proto", "version": 1 } ]Da mesma forma, para o esquema
Supplier, adicione uma referência de esquema apontando para o mesmo esquemaAddresscomum.
Sobre o modo de esquema
O modo de esquema define o estado operacional de um registro de esquema ou de um assunto específico e controla os tipos de modificações permitidas. O modo de esquema pode ser aplicado a um registro ou a um assunto específico em um registro de esquema. Estes são os caminhos para os recursos do modo de esquema:
Modo no nível do registro:se aplica a todo o registro de esquemas.
- Caminho:
projects/project/locations/location/schemaRegistry/schema_registry/mode
- Caminho:
Modo de assunto no nível do registro:se aplica a um assunto específico em todo o registro de esquema.
- Caminho:
projects/project/locations/location/schemaRegistries/schema_registry/mode/subject
- Caminho:
Estes são os modos compatíveis:
Readonly: nesse modo, o registro de esquema ou o assunto especificado não podem ser atualizados. Modificações, como atualização de configurações ou adição de novas versões de esquema, são impedidas.Readwrite: esse modo permite operações de gravação limitadas no registro de esquema ou no assunto ou assuntos especificados. Ele permite modificações como atualizar configurações e adicionar novas versões de esquema. Esse é o modo padrão para novos registros de esquema e assuntos.
Ao determinar se uma modificação é permitida para um assunto específico, o modo definido no nível do assunto tem prioridade sobre o modo definido no nível do registro de esquema.
Por exemplo, se um registro de esquema estiver no modo Readonly, mas um assunto específico nele estiver no modo Readwrite, as modificações nesse assunto específico serão permitidas. No entanto, a criação de novos assuntos é restrita pelo modo Readonly no nível do registro.
Exemplo para o modo de esquema
Considere um registro de esquema com o modo definido como Readwrite. Com essa configuração, é possível adicionar novos assuntos ao registro e novas versões de esquema a assuntos atuais.
Imagine que você tenha um assunto chamado production-config que quer proteger contra mudanças acidentais. Você define o modo do assunto production-config como Readonly. Como resultado, as seguintes
condições se aplicam ao assunto production-config:
Não é possível adicionar novas versões de esquema ao assunto.
Não é possível atualizar a configuração (como o tipo de compatibilidade) do assunto.
Outros assuntos no registro que não têm um modo próprio definido explicitamente permanecem no modo
Readwrite, para que você ainda possa modificá-los.Você pode continuar criando assuntos no registro porque ele ainda está no modo
Readwrite.
Depois, você pode decidir colocar todo o registro de esquema em um estado de manutenção
definindo o modo no nível do registro como Readonly. No entanto, você tem outro assunto, staging-config, que precisa permanecer modificável para testes contínuos. Você define explicitamente o modo para o assunto staging-config como
Readwrite. Como resultado, as seguintes condições se aplicam ao assunto staging-config:
O registro de esquema agora é
Readonly. Não é possível criar novos assuntos.A maioria dos temas atuais, como aqueles sem uma substituição de modo específica, também se torna
Readonlypor herança. Não é possível adicionar novas versões de esquema nem atualizar as configurações.O assunto
production-configpermaneceReadonly, conforme definido explicitamente.O assunto
staging-configpermanece no modoReadwriteporque a configuração no nível do assunto substitui o modoReadonlyno nível do registro. Você pode continuar adicionando versões de esquema e atualizando configurações parastaging-config.
Essa abordagem hierárquica oferece flexibilidade no gerenciamento de modificações de esquema em diferentes níveis de granularidade.
Para mais informações sobre como atualizar o modo de esquema, consulte Atualizar o modo de esquema.
Configuração recomendada para usar o registro de esquema em produção
Para proteger seus esquemas em um ambiente de produção, aplique as seguintes configurações:
Para impedir o registro de novos esquemas, defina
mode=READONLYpara todo o registro de esquema ou para os tópicos de produção específicos.Impeça que os clientes do Kafka criem novas versões de esquema garantindo que eles não tenham a permissão
create version.Nos serializadores do cliente Kafka, defina
auto.register.schemas=false. Para o Kafka Connect, configure essa definição para os serializadores de chave e valor conforme necessário:key.serializer.auto.register.schemas=falsevalue.serializer.auto.register.schemas=false
(Opcional) Para forçar os clientes a usar o esquema mais recente de um assunto, defina
use.latest.version=trueno serializador ou desserializador. Essa configuração orienta o cliente a usar a versão mais recente do esquema registrada para o assunto, em vez da versão que corresponde à mensagem específica.