Wenn sich Ihre Anwendungen und ihre Datenanforderungen ändern, muss auch die Struktur Ihrer Kafka-Nachrichten angepasst werden. Ein effektives Schema-Lifecycle-Management ist entscheidend, um diese Änderungen reibungslos zu bewältigen und die Datenintegrität aufrechtzuerhalten. Dabei werden nicht nur Schemas geändert, sondern auch die Arten von Änderungen, die für die davon abhängigen Anwendungen sicher oder ausreichend kompatibel sind, systematisch kontrolliert.
Die Schema-Registry von Managed Service for Apache Kafka unterstützt den gesamten Lebenszyklus der Schemabearbeitung und umfasst die folgenden Funktionen:
Sie können Kompatibilitätsregeln (Kompatibilitätstyp) definieren und erzwingen, um die Schemaentwicklung zu verwalten, wenn neue Schemaversionen eingeführt werden. Diese Regeln sorgen dafür, dass Produzenten und Verbraucher weiterhin korrekt agieren.
Konfigurieren Sie Betriebssteuerungen (Schemamodi), um die Unveränderlichkeit von Schemas auf verschiedenen Ebenen zu verwalten und so Ihre Datenverarbeitungspipelines zu schützen.
Sie können Schemareferenzen verwalten, um die Wiederverwendbarkeit und Konsistenz Ihrer Schemas zu fördern.
Funktionsweise der Schemaentwicklung
Sie ändern Ihre Schemadefinition. Sie können beispielsweise ein optionales Feld in Ihre
.proto- oder.avsc-Datei einfügen.Ein mit
auto.register.schemas=truekonfigurierter Producer sendet eine Nachricht mit dem neuen Schema oder Sie versuchen explizit, das neue Schema über die API oder die Clientbibliotheken zu registrieren.Wenn eine Registrierungsanfrage für eine neue Version die Schema-Registry erreicht, wird die konfigurierte Kompatibilitätsregel für das Ziel-Subjekt abgerufen. Dabei wird das vorgeschlagene neue Schema mit den erforderlichen vorherigen Versionen gemäß dieser Regel verglichen.
Wenn die Schemaversion kompatibel ist, wird das neue Schema erfolgreich als nächste Version unter dem Subjekt registriert, erhält eine neue Versionsnummer und möglicherweise eine neue
schema_id, wenn die Definition eindeutig ist.Der Ersteller (falls zutreffend) erhält die
schema_id, die er in Nachrichten einfügen kann.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 Ressourcenmusteroptionen angegeben:
Registry-Ebene:Legt die Standardkonfiguration für die gesamte Schemaregistrierung fest.
- Pfad:
projects/project/locations/location/schemaRegistries/schema_registry/config
- Pfad:
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
- Pfad:
Ebene „Thema“ in einem bestimmten Kontext:Legt eine bestimmte Konfiguration für ein Thema in einem benannten Kontext fest.
- Pfad:
projects/project/locations/location/schemaRegistries/schema_registry/contexts/context/config/subject
- Pfad:
Konfigurationen auf Subjektebene überschreiben Konfigurationen auf Registry-Ebene.
Wenn eine Einstellung nicht auf der Ebene des Fachs angegeben ist, wird der Wert von der Ebene des Registers übernommen. Wenn nicht explizit auf der Registrierungsebene festgelegt, ist der Standardwert Backward.
Die folgenden verfügbaren Typen bestimmen, wie die Schema-Registry eine neue Schemaversion mit vorherigen 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): Consumer-Anwendungen, die das neue Schema verwenden, können Daten decodieren, die nur mit dem zuvor registrierten Schema erstellt wurden. So können Sie optionale Felder hinzufügen und Felder löschen. Nutzer müssen vor Produzenten aktualisiert werden.Backward_transitive:Mit dem neuen Schema können Verbraucheranwendungen Daten decodieren, die mit allen vorherigen Schemaversionen für dieses Thema erstellt wurden. Diese Einstellung ist strenger alsBackward.Forward:Daten, die mit dem neuen Schema erstellt wurden, müssen von Clients gelesen werden können, die das zuvor registrierte Schema verwenden. Ersteller müssen zuerst aktualisiert werden. Nutzer, die das neue Schema verwenden, können möglicherweise keine Daten lesen, die mit noch älteren Schemas erstellt wurden. Mit dieser Einstellung können Sie optionale Felder löschen und Felder hinzufügen.Forward_transitive:Daten, die mit dem neuen Schema erstellt wurden, müssen mit allen vorherigen Schemaversionen lesbar sein. Diese Einstellung ist strenger alsForward.Full:Das neue Schema ist sowohl abwärts- als auch aufwärtskompatibel mit der zuvor registrierten Schemaversion. Clients können in beliebiger Reihenfolge relativ zum Producer mit dem neuen Schema 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 für dieses Thema. Diese Einstellung ist strenger alsFull.
Beispiel für 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 Thema mit dem Namen user-events sind strengere Kompatibilitätsregeln erforderlich. Sie aktualisieren die Schemakompatibilitätsstufe für das Subjekt user-events auf Full.
In diesem Fall gelten die folgenden Regeln:
Jede neue Schemaversion, die für das Subjekt
user-eventsregistriert wird, muss sowohl abwärts- als auch aufwärtskompatibel mit der zuvor registrierten Schemaversion für dieses Subjekt sein.Für andere Subjekte in der Schema-Registry gilt weiterhin die Kompatibilitätseinstellung
Backwardauf Registry-Ebene, sofern ihre Kompatibilität nicht explizit konfiguriert wurde.
Wenn Sie die Kompatibilitätsstufe der Schema-Registry später in Forward ändern, wirkt sich diese Änderung auf die Standardkompatibilität aller neuen Subjekte aus, die in der Registry erstellt werden. Das user-events-Thema behält jedoch die explizit festgelegte Full-Kompatibilität bei, da Konfigurationen auf Themaebene Konfigurationen auf Registry-Ebene überschreiben.
So können Sie eine Standardkompatibilitätsebene für die gesamte Registrierung festlegen und gleichzeitig die Flexibilität haben, spezifische Kompatibilitätsanforderungen für einzelne Themen basierend auf den Anforderungen Ihrer Anwendung zu definieren.
Weitere Informationen finden Sie unter Aktualisierungskompatibilitätstyp.
Best Practices für den Kompatibilitätsmodus
Verwenden Sie
Nonenicht als Kompatibilitätstypstrategie, da Sie sonst riskieren, dass Clients durch Schemaänderungen nicht mehr funktionieren.Wählen Sie eine zukunftsorientierte Strategie wie
ForwardoderForward-transitiveaus, wenn Sie zuerst die Produktionsumgebung aktualisieren möchten. Wählen Sie eine rückwärtsgerichtete Strategie wieBackwardoderBackward-transitiveaus, wenn Sie zuerst Verbraucher aktualisieren möchten.Wählen Sie eine transitive Strategie aus, wenn Sie die Kompatibilität mit mehreren früheren Schemaversionen beibehalten möchten. Wenn Sie die Kompatibilität maximieren und das Risiko minimieren möchten, dass Clients beim Aktualisieren von Schemaversionen nicht mehr funktionieren, verwenden Sie die
Full-transitive-Strategie.
Schemareferenzen
Mit Schemareferenzen können Sie gemeinsame Strukturen einmal definieren und von mehreren Schemas aus darauf verweisen. Beispielsweise kann ein Address-Schema sowohl in einem Customer- als auch in einem Supplier-Schema verwendet werden.
Dieser Ansatz fördert die Wiederverwendbarkeit und Konsistenz Ihrer Schemas. Außerdem werden durch die Verwendung von Schemareferenzen klare Abhängigkeiten geschaffen, sodass explizit nachvollziehbar ist, 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 einen Verweis auf dieses gemeinsame Schema. Diese Beziehung wird formal durch eine SchemaReference-Struktur definiert.
Ein SchemaReference hat die folgenden Komponenten:
name(String): Der vollständig qualifizierte Name des Schemas, auf das für Avro-Formate verwiesen wird, 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.
In einem Schema, in dem andere Schemas verwendet werden, werden diese Abhängigkeiten in einem references-Feld deklariert. 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.
Erstellen Sie ein Subjekt mit dem Namen
address_schemaund 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 Sie das Thema und speichern Sie es als Version 1 des Themas
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
Erstellen Sie das Thema und speichern Sie es als Version 1 des Themas
address_schema_proto.syntax = "proto3"; package com.example.common; message Address { string street = 1; string city = 2; string zip_code = 3; string country = 4; }Erstellen Sie das
customer_schema-Schema. Anstatt die Adressfelder zu wiederholen, verweisen Sie auf dasaddress_schema-Schema.Avro
Der Typ
com.example.common.Addressdes FeldsbillingAddressbezieht sich auf das im vorherigen Schritt definierteAddress-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_avrowü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.protoimportiertaddress.protound verwendetcom.example.common.Addressfür das Feldbilling_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_protowürden die Metadaten eine Schemareferenz enthalten:// Conceptual metadata for customer_schema_proto "references": [ { "name": "address.proto", "subject": "address_schema_proto", "version": 1 } ]Für Ihr
Supplier-Schema würden Sie eine Schemareferenz hinzufügen, die auf dasselbe gemeinsameAddress-Schema verweist.
Schemamodus
Der Schemamodus definiert den Betriebsstatus einer Schemaregistrierung oder eines bestimmten Themas und steuert die zulässigen Arten von Änderungen. Der Schemamodus kann auf eine Registry oder ein bestimmtes Thema in einer Schema-Registry angewendet werden. Im Folgenden finden Sie die Pfade für die Ressourcen im Schemamodus:
Modus auf Registry-Ebene:Gilt für die gesamte Schema-Registry.
- Pfad:
projects/project/locations/location/schemaRegistry/schema_registry/mode
- Pfad:
Themenmodus auf Registry-Ebene:Gilt für ein bestimmtes Thema in der gesamten Schema-Registry.
- Pfad:
projects/project/locations/location/schemaRegistries/schema_registry/mode/subject
- Pfad:
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: In diesem Modus sind eingeschränkte Schreibvorgänge in der Schemaregistrierung oder im angegebenen Thema bzw. den angegebenen Themen zulässig. Sie ermöglicht Änderungen wie das Aktualisieren von Konfigurationen und das Hinzufügen neuer Schemaversionen. Dies ist der Standardmodus für neue Schemaregister und neue Themen.
Bei der Entscheidung, 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 beispielsweise eine Schemaregistrierung im Readonly-Modus befindet, ein bestimmtes Thema darin jedoch im Readwrite-Modus, sind Änderungen an diesem bestimmten Thema zulässig. Die Erstellung neuer Themen wird jedoch durch den Readonly-Modus auf Registrierungsebene eingeschränkt.
Beispiel für den Schemamodus
Angenommen, Sie haben eine Schema-Registry, deren Modus auf Readwrite festgelegt ist. Mit dieser Konfiguration können Sie der Registry neue Themen und vorhandenen Themen neue Schemaversionen hinzufügen.
Angenommen, Sie haben ein Thema mit dem Namen production-config, das Sie vor versehentlichen Änderungen schützen möchten. Sie legen den Modus für das Thema production-config auf Readonly fest. Daher gelten für das Thema production-config die folgenden Bedingungen:
Sie können dem Thema keine neuen Schemaversionen hinzufügen.
Sie können die Konfiguration (z. B. den Kompatibilitätstyp) für das Subjekt nicht aktualisieren.
Andere Elemente in der Registrierung, für die kein eigener Modus explizit festgelegt ist, bleiben im
Readwrite-Modus, sodass Sie sie weiterhin ändern können.Sie können weiterhin Subjekte in der Registry erstellen, da sich die Registry selbst noch im
Readwrite-Modus befindet.
Später können Sie die gesamte Schema-Registry in den Wartungsmodus versetzen, indem Sie den Modus auf Registry-Ebene auf Readonly festlegen. Sie haben jedoch ein weiteres Thema, staging-config, das für laufende Tests modifizierbar bleiben muss. Sie legen den Modus für das staging-config-Subjekt explizit auf Readwrite fest. Daher gelten für das staging-config-Motiv die folgenden Bedingungen:
Die Schema-Registry ist jetzt
Readonly. Sie können keine neuen Themen erstellen.Die meisten vorhandenen Themen, z. B. solche ohne spezifische Modusüberschreibung, werden auch durch Vererbung zu
Readonly. Sie können keine neuen Schemaversionen hinzufügen oder die Konfigurationen aktualisieren.Das Thema
production-configbleibtReadonly, wie explizit festgelegt.Das
staging-config-Gerät verbleibt imReadwrite-Modus, da die Einstellung auf Geräteebene denReadonly-Modus auf Registry-Ebene überschreibt. Sie können weiterhin Schemaversionen hinzufügen und Konfigurationen fürstaging-configaktualisieren.
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 Schemaregistrierung in der Produktion
Um Ihre Schemas in einer Produktionsumgebung zu schützen, wenden Sie die folgenden Konfigurationen an:
Sie können die Registrierung neuer Schemas verhindern, indem Sie
mode=READONLYfü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 Berechtigung
create versionhaben.Legen Sie in den Serialisierungsprogrammen Ihres Kafka-Clients
auto.register.schemas=falsefest. Konfigurieren Sie für Kafka Connect diese Einstellung nach Bedarf für die Schlüssel- und Wert-Serialisierer:key.serializer.auto.register.schemas=falsevalue.serializer.auto.register.schemas=false
Optional: Wenn Sie erzwingen möchten, dass Clients das aktuelle Schema für ein Thema verwenden, legen Sie
use.latest.version=trueim Serializer oder Deserializer fest. Mit dieser Einstellung wird der Client angewiesen, die neueste für das Thema registrierte Schemaversion zu verwenden und nicht die Version, die der jeweiligen Nachricht entspricht.