Administración del ciclo de vida del esquema

A medida que cambian tus aplicaciones y sus requisitos de datos, también debe adaptarse la estructura de tus mensajes de Kafka. La administración eficaz del ciclo de vida del esquema es fundamental para manejar estos cambios sin problemas y mantener la integridad de los datos. Este proceso no solo implica cambiar esquemas, sino también controlar de forma sistemática los tipos de cambios que son seguros o suficientemente compatibles para las aplicaciones que dependen de ellos.

El registro de esquemas de Managed Service para Apache Kafka admite el ciclo de vida completo de la administración de esquemas y, además, incluye las siguientes funciones:

  • Definir y aplicar reglas de compatibilidad (tipo de compatibilidad) para administrar la evolución del esquema cuando se introducen versiones nuevas del esquema Estas reglas garantizan que los productores y los consumidores sigan operando correctamente.

  • Configura controles operativos (modos de esquema) para administrar la mutabilidad de los esquemas en diferentes niveles y proteger tus canalizaciones de procesamiento de datos.

  • Administra las referencias de esquema para promover la reutilización y la coherencia en todos tus esquemas.

Cómo funciona la evolución del esquema

  1. Modificas la definición de tu esquema. Por ejemplo, agrega un campo opcional a tu archivo .proto o .avsc.

  2. Un productor configurado con auto.register.schemas=true envía un mensaje con el esquema nuevo, o bien intentas registrar el esquema nuevo de forma explícita con la API o las bibliotecas cliente.

  3. Cuando una solicitud de registro para una versión nueva llega al registro de esquemas, este recupera la regla de compatibilidad configurada para el tema de destino. Compara el nuevo esquema propuesto con las versiones anteriores requeridas según esa regla.

  4. Si la versión del esquema es compatible, el nuevo esquema se registra correctamente como la siguiente versión del tema, se le asigna un nuevo número de versión y, posiblemente, un nuevo schema_id si la definición es única.

  5. El productor (si corresponde) recibe el schema_id para incluirlo en los mensajes.

  6. Si la versión del esquema es incompatible, el intento de registro falla y se devuelve un error.

Acerca del tipo de compatibilidad

La compatibilidad del esquema te permite definir cómo el registro de esquemas controla las verificaciones de compatibilidad entre diferentes versiones de esquemas. Puedes aplicar estas configuraciones en varios niveles dentro de la jerarquía del registro de esquemas, como se indica en las siguientes opciones de patrones de recursos:

  • A nivel del registro: Establece la configuración predeterminada para todo el registro de esquemas.

    • Ruta de acceso: projects/project/locations/location/schemaRegistries/schema_registry/config
  • A nivel del tema dentro del contexto predeterminado: Establece una configuración específica para un tema dentro del contexto predeterminado del registro.

    • Ruta de acceso: projects/project/locations/location/schemaRegistries/schema_registry/config/subject
  • A nivel del asunto dentro de un contexto específico: Establece una configuración específica para un asunto dentro de un contexto con nombre.

    • Ruta de acceso: projects/project/locations/location/schemaRegistries/schema_registry/contexts/context/config/subject

Los parámetros de configuración establecidos a nivel del asunto anulan los establecidos a nivel del registro. Si no se especifica un parámetro de configuración a nivel del asunto, se hereda el valor del nivel del registro. Si no se establece de forma explícita a nivel del registro, el valor predeterminado es Backward.

Los siguientes tipos disponibles determinan cómo el registro de esquemas compara una nueva versión del esquema con las anteriores:

  • None: No se realizan verificaciones de compatibilidad. Permite cualquier cambio, pero conlleva un alto riesgo de dañar los clientes.

  • Backward (predeterminado): Las aplicaciones para el consumidor que usan el nuevo esquema pueden decodificar los datos producidos solo con el esquema registrado anteriormente. Esto permite agregar campos opcionales y borrar campos. Los consumidores deben actualizarse antes que los productores.

  • Backward_transitive: Las aplicaciones para el consumidor que usan el nuevo esquema pueden decodificar los datos producidos con todas las versiones anteriores del esquema en ese tema. Este parámetro de configuración es más estricto que Backward.

  • Forward: Los datos producidos con el nuevo esquema deben ser legibles para los clientes que usan el esquema registrado anterior. Primero se deben actualizar los productores, pero es posible que los consumidores que usan el esquema nuevo no puedan leer los datos producidos con esquemas aún más antiguos. Este parámetro de configuración permite borrar campos opcionales y agregar campos.

  • Forward_transitive: Los datos producidos con el nuevo esquema deben poder leerse con todas las versiones anteriores del esquema. Este parámetro de configuración es más estricto que Forward.

  • Full: El esquema nuevo es compatible con versiones anteriores y posteriores del esquema registrado previamente. Los clientes se pueden actualizar en cualquier orden en relación con el productor usando el nuevo esquema. Permite agregar o borrar campos opcionales.

  • Full_transitive: El nuevo esquema es compatible con todas las versiones anteriores del esquema de ese tema. Este parámetro de configuración es más estricto que Full.

Ejemplo de tipo de compatibilidad

Supongamos que tienes un registro de esquemas con el tipo de compatibilidad Backward. También crearás varios temas dentro de este registro, y estos heredarán la compatibilidad Backward del registro.

Para un tema específico llamado user-events, necesitas reglas de compatibilidad más estrictas. Actualizas el nivel de compatibilidad del esquema para el tema user-events a Full.

En esta situación, se aplican las siguientes reglas:

  • Cualquier versión nueva del esquema registrada en el tema user-events debe ser compatible con la versión del esquema registrada anteriormente para ese tema, tanto hacia atrás como hacia adelante.

  • Los demás temas del registro de esquemas siguen cumpliendo con el parámetro de configuración de compatibilidad Backward a nivel del registro, a menos que su compatibilidad se haya configurado de forma explícita.

Si más adelante cambias el nivel de compatibilidad del registro de esquemas a Forward, este cambio afectará la compatibilidad predeterminada de cualquier tema nuevo que se cree en el registro. Sin embargo, el tema user-events conservaría su compatibilidad Full establecida de forma explícita, ya que las configuraciones a nivel del tema anulan las configuraciones a nivel del registro.

Esto demuestra cómo puedes tener un nivel de compatibilidad predeterminado para todo el registro y, al mismo tiempo, tener la flexibilidad de definir requisitos de compatibilidad específicos para cada tema según las necesidades de tu aplicación.

Para obtener más información, consulta Tipo de compatibilidad de actualización.

Prácticas recomendadas para el modo de compatibilidad

  • No uses None como estrategia de tipo de compatibilidad, ya que corres el riesgo de que los clientes se interrumpan con los cambios de esquema.

  • Elige una estrategia basada en el avance, como Forward o Forward-transitive, si deseas actualizar primero a los productores. Elige una estrategia basada en la retroalimentación, como Backward o Backward-transitive, si quieres actualizar primero a los consumidores.

  • Elige una estrategia transitiva si deseas mantener la compatibilidad con varias versiones anteriores del esquema. Si deseas maximizar la compatibilidad y minimizar el riesgo de que se interrumpan los clientes cuando actualices las versiones del esquema, usa la estrategia Full-transitive.

Acerca de las referencias de esquemas

Las referencias de esquema te permiten definir estructuras comunes una vez y hacer referencia a ellas desde varios esquemas. Por ejemplo, un esquema Address se puede usar como parte de un esquema Customer y un esquema Supplier.

Este enfoque promueve la reutilización y la coherencia en todos tus esquemas. Además, el uso de referencias de esquema crea dependencias claras, ya que se realiza un seguimiento explícito de los esquemas que dependen de otros. Esto mejora el mantenimiento de la arquitectura de tu esquema.

Cuando un esquema necesita usar otro esquema común, incluye una referencia a ese esquema común. Esta relación se define formalmente con una estructura SchemaReference.

Un SchemaReference tiene los siguientes componentes:

  • name (cadena): Es el nombre completamente calificado del esquema al que se hace referencia para los formatos Avro o el nombre de archivo de un tipo importado para los formatos Protobuf, tal como se usa dentro de la propia definición del esquema.

  • subject (cadena): Es el nombre del asunto con el que el esquema al que se hace referencia se registra en el registro de esquemas.

  • version (int32): Es el número de versión específico del esquema al que se hace referencia.

Un esquema que usa otros esquemas declara estas dependencias en un campo references. Este campo contiene una lista de objetos SchemaReference.

Ejemplo de referencias de esquemas

Supongamos que necesitas definir esquemas para los datos de Customer y los datos de Supplier, y ambos deben incluir una dirección. Con las referencias de esquema, puedes definir la estructura de la dirección una vez y reutilizarla.

Para seguir este ejemplo, consulta Cómo crear un asunto.

  1. Crea un sujeto llamado address_schema y registra la definición de una dirección estándar. Cuando creas un tema por primera vez, también creas la versión 1 del esquema para ese tema.

    Avro

    Crea y almacena esto como la versión 1 del asunto 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

    Crea y almacena esto como la versión 1 del asunto 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. Crea el esquema customer_schema. En lugar de repetir los campos de dirección, haces referencia al esquema address_schema.

    Avro

    El tipo com.example.common.Address del campo billingAddress hace referencia al esquema Address definido en el paso 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"}
      ]
    }
    

    Cuando se registra customer_schema_avro, sus metadatos incluirían una referencia de esquema:

    // Conceptual metadata for customer_schema_avro
    "references": [
      {
        "name": "com.example.common.Address",
        "subject": "address_schema_avro",
        "version": 1
      }
    ]
    

    Protobuf

    El archivo customer.proto importa address.proto y usa com.example.common.Address para el 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;
    }
    

    Cuando se registra customer_schema_proto, sus metadatos incluirían una referencia de esquema:

    // Conceptual metadata for customer_schema_proto
    "references": [
      {
        "name": "address.proto",
        "subject": "address_schema_proto",
        "version": 1
      }
    ]
    
  3. Del mismo modo, para tu esquema Supplier, agregarías una referencia de esquema que apunte al mismo esquema Address común.

Acerca del modo de esquema

El modo de esquema define el estado operativo de un registro de esquemas o un tema específico, y controla los tipos de modificaciones permitidas. El modo de esquema se puede aplicar a un registro o a un tema específico dentro de un registro de esquemas. Las siguientes son las rutas de acceso a los recursos del modo de esquema:

  • Modo a nivel del registro: Se aplica a todo el registro de esquemas.

    • Ruta de acceso: projects/project/locations/location/schemaRegistry/schema_registry/mode
  • Modo de asunto a nivel del registro: Se aplica a un asunto específico dentro de todo el registro de esquemas.

    • Ruta de acceso: projects/project/locations/location/schemaRegistries/schema_registry/mode/subject

Se admiten los siguientes modos:

  • Readonly: En este modo, no se puede actualizar el registro de esquemas ni el tema o los temas especificados. Se evitan las modificaciones, como la actualización de configuraciones o la adición de nuevas versiones de esquema.

  • Readwrite: Este modo permite operaciones de escritura limitadas en el registro de esquemas o en los temas especificados. Permite realizar modificaciones, como actualizar la configuración y agregar nuevas versiones del esquema. Este es el modo predeterminado para los registros de esquemas y los temas nuevos.

Cuando se determina si se permite una modificación para un tema específico, el modo establecido a nivel del tema tiene prioridad sobre el modo establecido a nivel del registro de esquemas.

Por ejemplo, si un registro de esquema está en modo Readonly, pero un tema específico dentro de él está en modo Readwrite, se permiten las modificaciones en ese tema específico. Sin embargo, la creación de temas nuevos está restringida por el modo Readonly a nivel del registro.

Ejemplo para el modo de esquema

Considera un registro de esquemas con el modo establecido en Readwrite. Esta configuración significa que puedes agregar temas nuevos al registro y versiones de esquema nuevas a los temas existentes.

Supongamos que tienes un tema llamado production-config que deseas proteger de cambios accidentales. Estableces el modo para el asunto production-config en Readonly. Como resultado, se aplican las siguientes condiciones al tema production-config:

  • No puedes agregar versiones de esquema nuevas al tema.

  • No puedes actualizar la configuración (como el tipo de compatibilidad) del tema.

  • Los demás temas del registro que no tienen su propio modo establecido de forma explícita permanecen en el modo Readwrite, por lo que aún puedes modificarlos.

  • Puedes seguir creando temas en el registro porque el registro en sí sigue en modo Readwrite.

Más adelante, es posible que decidas poner todo el registro de esquemas en un estado de mantenimiento configurando el modo a nivel del registro en Readonly. Sin embargo, tienes otro tema, staging-config, que debe seguir siendo modificable para las pruebas en curso. Configuraste explícitamente el modo para el asunto staging-config en Readwrite. Como resultado, se aplican las siguientes condiciones al sujeto staging-config:

  • El registro de esquema ahora es Readonly. No puedes crear temas nuevos.

  • La mayoría de los temas existentes, como los que no tienen una anulación de modo específica, también se convierten en Readonly por herencia. No puedes agregarles versiones de esquema nuevas ni actualizar sus configuraciones.

  • El asunto production-config permanece como Readonly según lo establecido de forma explícita.

  • El asunto staging-config permanece en el modo Readwrite porque su configuración a nivel del asunto anula el modo Readonly a nivel del registro. Puedes seguir agregando versiones del esquema y actualizar la configuración de staging-config.

Este enfoque jerárquico proporciona flexibilidad para administrar las modificaciones del esquema en diferentes niveles de detalle.

Para obtener más información sobre cómo actualizar el modo de esquema, consulta Actualiza el modo de esquema.

Configuración recomendada para usar el registro de esquemas en producción

Para proteger tus esquemas en un entorno de producción, aplica las siguientes configuraciones:

  • Para evitar el registro de esquemas nuevos, configura mode=READONLY para todo el registro de esquemas o para los temas de producción específicos.

  • Impide que los clientes de Kafka creen versiones de esquema nuevas. Para ello, asegúrate de que no tengan el permiso create version.

  • En los serializadores de clientes de Kafka, establece auto.register.schemas=false. Para Kafka Connect, configura este parámetro para los serializadores de clave y valor según sea necesario:

    • key.serializer.auto.register.schemas=false
    • value.serializer.auto.register.schemas=false
  • (Opcional) Para forzar a los clientes a usar el esquema más reciente de un tema, establece use.latest.version=true en el serializador o deserializador. Este parámetro de configuración indica al cliente que use la versión de esquema más reciente registrada para el asunto, en lugar de la versión que coincide con el mensaje específico.

¿Qué sigue?

Apache Kafka® es una marca registrada de The Apache Software Foundation o sus afiliados en Estados Unidos y otros países.