Schema Registry Operations¶
Operational procedures for running Schema Registry in production environments.
Deployment¶
Single Node¶
For development and testing:
# Start Schema Registry
schema-registry-start /etc/schema-registry/schema-registry.properties
Configuration:
# schema-registry.properties
listeners=http://0.0.0.0:8081
kafkastore.bootstrap.servers=kafka1:9092,kafka2:9092,kafka3:9092
kafkastore.topic=_schemas
debug=false
High Availability¶
For production, deploy multiple instances:
Configuration:
# All instances share configuration
listeners=http://0.0.0.0:8081
kafkastore.bootstrap.servers=kafka1:9092,kafka2:9092,kafka3:9092
kafkastore.topic=_schemas
kafkastore.topic.replication.factor=3
# Leader election
master.eligibility=true
Docker Deployment¶
version: '3.8'
services:
schema-registry:
image: confluentinc/cp-schema-registry:7.5.0
hostname: schema-registry
ports:
- "8081:8081"
environment:
SCHEMA_REGISTRY_HOST_NAME: schema-registry
SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: kafka1:9092,kafka2:9092,kafka3:9092
SCHEMA_REGISTRY_LISTENERS: http://0.0.0.0:8081
SCHEMA_REGISTRY_KAFKASTORE_TOPIC_REPLICATION_FACTOR: 3
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8081/"]
interval: 30s
timeout: 10s
retries: 5
Configuration¶
Essential Settings¶
| Property | Default | Description |
|---|---|---|
listeners |
http://0.0.0.0:8081 |
REST API listeners |
kafkastore.bootstrap.servers |
Required | Kafka bootstrap servers |
kafkastore.topic |
_schemas |
Schema storage topic |
kafkastore.topic.replication.factor |
3 | Replication factor |
schema.compatibility.level |
BACKWARD |
Default compatibility |
Security¶
SSL/TLS:
listeners=https://0.0.0.0:8081
ssl.keystore.location=/path/to/keystore.jks
ssl.keystore.password=password
ssl.key.password=password
ssl.truststore.location=/path/to/truststore.jks
ssl.truststore.password=password
Authentication:
authentication.method=BASIC
authentication.realm=SchemaRegistry
authentication.roles=admin,developer,readonly
Kafka Security:
kafkastore.security.protocol=SASL_SSL
kafkastore.sasl.mechanism=PLAIN
kafkastore.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="user" password="password";
Monitoring¶
Health Check¶
# Basic health check
curl http://schema-registry:8081/
# Response
{"mode": "READWRITE"}
Key Metrics¶
| Metric | Description | Alert Threshold |
|---|---|---|
kafka.schema.registry:type=master-slave-role |
Leadership status | Change events |
kafka.schema.registry:type=jersey-metrics |
API request metrics | Error rate > 1% |
kafka.schema.registry:type=json-schema-provider-metrics |
Schema operations | Latency > 100ms |
JMX Monitoring¶
Enable JMX:
export SCHEMA_REGISTRY_JMX_OPTS="-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false"
Prometheus Metrics¶
# prometheus.yml
scrape_configs:
- job_name: 'schema-registry'
static_configs:
- targets: ['schema-registry:8081']
metrics_path: /metrics
Backup and Recovery¶
Backup Strategies¶
Topic-Based Backup:
The _schemas topic contains all schema data. Backup using MirrorMaker or topic replication:
# Export schemas topic
kafka-console-consumer.sh \
--bootstrap-server kafka:9092 \
--topic _schemas \
--from-beginning \
--property print.key=true \
--property print.value=true > schemas-backup.txt
API-Based Backup:
#!/bin/bash
# backup-schemas.sh
REGISTRY_URL="http://schema-registry:8081"
BACKUP_DIR="./schema-backup"
mkdir -p $BACKUP_DIR
# Get all subjects
SUBJECTS=$(curl -s $REGISTRY_URL/subjects | jq -r '.[]')
for SUBJECT in $SUBJECTS; do
# Get all versions
VERSIONS=$(curl -s "$REGISTRY_URL/subjects/$SUBJECT/versions" | jq -r '.[]')
for VERSION in $VERSIONS; do
# Export each version
curl -s "$REGISTRY_URL/subjects/$SUBJECT/versions/$VERSION" \
> "$BACKUP_DIR/${SUBJECT}_v${VERSION}.json"
done
done
echo "Backup complete: $(ls $BACKUP_DIR | wc -l) schemas"
Recovery¶
Restore from API Backup:
#!/bin/bash
# restore-schemas.sh
REGISTRY_URL="http://schema-registry:8081"
BACKUP_DIR="./schema-backup"
for FILE in $BACKUP_DIR/*.json; do
SUBJECT=$(basename $FILE | sed 's/_v[0-9]*\.json//')
SCHEMA=$(cat $FILE | jq '.schema')
curl -X POST \
-H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data "{\"schema\": $SCHEMA}" \
"$REGISTRY_URL/subjects/$SUBJECT/versions"
done
Administration¶
Subject Management¶
# List subjects
curl http://schema-registry:8081/subjects
# Delete subject (soft)
curl -X DELETE http://schema-registry:8081/subjects/my-subject
# Delete subject (hard)
curl -X DELETE "http://schema-registry:8081/subjects/my-subject?permanent=true"
Compatibility Management¶
# Get global compatibility
curl http://schema-registry:8081/config
# Set global compatibility
curl -X PUT \
-H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"compatibility": "BACKWARD"}' \
http://schema-registry:8081/config
# Set subject compatibility
curl -X PUT \
-H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"compatibility": "FULL"}' \
http://schema-registry:8081/config/my-subject
Mode Management¶
# Get mode
curl http://schema-registry:8081/mode
# Set read-only mode
curl -X PUT \
-H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"mode": "READONLY"}' \
http://schema-registry:8081/mode
| Mode | Description |
|---|---|
READWRITE |
Normal operation |
READONLY |
Maintenance mode, no writes |
IMPORT |
Allow ID specification during restore |
Troubleshooting¶
Common Issues¶
| Issue | Cause | Solution |
|---|---|---|
| 409 Conflict | Incompatible schema | Check compatibility, update schema |
| 503 Service Unavailable | No leader elected | Check Kafka connectivity |
| 404 Not Found | Subject doesn't exist | Verify subject name |
| Connection refused | Registry not running | Check process, ports |
Debugging¶
Enable Debug Logging:
debug=true
Check Leader Status:
curl http://schema-registry:8081/v1/metadata/id
Verify Kafka Connectivity:
# Check _schemas topic
kafka-topics.sh --bootstrap-server kafka:9092 --describe --topic _schemas
# Check consumer group
kafka-consumer-groups.sh --bootstrap-server kafka:9092 --describe --group schema-registry
Schema ID Conflicts¶
If schema IDs conflict after restore:
-
Set mode to IMPORT:
curl -X PUT \ -H "Content-Type: application/vnd.schemaregistry.v1+json" \ --data '{"mode": "IMPORT"}' \ http://schema-registry:8081/mode -
Register with specific ID:
curl -X POST \ -H "Content-Type: application/vnd.schemaregistry.v1+json" \ --data '{"schema": "...", "id": 42}' \ http://schema-registry:8081/subjects/my-subject/versions -
Return to normal mode:
curl -X PUT \ -H "Content-Type: application/vnd.schemaregistry.v1+json" \ --data '{"mode": "READWRITE"}' \ http://schema-registry:8081/mode
Performance Tuning¶
Caching¶
Schema Registry caches schemas in memory. For high-throughput environments:
# Increase cache size
schema.cache.size=10000
# Cache expiry (ms)
schema.cache.expiry.ms=300000
Client Caching¶
Configure clients to cache schemas locally:
# Producer/Consumer
schema.registry.cache.capacity=1000
Connection Pooling¶
# Kafka store connection pool
kafkastore.init.timeout.ms=60000
kafkastore.timeout.ms=500
Capacity Planning¶
| Metric | Small | Medium | Large |
|---|---|---|---|
| Schemas | < 1,000 | 1,000-10,000 | > 10,000 |
| Requests/sec | < 100 | 100-1,000 | > 1,000 |
| Memory | 1 GB | 2-4 GB | 8+ GB |
| CPU | 1 core | 2-4 cores | 4+ cores |
| Instances | 2 | 3 | 3+ |
Related Documentation¶
- Schema Registry Overview - Architecture and concepts
- Schema Evolution - Safe evolution practices
- Compatibility - Compatibility modes
- Why Schemas - Schema management benefits