Gerenciamento do ciclo de vida do esquema

À 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 de 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 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 dos 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 esquemas.

Como a evolução do esquema funciona

  1. Você modifica a definição do esquema. Por exemplo, adicione um campo opcional ao arquivo .proto ou .avsc.

  2. Um produtor configurado com auto.register.schemas=true envia uma mensagem usando o novo esquema ou você tenta registrar explicitamente o novo esquema usando a API ou as bibliotecas de cliente.

  3. Quando uma solicitação de registro de uma nova versão chega ao registro de esquema, ela recupera a regra de compatibilidade configurada para o assunto de destino. Ela compara o novo esquema proposto com as versões anteriores necessárias de acordo com essa regra.

  4. Se a versão do esquema for compatível, o novo esquema será registrado como a próxima versão do assunto, receberá um novo número de versão e, possivelmente, um novo schema_id se a definição for exclusiva.

  5. O produtor (se aplicável) recebe o schema_id para incluir nas mensagens.

  6. Se a versão do esquema for incompatível, a tentativa de registro falhará e um erro será retornado.

Sobre o tipo de compatibilidade

A compatibilidade de esquema permite 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:

  • Nível de registro:define a configuração padrão para todo o registro de esquema.

    • Caminho: projects/project/locations/location/schemaRegistries/schema_registry/config
  • Nível de assunto no contexto padrão:define a configuração específica para um assunto no contexto padrão do registro.

    • Caminho: projects/project/locations/location/schemaRegistries/schema_registry/config/subject
  • Nível de assunto em um contexto específico:define a configuração específica para um assunto em um contexto nomeado.

    • Caminho: projects/project/locations/location/schemaRegistries/schema_registry/contexts/context/config/subject

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 for 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 acarreta um alto risco de quebrar clientes.

  • Backward (padrão) : os aplicativos de 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 de consumidor que usam o novo esquema podem decodificar dados produzidos com todas as versões de esquema anteriores nesse assunto. Essa configuração é mais rigorosa que Backward.

  • Forward:os dados produzidos usando 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 usando o novo esquema precisam ser legíveis usando todas as versões de esquema anteriores. Essa configuração é mais rigorosa que Forward.

  • Full:o novo esquema é compatível com versões anteriores e futuras da versão de esquema registrada anteriormente. Os clientes podem ser atualizados em qualquer ordem em relação ao produtor que usa o novo esquema. Permite adicionar ou excluir campos opcionais.

  • Full_transitive:o novo esquema é compatível com versões anteriores e futuras de todas as versões de esquema anteriores nesse assunto. Essa configuração é mais rigorosa que Full.

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 nesse registro, e eles herdam a compatibilidade Backward do registro.

Para um assunto específico chamado user-events, você precisa de regras de compatibilidade mais rigorosas. Atualize 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-events precisa 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 aderem à configuração de compatibilidade Backward no nível do registro, a menos que a compatibilidade tenha sido configurada explicitamente.

Se você mudar o nível de compatibilidade do registro de esquema para Forward, essa mudança 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 você pode ter um nível de compatibilidade padrão para todo o registro e também ter a flexibilidade de definir requisitos de compatibilidade específicos para assuntos individuais com base nas necessidades do aplicativo.

Para mais informações, consulte Atualizar o tipo de compatibilidade.

Práticas recomendadas do modo de compatibilidade

  • Não use None como uma estratégia de tipo de compatibilidade, porque você corre o risco de quebrar clientes com mudanças de esquema.

  • Escolha uma estratégia baseada em encaminhamento, como Forward ou Forward-transitive, se quiser atualizar os produtores primeiro. Escolha uma estratégia baseada em versões anteriores, como Backward ou Backward-transitive, se quiser atualizar os consumidores primeiro.

  • Escolha uma estratégia transitiva se quiser manter a compatibilidade com várias versões de esquema anteriores. Se 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

As referências de esquema permitem definir estruturas comuns uma vez e se referir a elas em vários esquemas. Por exemplo, um esquema Address pode ser usado como parte de um esquema Customer e Supplier.

Essa abordagem promove a reutilização e a consistência em todos os 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 comum. 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 Customer e Supplier, e ambos precisam 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.

  1. Crie um assunto chamado address_schema e registre a definição de um endereço padrão. Ao criar um assunto pela primeira vez, você também está criando a versão 1 do esquema para esse assunto.

    Avro

    Crie e armazene isso como a versão 1 do assunto address_schema_avro.

    {
      "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 a versão 1 do assunto address_schema_proto.

    syntax = "proto3";
    
    package com.example.common;
    
    message Address {
      string street = 1;
      string city = 2;
      string zip_code = 3;
      string country = 4;
    }
    
  2. Crie o esquema customer_schema. Em vez de repetir os campos de endereço, você referencia o esquema address_schema.

    Avro

    O tipo do campo billingAddress com.example.common.Address se refere ao esquema Address definido 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 incluem 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.proto importa address.proto e usa com.example.common.Address para o campo billing_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 incluem uma referência de esquema:

    // Conceptual metadata for customer_schema_proto
    "references": [
      {
        "name": "address.proto",
        "subject": "address_schema_proto",
        "version": 1
      }
    ]
    
  3. Da mesma forma, para o esquema Supplier, você adicionaria uma referência de esquema que aponta para o mesmo esquema Address comum.

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. A seguir estão os caminhos para os recursos do modo de esquema:

  • Modo de nível de registro:aplica-se a todo o registro de esquema.

    • Caminho: projects/project/locations/location/schemaRegistry/schema_registry/mode
  • Modo de assunto de nível de registro:aplica-se a um assunto específico em todo o registro de esquema.

    • Caminho: projects/project/locations/location/schemaRegistries/schema_registry/mode/subject

Os seguintes modos são compatíveis:

  • Readonly: nesse modo, o registro de esquema ou o assunto ou assuntos especificados não podem ser atualizados. Modificações, como a atualização de configurações ou a 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 a atualização de configurações e a adição de novas versões de esquema. Esse é o modo padrão para novos registros de esquema e novos assuntos.

Ao determinar se uma modificação é permitida para um assunto específico, o modo definido no nível do assunto tem precedência 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 de modo de esquema

Considere um registro de esquema com o modo definido como Readwrite. Essa configuração significa que você pode adicionar novos assuntos ao registro e novas versões de esquema aos assuntos atuais.

Suponha que você tenha um assunto chamado production-config que queira proteger contra mudanças acidentais. Defina o modo para o 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 o próprio modo definido explicitamente permanecem no modo Readwrite, para que você ainda possa modificá-los.

  • Você pode continuar criando assuntos no registro porque o registro em si ainda está no modo Readwrite.

Mais tarde, você pode decidir colocar todo o registro de esquema em um estado de manutenção definindo o modo de nível de registro como Readonly. No entanto, você tem outro assunto, staging-config, que precisa permanecer modificável para testes contínuos. Defina 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 assuntos atuais, como aqueles sem uma substituição de modo específica, também se tornam Readonly por herança. Não é possível adicionar novas versões de esquema a eles nem atualizar as configurações.

  • O assunto production-config permanece Readonly conforme definido explicitamente.

  • O assunto staging-config permanece no modo Readwrite porque a configuração no nível do assunto substitui o modo Readonly no nível do registro. Você pode continuar adicionando versões de esquema e atualizando configurações para staging-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 na produção

Para proteger seus esquemas em um ambiente de produção, aplique as seguintes configurações:

  • Impeça o registro de novos esquemas definindo mode=READONLY para 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 de cliente do Kafka, defina auto.register.schemas=false. Para o Kafka Connect, configure essa configuração para os serializadores de chave e valor conforme necessário:

    • key.serializer.auto.register.schemas=false
    • value.serializer.auto.register.schemas=false
  • (Opcional) Para forçar os clientes a usar o esquema mais recente de um assunto, defina use.latest.version=true no serializador ou desserializador. Essa configuração direciona o cliente para usar a versão de esquema mais recente registrada para o assunto, em vez da versão que corresponde à mensagem específica.

A seguir

Apache Kafka® é uma marca registrada da The Apache Software Foundation ou afiliadas nos Estados Unidos e/ou em outros países.