Verwaltung des Schema-Lebenszyklus

Wenn sich Ihre Anwendungen und ihre Datenanforderungen ändern, muss auch die Struktur Ihrer Kafka-Nachrichten angepasst werden. Eine effektive Verwaltung des Schemalebenszyklus ist entscheidend, um diese Änderungen reibungslos zu bewältigen und die Datenintegrität aufrechtzuerhalten. Dieser Prozess umfasst nicht nur das Ändern von Schemas, sondern auch die systematische Kontrolle der Arten von Änderungen, die für die Anwendungen, von denen sie abhängen, sicher oder ausreichend kompatibel sind.

Die Schema-Registry für Managed Service for Apache Kafka unterstützt den gesamten Lebenszyklus der Schemaverwaltung und umfasst die folgenden Funktionen:

  • Definieren und erzwingen Sie Kompatibilitätsregeln (Kompatibilitätstyp), um die Schemaentwicklung zu verwalten, wenn neue Schemaversionen eingeführt werden. Diese Regeln sorgen dafür, dass Produzenten und Konsumenten weiterhin korrekt funktionieren.

  • Konfigurieren Sie betriebliche Kontrollen (Schemamodi), um die Veränderbarkeit von Schemas auf verschiedenen Ebenen zu verwalten und so Ihre Datenverarbeitungspipelines zu schützen.

  • Verwalten Sie Schemareferenzen, um die Wiederverwendbarkeit und Konsistenz Ihrer Schemas zu fördern.

Funktionsweise der Schemaentwicklung

  1. Sie ändern Ihre Schemadefinition. Fügen Sie beispielsweise Ihrer .proto- oder .avsc-Datei ein optionales Feld hinzu.

  2. Ein mit auto.register.schemas=true konfigurierter Producer sendet eine Nachricht mit dem neuen Schema oder Sie versuchen explizit, das neue Schema über die API oder die Clientbibliotheken zu registrieren.

  3. Wenn eine Registrierungsanfrage für eine neue Version die Schema-Registry erreicht, ruft sie die konfigurierte Kompatibilitätsregel für das Zielsubjekt ab. Gemäß dieser Regel wird das vorgeschlagene neue Schema mit den erforderlichen vorherigen Versionen verglichen.

  4. Wenn die Schemaversion kompatibel ist, wird das neue Schema als nächste Version unter dem Subjekt registriert, eine neue Versionsnummer zugewiesen und möglicherweise eine neue schema_id, wenn die Definition eindeutig ist.

  5. Der Producer (falls zutreffend) erhält die schema_id, die er in Nachrichten einfügen kann.

  6. Wenn die Schemaversion nicht kompatibel ist, schlägt der Registrierungsversuch fehl und es wird ein Fehler zurückgegeben.

Kompatibilitätstyp

Mit der Schemakompatibilität können Sie definieren, wie die Schema-Registry Kompatibilitätsprüfungen zwischen verschiedenen Schemaversionen verarbeitet. Sie können diese Konfigurationen auf verschiedenen Ebenen innerhalb der Schema-Registry-Hierarchie anwenden, wie durch die folgenden Optionen für Ressourcenmuster angegeben:

  • Registry-Ebene:Legt die Standardkonfiguration für die gesamte Schema-Registry fest.

    • Pfad: projects/project/locations/location/schemaRegistries/schema_registry/config
  • Subjektebene im Standardkontext:Legt eine bestimmte Konfiguration für ein Subjekt im Standardkontext der Registry fest.

    • Pfad: projects/project/locations/location/schemaRegistries/schema_registry/config/subject
  • Subjektebene in einem bestimmten Kontext:Legt eine bestimmte Konfiguration für ein Subjekt in einem benannten Kontext fest.

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

Konfigurationen, die auf Subjektebene festgelegt werden, überschreiben die auf Registry-Ebene festgelegten Konfigurationen. Wenn eine Einstellung nicht auf Subjektebene angegeben ist, wird der Wert von der Registry-Ebene übernommen. Wenn sie nicht explizit auf Registry-Ebene festgelegt ist, ist die Standardeinstellung Backward.

Die folgenden verfügbaren Typen bestimmen, wie die Schema-Registry eine neue Schemaversion mit vorherigen Versionen vergleicht:

  • None:Es werden keine Kompatibilitätsprüfungen durchgeführt. Ermöglicht jede Änderung, birgt aber ein hohes Risiko, dass Clients nicht mehr funktionieren.

  • Backward (Standard) : Konsumentenanwendungen, die das neue Schema verwenden, können Daten decodieren, die nur mit dem zuvor registrierten Schema erstellt wurden. So können optionale Felder hinzugefügt und Felder gelöscht werden. Konsumenten müssen vor Produzenten aktualisiert werden.

  • Backward_transitive:Konsumentenanwendungen, die das neue Schema verwenden, können Daten decodieren, die mit allen vorherigen Schemaversionen in diesem Subjekt erstellt wurden. Diese Einstellung ist strenger als Backward.

  • Forward:Daten, die mit dem neuen Schema erstellt wurden, müssen von Clients gelesen werden können, die das zuvor registrierte Schema verwenden. Produzenten müssen zuerst aktualisiert werden, aber Konsumenten, die das neue Schema verwenden, können möglicherweise keine Daten lesen, die mit noch älteren Schemas erstellt wurden. Mit dieser Einstellung können optionale Felder gelöscht und Felder hinzugefügt werden.

  • Forward_transitive:Daten, die mit dem neuen Schema erstellt wurden, müssen mit allen vorherigen Schemaversionen gelesen werden können. Diese Einstellung ist strenger als Forward.

  • Full:Das neue Schema ist sowohl abwärts- als auch aufwärtskompatibel mit der zuvor registrierten Schemaversion. Clients können in beliebiger Reihenfolge im Verhältnis zum Producer, der das neue Schema verwendet, aktualisiert werden. Ermöglicht das Hinzufügen oder Löschen optionaler Felder.

  • Full_transitive:Das neue Schema ist sowohl abwärts- als auch aufwärtskompatibel mit allen vorherigen Schemaversionen in diesem Subjekt. Diese Einstellung ist strenger als Full.

Beispiel für den Kompatibilitätstyp

Angenommen, Sie haben eine Schema-Registry mit dem Kompatibilitätstyp Backward. Sie erstellen auch mehrere Subjekte in dieser Registry, die die Backward-Kompatibilität der Registry übernehmen.

Für ein bestimmtes Subjekt mit dem Namen user-events benötigen Sie strengere Kompatibilitätsregeln. Sie aktualisieren die Schemakompatibilitätsstufe für das Subjekt user-events auf Full.

In dieser Situation gelten die folgenden Regeln:

  • Jede neue Schemaversion, die unter dem Subjekt user-events registriert wird, muss sowohl abwärts- als auch aufwärtskompatibel mit der zuvor registrierten Schemaversion für dieses Subjekt sein.

  • Andere Subjekte in der Schema-Registry halten sich weiterhin an die Backward-Kompatibilitätseinstellung auf Registry-Ebene, es sei denn, ihre Kompatibilität wurde explizit konfiguriert.

Wenn Sie später die Kompatibilitätsstufe der Schema-Registry in Forward ändern, wirkt sich diese Änderung auf die Standardkompatibilität für alle neuen Subjekte aus, die in der Registry erstellt werden. Das Subjekt user-events behält jedoch seine explizit festgelegte Full-Kompatibilität bei, da Konfigurationen auf Subjektebene Konfigurationen auf Registry-Ebene überschreiben.

So können Sie eine Standardkompatibilitätsstufe für die gesamte Registry festlegen und gleichzeitig die Flexibilität haben, bestimmte Kompatibilitätsanforderungen für einzelne Subjekte basierend auf Ihren Anwendungsanforderungen zu definieren.

Weitere Informationen finden Sie unter Kompatibilitätstyp aktualisieren.

Best Practices für den Kompatibilitätsmodus

  • Verwenden Sie None nicht als Kompatibilitätstypstrategie, da Sie sonst riskieren, dass Clients aufgrund von Schemaänderungen nicht mehr funktionieren.

  • Wählen Sie eine aufwärtskompatible Strategie wie Forward oder Forward-transitive, wenn Sie zuerst Produzenten aktualisieren möchten. Wählen Sie eine abwärtskompatible Strategie wie Backward oder Backward-transitive, wenn Sie zuerst Konsumenten aktualisieren möchten.

  • Wählen Sie eine transitive Strategie, wenn Sie die Kompatibilität mit mehreren vorherigen Schemaversionen aufrechterhalten möchten. Wenn Sie die Kompatibilität maximieren und das Risiko minimieren möchten, dass Clients bei der Aktualisierung von Schemaversionen nicht mehr funktionieren, verwenden Sie die Strategie Full-transitive.

Schemareferenzen

Mit Schemareferenzen können Sie allgemeine Strukturen einmal definieren und von mehreren Schemas darauf verweisen. Beispielsweise kann ein Address-Schema sowohl als Teil eines Customer- als auch eines Supplier-Schemas verwendet werden.

Dieser Ansatz fördert die Wiederverwendbarkeit und Konsistenz Ihrer Schemas. Außerdem werden durch die Verwendung von Schemareferenzen klare Abhängigkeiten erstellt, sodass explizit nachverfolgt wird, welche Schemas von anderen abhängen. Dadurch wird die Wartbarkeit Ihrer Schemaarchitektur verbessert.

Wenn ein Schema ein anderes gemeinsames Schema verwenden muss, enthält es eine Referenz auf dieses gemeinsame Schema. Diese Beziehung wird formal durch eine SchemaReference-Struktur definiert.

Eine SchemaReference hat die folgenden Komponenten:

  • name (String): Der voll qualifizierte Name des Schemas, auf das verwiesen wird, für Avro-Formate oder der Dateiname eines importierten Typs für Protobuf-Formate, wie er in der Schemadefinition selbst verwendet wird.

  • subject (String): Der Name des Subjekts, unter dem das referenzierte Schema in der Schema-Registry registriert ist.

  • version (int32): Die spezifische Versionsnummer des referenzierten Schemas.

Ein Schema, das andere Schemas verwendet, deklariert diese Abhängigkeiten in einem references-Feld. Dieses Feld enthält eine Liste von SchemaReference-Objekten.

Beispiel für Schemareferenzen

Angenommen, Sie müssen Schemas für Customer- und Supplier-Daten definieren und beide müssen eine Adresse enthalten. Mit Schemareferenzen können Sie die Adressstruktur einmal definieren und wiederverwenden.

Informationen zum Folgen dieses Beispiels finden Sie unter Subjekt erstellen.

  1. Erstellen Sie ein Subjekt mit dem Namen address_schema und registrieren Sie die Definition für eine Standardadresse. Wenn Sie zum ersten Mal ein Subjekt erstellen, erstellen Sie auch Version 1 des Schemas für dieses Subjekt.

    Avro

    Erstellen und speichern Sie dies als Subjekt address_schema_avro Version 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

    Erstellen und speichern Sie dies als Subjekt address_schema_proto Version 1.

    syntax = "proto3";
    
    package com.example.common;
    
    message Address {
      string street = 1;
      string city = 2;
      string zip_code = 3;
      string country = 4;
    }
    
  2. Erstellen Sie das customer_schema-Schema. Anstatt die Adressfelder zu wiederholen, verweisen Sie auf das address_schema-Schema.

    Avro

    Der Typ com.example.common.Address des Felds billingAddress verweist auf das im vorherigen Schritt definierte Address Schema.

    {
      "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"}
      ]
    }
    

    Bei der Registrierung von customer_schema_avro würden die Metadaten eine Schemareferenz enthalten:

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

    Protobuf

    Die Datei customer.proto importiert address.proto und verwendet com.example.common.Address für das Feld 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;
    }
    

    Bei der Registrierung von customer_schema_proto würden die Metadaten eine Schemareferenz enthalten:

    // Conceptual metadata for customer_schema_proto
    "references": [
      {
        "name": "address.proto",
        "subject": "address_schema_proto",
        "version": 1
      }
    ]
    
  3. Ebenso würden Sie für Ihr Supplier-Schema eine Schemareferenz hinzufügen, die auf dasselbe gemeinsame Address-Schema verweist.

Schemamodus

Der Schemamodus definiert den Betriebsstatus einer Schema-Registry oder eines bestimmten Subjekts und steuert die Arten von Änderungen, die zulässig sind. Der Schemamodus kann auf eine Registry oder ein bestimmtes Subjekt in einer Schema-Registry angewendet werden. Die folgenden Pfade gelten für die Schemamodusressourcen:

  • Modus auf Registry-Ebene:Gilt für die gesamte Schema-Registry.

    • Pfad: projects/project/locations/location/schemaRegistry/schema_registry/mode
  • Modus auf Registry-Ebene für Subjekte:Gilt für ein bestimmtes Subjekt in der gesamten Schema-Registry.

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

Die folgenden Modi werden unterstützt:

  • Readonly: In diesem Modus kann die Schema-Registry oder das angegebene Subjekt bzw. die angegebenen Subjekte nicht aktualisiert werden. Änderungen wie das Aktualisieren von Konfigurationen oder das Hinzufügen neuer Schemaversionen sind nicht möglich.

  • Readwrite: Dieser Modus ermöglicht eingeschränkte Schreibvorgänge in der Schema -Registry oder für das angegebene Subjekt bzw. die angegebenen Subjekte. Er ermöglicht Änderungen wie das Aktualisieren von Konfigurationen und das Hinzufügen neuer Schemaversionen. Dies ist der Standardmodus für neue Schema-Registries und neue Subjekte.

Wenn Sie festlegen, ob eine Änderung für ein bestimmtes Subjekt zulässig ist, hat der auf Subjektebene festgelegte Modus Vorrang vor dem auf Schema-Registry-Ebene festgelegten Modus.

Wenn sich eine Schema-Registry beispielsweise im Modus Readonly befindet, ein bestimmtes Subjekt darin aber im Modus Readwrite, sind Änderungen an diesem bestimmten Subjekt zulässig. Die Erstellung neuer Subjekte ist jedoch durch den Modus Readonly auf Registry-Ebene eingeschränkt.

Beispiel für den Schemamodus

Angenommen, für eine Schema-Registry ist der Modus Readwrite festgelegt. Diese Konfiguration bedeutet, dass Sie der Registry neue Subjekte und vorhandenen Subjekten neue Schemaversionen hinzufügen können.

Angenommen, Sie haben ein Subjekt mit dem Namen production-config, das Sie vor versehentlichen Änderungen schützen möchten. Sie legen den Modus für das Subjekt production-config auf Readonly fest. Daher gelten für das Subjekt production-config die folgenden Bedingungen:

  • Sie können dem Subjekt keine neuen Schemaversionen hinzufügen.

  • Sie können die Konfiguration (z. B. den Kompatibilitätstyp) für das Subjekt nicht aktualisieren.

  • Für andere Subjekte in der Registry, für die kein eigener Modus explizit festgelegt wurde, bleibt der Modus Readwrite bestehen, sodass Sie sie weiterhin ändern können.

  • Sie können weiterhin Subjekte in der Registry erstellen, da sich die Registry selbst weiterhin im Modus Readwrite befindet.

Später entscheiden Sie möglicherweise, die gesamte Schema-Registry in einen Wartungszustand zu versetzen, indem Sie den Modus auf Registry-Ebene auf Readonly festlegen. Sie haben jedoch ein weiteres Subjekt, staging-config, das für laufende Tests änderbar bleiben muss. Sie legen den Modus für das Subjekt staging-config explizit auf Readwrite fest. Daher gelten für das Subjekt staging-config die folgenden Bedingungen:

  • Die Schema-Registry ist jetzt Readonly. Sie können keine neuen Subjekte erstellen.

  • Die meisten vorhandenen Subjekte, z. B. solche ohne spezifische Modusüberschreibung, werden durch Vererbung ebenfalls Readonly. Sie können ihnen keine neuen Schemaversionen hinzufügen oder ihre Konfigurationen aktualisieren.

  • Das Subjekt production-config bleibt wie explizit festgelegt Readonly.

  • Das Subjekt staging-config bleibt im Modus Readwrite, da die Einstellung auf Subjektebene den Modus Readonly auf Registry-Ebene überschreibt. Sie können weiterhin Schemaversionen hinzufügen und Konfigurationen für staging-config aktualisieren.

Dieser hierarchische Ansatz bietet Flexibilität bei der Verwaltung von Schemaänderungen auf verschiedenen Granularitätsebenen.

Weitere Informationen zum Aktualisieren des Schemamodus finden Sie unter Schemamodus aktualisieren.

Empfohlene Konfiguration für die Verwendung der Schema-Registry in der Produktion

Wenden Sie die folgenden Konfigurationen an, um Ihre Schemas in einer Produktionsumgebung zu schützen:

  • Verhindern Sie die Registrierung neuer Schemas, indem Sie mode=READONLY für die gesamte Schema-Registry oder für die spezifischen Produktionsthemen festlegen.

  • Verhindern Sie, dass Kafka-Clients neue Schemaversionen erstellen, indem Sie dafür sorgen, dass sie nicht die create version Berechtigung haben.

  • Legen Sie in Ihren Kafka-Client-Serialisierern auto.register.schemas=false fest. Konfigurieren Sie diese Einstellung für Kafka Connect nach Bedarf für die Schlüssel- und Wertserialisierer:

    • key.serializer.auto.register.schemas=false
    • value.serializer.auto.register.schemas=false
  • (Optional) Wenn Sie Clients zwingen möchten, das neueste Schema für ein Subjekt zu verwenden, legen Sie use.latest.version=true im Serialisierer oder Deserialisierer fest. Mit dieser Einstellung wird der Client angewiesen, die neueste für das Subjekt registrierte Schemaversion zu verwenden und nicht die Version, die der jeweiligen Nachricht entspricht.

Nächste Schritte

Apache Kafka® ist eine eingetragene Marke der Apache Software Foundation oder ihrer Tochtergesellschaften in den USA und/oder anderen Ländern.