Pendaftaran Skema dan Evolusi Kontrak Avro
Kuatkuasakan kontrak peristiwa dengan pendaftaran skema dan kembangkan muatan menggunakan peraturan keserasian.
Pendaftaran Skema dan Evolusi Kontrak Avro ialah pelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Kem Intensif Pembangunan Bahagian Belakang FastAPI merangkumi sejumlah 4 pelajaran.
Mengapa Kontrak Peristiwa Memerlukan Daftar
Dalam bahagian belakang FastAPI dipacu peristiwa, perkhidmatan anda menerbitkan peristiwa ke Kafka atau Pulsar dan banyak pengguna bebas membacanya. Muatan peristiwa ialah kontrak: pengeluar dan pengguna mesti bersetuju tentang nama medan, jenis dan struktur.
- Jika pengeluar menamakan semula
user_idkepadauserId, setiap pengguna rosak secara senyap. - JSON biasa tidak mempunyai bentuk yang dikuatkuasakan, jadi kesilapan ejaan terus dihantar ke persekitaran produksi.
Daftar Skema menyimpan skema berversi secara berpusat dan menolak mesej yang melanggar kontrak yang dipersetujui, lalu memisahkan pasukan sambil memastikan data selamat.
Avro: Format Padat Berasaskan Skema
Apache Avro ialah format pensirian yang paling biasa digunakan bersama daftar skema. Setiap rekod diterangkan oleh skema JSON, dan muatan perduaan itu sendiri tidak membawa nama medan, hanya nilai, menjadikannya padat.
- Skema mentakrifkan
name,type,fieldsdan nilaidefaultpilihan. - Pembaca memerlukan skema untuk menyahkod bait, dan itulah sebabnya daftar tersebut wujud.
Di bawah ialah skema Avro minimum untuk peristiwa OrderCreated.
order_created_schema = {
"type": "record",
"name": "OrderCreated",
"namespace": "com.shop.events",
"fields": [
{"name": "order_id", "type": "string"},
{"name": "user_id", "type": "string"},
{"name": "amount_cents", "type": "long"},
{"name": "currency", "type": "string"},
],
}
print(order_created_schema["name"], "has", len(order_created_schema["fields"]), "fields")Mensiri Rekod dengan fastavro
Pustaka Python tulen fastavro membolehkan anda mengekod dan menyahkod rekod Avro tanpa broker. Susun atur bait ini sama seperti yang akan dihantar oleh pengeluar anda ke Kafka.
parse_schemamengesahkan skema sekali.schemaless_writermenulis badan perduaan;schemaless_readermenyahkodnya.
Perhatikan bahawa bait yang dikodkan hanya mengandungi nilai, bukan nama medan.
import io
from fastavro import parse_schema, schemaless_writer, schemaless_reader
schema = parse_schema({
"type": "record",
"name": "OrderCreated",
"fields": [
{"name": "order_id", "type": "string"},
{"name": "amount_cents", "type": "long"},
],
})
record = {"order_id": "o-123", "amount_cents": 4999}
buf = io.BytesIO()
schemaless_writer(buf, schema, record)
encoded = buf.getvalue()
print("encoded bytes:", encoded)
buf.seek(0)
decoded = schemaless_reader(buf, schema)
print("decoded:", decoded)Format Wayar Confluent
Apabila anda menerbitkan melalui daftar, nilainya bukan Avro mentah. Pensiri Confluent menambahkan pengepala 5 bait supaya pengguna tahu skema yang perlu diambil.
- Bait 0: bait ajaib, sentiasa
0x00. - Bait 1-4: ID skema 4 bait tertib big-endian.
- Baki bait: badan Avro tanpa skema.
Pengguna membaca ID tersebut, memuat turun versi skema yang tepat daripada daftar, kemudian menyahkod badan. Inilah cara muatan lama dan baharu wujud bersama pada topik yang sama.
import struct
MAGIC = 0
schema_id = 42
avro_body = b"\x0co-1234\x9eL" # pretend Avro bytes
frame = struct.pack(">bI", MAGIC, schema_id) + avro_body
print("wire bytes:", frame)
magic, sid = struct.unpack(">bI", frame[:5])
print("magic:", magic, "schema_id:", sid)
print("body:", frame[5:])Mendaftarkan Skema semasa Permulaan FastAPI
Pola yang kemas ialah mendaftarkan skema pengeluar anda sekali semasa permulaan aplikasi menggunakan API REST daftar. Daftar tersebut mengembalikan ID skema yang stabil untuk digunakan semula bagi setiap mesej.
- Subjek secara lalai mengikut konvensyen
<topic>-value. - Mendaftarkan skema yang sama adalah idempoten: anda menerima ID yang sama semula.
Coretan ini menghantar skema Avro kepada daftar yang serasi dengan Confluent.
import json
import httpx
REGISTRY_URL = "http://schema-registry:8081"
async def register_schema(subject: str, avro_schema: dict) -> int:
payload = {"schema": json.dumps(avro_schema)}
async with httpx.AsyncClient() as client:
resp = await client.post(
f"{REGISTRY_URL}/subjects/{subject}/versions",
json=payload,
headers={"Content-Type": "application/vnd.schemaregistry.v1+json"},
)
resp.raise_for_status()
return resp.json()["id"]
# Called inside FastAPI's lifespan startup:
# schema_id = await register_schema("orders-value", order_created_schema)Mod Keserasian: Keputusan Teras
Daftar menguatkuasakan dasar evolusi bagi setiap subjek. Mod yang anda pilih menentukan perubahan skema yang dibenarkan dan menetapkan susunan naik taraf anda.
- BACKWARD (lalai): skema baharu boleh membaca data yang ditulis oleh skema sebelumnya. Naik taraf pengguna dahulu.
- FORWARD: skema sebelumnya boleh membaca data yang ditulis oleh skema baharu. Naik taraf pengeluar dahulu.
- FULL: kedua-dua arah dipenuhi. Susunan tidak penting.
- *_TRANSITIVE: pemeriksaan dijalankan terhadap semua versi terdahulu, bukan versi terkini sahaja.
Kebanyakan pasukan menggunakan BACKWARD sebagai lalai kerana pengguna biasanya ketinggalan berbanding pengeluar.
Perubahan Serasi Ke Belakang: Tambah Medan Dengan Nilai Lalai
Di bawah keserasian BACKWARD, anda boleh menambah medan hanya jika medan itu mempunyai nilai lalai. Pengguna yang menggunakan skema baharu ketika membaca mesej lama hanya mengisi nilai lalai; medan yang dibuang juga memerlukan medan lama mempunyai nilai lalai.
- Menambah
discount_centsdengandefault: 0adalah selamat. - Menambahnya tanpa nilai lalai akan ditolak kerana rekod lama tidak mempunyai nilai untuk dibekalkan.
Versi baharu di bawah mengembangkan peristiwa pesanan dengan selamat.
order_v2 = {
"type": "record",
"name": "OrderCreated",
"namespace": "com.shop.events",
"fields": [
{"name": "order_id", "type": "string"},
{"name": "user_id", "type": "string"},
{"name": "amount_cents", "type": "long"},
{"name": "currency", "type": "string"},
# NEW field is backward compatible ONLY because of the default
{"name": "discount_cents", "type": "long", "default": 0},
],
}
print("fields in v2:", [f["name"] for f in order_v2["fields"]])Membaca Bait Lama Dengan Skema Baharu
Avro menyelesaikan perbezaan antara skema penulis (digunakan untuk mengekod) dan skema pembaca (digunakan untuk menyahkod). Apabila pembaca mempunyai medan baharu dengan nilai lalai, penyahkodan bait lama memasukkan nilai lalai itu secara automatik.
- Hantar kedua-dua skema kepada
schemaless_readersebagai pembaca dan penulis. discount_centsyang tiada akan muncul sebagai nilai lalainya,0.
Inilah yang menjadikan evolusi BACKWARD tidak memecahkan sistem dalam produksi.
import io
from fastavro import parse_schema, schemaless_writer, schemaless_reader
writer = parse_schema({
"type": "record", "name": "OrderCreated",
"fields": [{"name": "order_id", "type": "string"},
{"name": "amount_cents", "type": "long"}],
})
reader = parse_schema({
"type": "record", "name": "OrderCreated",
"fields": [{"name": "order_id", "type": "string"},
{"name": "amount_cents", "type": "long"},
{"name": "discount_cents", "type": "long", "default": 0}],
})
buf = io.BytesIO()
schemaless_writer(buf, writer, {"order_id": "o-9", "amount_cents": 1500})
buf.seek(0)
out = schemaless_reader(buf, writer, reader)
print(out) # discount_cents filled from defaultPerubahan Memecahkan Sistem yang Ditolak oleh Daftar
Sesetengah penyuntingan tidak mungkin serasi dan pemeriksaan keserasian daftar (permintaan awal POST .../compatibility/subjects/<s>/versions/latest) akan mengembalikan is_compatible: false.
- Menamakan semula medan (ia menjadi penambahan + pembuangan tanpa alias).
- Menukar jenis dengan cara yang tidak serasi, contohnya
stringkepadalong. - Menambah medan wajib tanpa nilai lalai di bawah BACKWARD.
Untuk menamakan semula dengan selamat, gunakan alias Avro supaya pembaca memetakan nama lama kepada nama baharu.
# Safe rename using aliases: old name "user_id" -> new "customer_id"
renamed = {
"type": "record",
"name": "OrderCreated",
"fields": [
{"name": "order_id", "type": "string"},
{
"name": "customer_id",
"type": "string",
"aliases": ["user_id"],
},
{"name": "amount_cents", "type": "long"},
],
}
for f in renamed["fields"]:
print(f["name"], f.get("aliases", []))Memeriksa Keserasian dalam CI Sebelum Pelancaran
Kesannya, perubahan yang memecahkan sistem dapat dikesan sebelum sampai ke broker dengan memanggil titik akhir keserasian daftar daripada saluran paip CI anda. Jika skema yang dicadangkan tidak serasi, gagalkan binaan.
- Ini melindungi setiap pengguna tanpa menjalankan satu mesej pun melalui Kafka.
- Jalankannya sebagai langkah dalam kerja yang sama yang membina imej FastAPI anda.
Pembantu ini mengembalikan True hanya apabila daftar meluluskan versi baharu.
import json
import httpx
REGISTRY_URL = "http://schema-registry:8081"
async def is_compatible(subject: str, new_schema: dict) -> bool:
url = f"{REGISTRY_URL}/compatibility/subjects/{subject}/versions/latest"
async with httpx.AsyncClient() as client:
resp = await client.post(
url,
json={"schema": json.dumps(new_schema)},
headers={"Content-Type": "application/vnd.schemaregistry.v1+json"},
)
resp.raise_for_status()
return resp.json()["is_compatible"]
# In CI:
# ok = await is_compatible("orders-value", order_v2)
# if not ok: raise SystemExit("Schema change is incompatible")Menghasilkan dan Menggunakan dengan confluent-kafka
Dalam produksi, anda membiarkan pensiri mengendalikan format wayar dan carian daftar. confluent-kafka AvroSerializer mendaftarkan skema, menambahkan ID dan mengekod badan; AvroDeserializer melakukan proses sebaliknya.
- Pensiri menyimpan ID skema dalam cache, jadi daftar jarang diakses.
- Pengguna secara telus mengambil apa sahaja skema penulis yang digunakan untuk mengekod setiap mesej.
Inilah penghubung antara penerbit peristiwa FastAPI anda dengan perkhidmatan hiliran.
from confluent_kafka.schema_registry import SchemaRegistryClient
from confluent_kafka.schema_registry.avro import AvroSerializer
from confluent_kafka import Producer
sr = SchemaRegistryClient({"url": "http://schema-registry:8081"})
schema_str = '''
{"type":"record","name":"OrderCreated",
"fields":[{"name":"order_id","type":"string"},
{"name":"amount_cents","type":"long"}]}
'''
serializer = AvroSerializer(sr, schema_str)
producer = Producer({"bootstrap.servers": "kafka:9092"})
# producer.produce(topic="orders",
# value=serializer({"order_id": "o-1", "amount_cents": 999}, ctx))Semakan Ringkas: Memilih Mod Keserasian
Pasukan anda perlu menambah medan pilihan baharu pada peristiwa Kafka, dan anda tidak boleh menggunakan semula setiap pengguna pada saat yang sama dengan pengeluar. Pengguna biasanya ketinggalan berbanding pengeluar dalam pelancaran.
Ringkasan: Kontrak yang Berkembang dengan Selamat
Sekarang anda tahu cara menguatkuasakan dan mengembangkan kontrak peristiwa dalam bahagian belakang FastAPI dipacu peristiwa.
- Daftar Skema menyimpan skema berversi dan mengeluarkan ID skema yang disematkan dalam format wayar Confluent (bait ajaib + ID 4 bait + badan Avro).
- Avro memisahkan skema penulis dan pembaca, lalu menyelesaikan perbezaan melalui nilai lalai dan alias.
- BACKWARD (lalai yang biasa) bermaksud skema baharu membaca data lama: tambah medan hanya dengan nilai lalai, dan naik taraf pengguna dahulu.
- FORWARD menaik taraf pengeluar dahulu; FULL membenarkan mana-mana susunan; varian TRANSITIVE memeriksa semua versi terdahulu.
- Jalankan pemeriksaan keserasian dalam CI daftar untuk menyekat perubahan yang memecahkan sistem sebelum sampai ke Kafka atau Pulsar.
Anggap skema anda sebagai kod: versikan, semak dan biarkan daftar melindungi kontrak tersebut.
Pelajari Kem Intensif Pembangunan Bahagian Belakang FastAPI dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 21
- Pelajaran
- 84
Soalan Lazim
Adakah pelajaran “Pendaftaran Skema dan Evolusi Kontrak Avro” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI, termasuk “Pendaftaran Skema dan Evolusi Kontrak Avro”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Kem Intensif Pembangunan Bahagian Belakang FastAPI merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Pendaftaran Skema dan Evolusi Kontrak Avro”?
Kuatkuasakan kontrak peristiwa dengan pendaftaran skema dan kembangkan muatan menggunakan peraturan keserasian. Anda berlatih Kem Intensif Pembangunan Bahagian Belakang FastAPI menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Kem Intensif Pembangunan Bahagian Belakang FastAPI?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.
Berapa lamakah pelajaran “Pendaftaran Skema dan Evolusi Kontrak Avro” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI ini?
Ya. Setiap pelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Menghasilkan dan Menggunakan Peristiwa Kafka Secara Tak Segerak
- Pendaftaran Skema dan Evolusi Kontrak Avro
- Corak Peti Keluar Transaksi
- Pengguna Idempoten dan Semantik Tepat Sekali