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 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

  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 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.

  4. 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_id se a definição for única.

  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 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
  • 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
  • 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

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 que Backward.

  • 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 que Forward.

  • 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 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 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-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 obedecem à configuração de compatibilidade Backward no 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 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 com base 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 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.

  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 cria a versão 1 do esquema para esse assunto.

    Avro

    Crie e armazene isso como assunto address_schema_avro versã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_proto versão 1.

    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ê faz referência ao esquema address_schema.

    Avro

    O tipo com.example.common.Address do campo billingAddress 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 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.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 dele incluiriam 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, adicione uma referência de esquema apontando 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. 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
  • 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

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 Readonly por herança. Não é possível adicionar novas versões de esquema 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 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=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 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=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 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.

A seguir

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