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
Sie ändern Ihre Schemadefinition. Fügen Sie beispielsweise Ihrer
.proto- oder.avsc-Datei ein optionales Feld hinzu.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, 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.
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.Der Producer (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 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
- 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:
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
- Pfad:
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 alsBackward.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 alsForward.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 alsFull.
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-eventsregistriert 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
Nonenicht als Kompatibilitätstypstrategie, da Sie sonst riskieren, dass Clients aufgrund von Schemaänderungen nicht mehr funktionieren.Wählen Sie eine aufwärtskompatible Strategie wie
ForwardoderForward-transitive, wenn Sie zuerst Produzenten aktualisieren möchten. Wählen Sie eine abwärtskompatible Strategie wieBackwardoderBackward-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.
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 und speichern Sie dies als Subjekt
address_schema_avroVersion 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_protoVersion 1.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 FeldsbillingAddressverweist auf das im vorherigen Schritt definierteAddressSchema.{ "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 } ]Ebenso würden Sie für Ihr
Supplier-Schema eine Schemareferenz hinzufügen, die auf dasselbe gemeinsameAddress-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
- Pfad:
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
- 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: 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
Readwritebestehen, sodass Sie sie weiterhin ändern können.Sie können weiterhin Subjekte in der Registry erstellen, da sich die Registry selbst weiterhin im Modus
Readwritebefindet.
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-configbleibt wie explizit festgelegtReadonly.Das Subjekt
staging-configbleibt im ModusReadwrite, da die Einstellung auf Subjektebene den ModusReadonlyauf 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 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=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
create versionBerechtigung haben.Legen Sie in Ihren Kafka-Client-Serialisierern
auto.register.schemas=falsefest. Konfigurieren Sie diese Einstellung für Kafka Connect nach Bedarf für die Schlüssel- und Wertserialisierer:key.serializer.auto.register.schemas=falsevalue.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=trueim 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.