Upstream schema changes are one of the biggest causes of pipeline failures in both streaming and batch ingestion. Databricks absorbs these changes safely by combining Confluent Schema Registry integration, Auto Loader's schema inference and evolution, and Delta Lake's schema evolution. This article organizes these patterns from both a production and exam-prep perspective.
A schema registry is a service that centrally manages message schema definitions (field names, types, and default values). It's used with messaging systems like Kafka to guarantee schema compatibility between producers and consumers.
| Compatibility Mode | Allowed Changes | Use Case |
|---|---|---|
| BACKWARD | Remove fields, add fields with defaults | When consumers are updated first |
| FORWARD | Add fields, remove fields with defaults | When producers are updated first |
| FULL | Only add/remove fields that have defaults | When the producer/consumer update order is unpredictable |
When reading Avro-encoded Confluent Kafka topics from Databricks, you deserialize using from_avro combined with the schema registry URL.
from pyspark.sql.functions import col
from pyspark.sql.avro.functions import from_avro
schema_registry_options = {
"schema.registry.url": "https://your-registry.confluent.cloud",
"confluent.schema.registry.basic.auth.credentials.source": "USER_INFO",
"confluent.schema.registry.basic.auth.user.info": "<API_KEY>:<API_SECRET>"
}
df = (spark.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "broker:9092")
.option("subscribe", "orders-topic")
.option("startingOffsets", "latest")
.load()
.select(
from_avro(
col("value"),
"orders-value",
schema_registry_options
).alias("data")
)
.select("data.*")
)The second argument to from_avro is the subject name in Schema Registry (typically topic-name-value). Because the schema ID is included in the message header, even if the producer updates the schema, consumers can dynamically fetch the schema from the registry and deserialize.
Auto Loader (cloudFiles) incrementally ingests files from cloud storage and supports automatic schema inference and evolution. For file-based (rather than Kafka) ingestion, it's the workhorse for schema management.
| Option | Value | Behavior |
|---|---|---|
| cloudFiles.inferColumnTypes | true | Infer types via sampling (default treats everything as string) |
| cloudFiles.schemaEvolutionMode | addNewColumns | Automatically adds new columns to the schema when detected |
| cloudFiles.schemaEvolutionMode | rescue | Captures unknown columns in _rescued_data |
| cloudFiles.schemaEvolutionMode | failOnNewColumns | Stops the stream when new columns are detected |
| cloudFiles.schemaEvolutionMode | none | Locks in the initial inferred schema and ignores changes |
| cloudFiles.schemaLocation | Path | Storage location for the inferred schema (can be separated from the checkpoint) |
df = (spark.readStream
.format("cloudFiles")
.option("cloudFiles.format", "json")
.option("cloudFiles.inferColumnTypes", "true")
.option("cloudFiles.schemaEvolutionMode", "addNewColumns")
.option("cloudFiles.schemaLocation", "/mnt/schema/orders")
.load("/mnt/landing/orders/")
)Schema files saved at schemaLocation are loaded on the next stream start. In addNewColumns mode, when new columns are detected the stream temporarily restarts and the schema file is updated.
When writing to Delta tables, you control how schema differences are handled with mergeSchema and overwriteSchema.
# mergeSchema: add new columns (existing columns are preserved)
(df.writeStream
.format("delta")
.option("mergeSchema", "true")
.option("checkpointLocation", "/mnt/checkpoints/orders")
.outputMode("append")
.toTable("silver.orders")
)
# overwriteSchema: replace the entire schema (destructive change)
(df.write
.format("delta")
.mode("overwrite")
.option("overwriteSchema", "true")
.saveAsTable("silver.orders_v2")
)| Comparison Axis | Avro | JSON |
|---|---|---|
| Serialization format | Binary (compact) | Text (human-readable) |
| Schema embedding | Schema ID embedded in header | No schema (self-describing) |
| Schema Registry integration | Native support | Optional (json-schema integration available) |
| Compatibility checks | Automatically validated by the registry | Managed manually |
| Message size | Small (30-50% reduction) | Large (includes field names every time) |
| Debugging ease | Requires dedicated tooling | Readable as-is |
| Recommended use case | High-throughput production pipelines | Development, prototyping, log collection |
Here is a typical schema management flow that combines a Kafka source, Auto Loader, and Delta Lake.
[Producer]
│ Avro + Schema Registry (BACKWARD compatible)
v
[Kafka Topic]
│ from_avro + schema_registry_options
v
[Databricks Streaming Job]
│ schema change detected
├─ new column → add to Delta with mergeSchema=true
└─ type change → stop stream → manual schema migration
v
[Delta Table (Silver)]
│ final validation via NOT NULL / CHECK constraints
v
[Delta Table (Gold)][Cloud Storage (JSON/CSV/Parquet)]
│ Auto Loader (cloudFiles)
│ schemaEvolutionMode = addNewColumns
│ schemaLocation = /mnt/schema/xxx
v
[Databricks Streaming Job]
│ mergeSchema=true
v
[Delta Table (Bronze → Silver)]Data Engineer Associate / Professional
問題 1
You're ingesting JSON files from cloud storage with Auto Loader. The upstream system may add new columns, and you want to automatically add them to the Delta table without stopping the pipeline. Which combination of settings is best?
正解: A
addNewColumns mode updates the schema file and restarts the stream when new columns are detected, and mergeSchema=true adds them to the Delta table. failOnNewColumns stops the stream, which doesn't meet the requirement. rescue only captures new columns in _rescued_data without auto-adding them. none mode locks the schema, so new columns are ignored.
Can you manage schemas in Databricks without Confluent Schema Registry?
Yes. Combining Auto Loader's schemaEvolutionMode with Delta Lake's schema evolution (mergeSchema) lets you handle schema management entirely within Databricks. Confluent Schema Registry becomes necessary when you need to centrally manage Avro schema compatibility across multiple producers/consumers in the Kafka ecosystem. When Databricks is only a consumer, Auto Loader plus Delta is often sufficient.
What happens when you set Auto Loader's schemaEvolutionMode to 'rescue'?
In rescue mode, data for columns that don't match the existing schema is captured as a JSON string in a special _rescued_data column. The pipeline keeps running, and known columns are processed normally. You can analyze _rescued_data later to decide whether to add new columns, which is ideal when you want to safely evaluate the impact of schema changes.
Should you use Avro or JSON as the Kafka message format?
Choose Avro when you need strict schema compatibility management, and JSON when you prioritize flexibility and readability. Avro integrates natively with Schema Registry and produces smaller messages via binary serialization. JSON works without Schema Registry and is easier to debug, but you have to manage schema-evolution compatibility checks yourself. Avro is the common choice for high-throughput production pipelines.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
Databricks Certifications: All 7 Exams, Difficulty & Study Plan (2026)
Complete guide to all 7 Databricks certifications — Data Eng...
Databricks Exam Difficulty Ranking: All 7 Certs Compared (2026)
Every Databricks certification ranked by difficulty, with st...
Databricks Study Guide: Fastest Pass Route & Time Estimates (2026)
How to pass Databricks certifications efficiently. Official ...
Databricks Data Engineer Associate: Complete Guide (2026)
Domain-by-domain breakdown of the Databricks Certified Data ...
Databricks Data Engineer Professional: Complete Guide (2026)
Tactics for the Databricks Certified Data Engineer Professio...