3. Schema Consistency I — Schema Compatibility Enforcer
01. Pattern Overview
- Schema Compatibility Enforcer는 스키마 변경 자체를 통제하는 패턴.
- 데이터 producer가 스키마를 변경할 때, 그 변경이 기존 consumer를 깨뜨리지 않는지를 호환성 규칙으로 검증
02. 3가지 Enforcement 모드
1) External Service/Library 모드 — Schema Registry 같은 외부 서비스가 스키마를 버전 관리하고, producer가 데이터를 쓰기 전에 스키마를 검증한다. 호환성 규칙을 명시적으로 설정
# Kafka Schema Registry를 통한 스키마 등록 및 호환성 검증# 스키마 정의 (Avro)schema = { "type": "record", "namespace": "com.example", "name": "Visit", "fields": [ {"name": "visit_id", "type": "string"}, {"name": "event_time", "type": "int", "logicalType": "date"} ]}
# Schema Registry에 FORWARD compatibility로 설정된 상태에서# producer가 visit_id 필드를 제거한 새 스키마로 쓰려고 시도하면:# → 409 에러 발생# "Schema being registered is incompatible with an earlier schema"# "READER_FIELD_MISSING_DEFAULT_VALUE: visit_id has no default# value and is missing in the new schema"2) Implicit with Inserts 모드 — Delta Lake, RDBMS 같은 저장소가 테이블 생성 시 정의된 스키마와 다른 데이터를 쓰려고 하면 자동으로 거부.
# Delta Lake implicit schema enforcement# 기존 테이블 스키마: visit_id(string), page(string), event_time(long)
# producer가 ad_id 컬럼을 추가한 데이터를 쓰려고 시도new_data = spark.createDataFrame([ ("v1", "/home", 1700000000, "ad_123")], ["visit_id", "page", "event_time", "ad_id"])
new_data.write.format("delta").mode("append").save(table_path)# → AnalysisException 발생# "A schema mismatch detected when writing to the Delta table"# Table schema: visit_id, page, event_time# Data schema: visit_id, page, event_time, ad_idDelta Lake는 명시적으로 mergeSchema 옵션을 켜지 않는 한, 스키마 변경을 허용하지 않는다.
3) Event-driven for DDL 모드 — PostgreSQL, SQL Server 같은 RDBMS에서 DDL 이벤트 트리거를 걸어, DROP COLUMN이나 RENAME COLUMN 같은 스키마 변경 시도를 가로채서 검증하거나 롤백
# PostgreSQL: DDL event trigger로 스키마 변경 방지# (SQL로 정의하지만 개념 이해를 위해 pseudo-code로 표현)
# CREATE EVENT TRIGGER prevent_column_drop# ON ddl_command_start# WHEN TAG IN ('ALTER TABLE')# EXECUTE FUNCTION check_schema_compatibility();
# 또는 더 간단한 방법: ALTER TABLE 권한 자체를 부여하지 않음# REVOKE ALTER ON TABLE visits FROM data_producer_role;04. 호환성 모드 (Compatibility Modes)
Schema Registry를 사용할 때 설정할 수 있는 호환성 모드는 크게 3가지이며, 각각 transitive/nontransitive 변형이 있다.
Backward Compatibility — 새 스키마를 쓰는 consumer가 이전 스키마로 생산된 데이터를 읽을 수 있다. 허용 액션: 필드 삭제, optional 필드 추가.
Forward Compatibility — 이전 스키마를 쓰는 consumer가 새 스키마로 생산된 데이터를 읽을 수 있다. 허용 액션: 필드 추가, optional 필드 삭제.
Full Compatibility — backward + forward 모두 보장. 허용 액션: optional 필드 추가/삭제만 가능.
05. Transitive vs Nontransitive
Nontransitive — 직전 버전과의 호환성만 검증 (v(n) ↔ v(n-1)).
Transitive — 모든 이전/이후 버전과의 호환성을 검증 (v(n) ↔ v(0), v(1), …, v(n-1)).
# Backward compatibility에서 transitive가 깨지는 시나리오
# v0: order_id LONG REQUIRED# v1: order_id LONG REQUIRED, amount DOUBLE DEFAULT 0.0 ← optional 추가 (OK)# v2: order_id LONG REQUIRED, amount DOUBLE REQUIRED ← default 제거 (?)
# Nontransitive 관점 (v2 ↔ v1만 비교):# v2 consumer가 v1 데이터를 읽을 때 → amount에 default 0.0이 있으므로 OK ✓
# Transitive 관점 (v2 ↔ v0도 비교):# v2 consumer가 v0 데이터를 읽을 때 → amount 필드 자체가 없고 default도 없음 ✗# → 호환성 위반!v1 → v2 진화는 nontransitive에서는 유효하지만, transitive에서는 v0과의 호환성이 깨져서 거부된다. 이것이 transitive 모드가 더 엄격하지만 더 안전한 이유다.
Consequences
Interaction overhead — 특히 external service 모드에서, producer는 매 레코드마다 Schema Registry에 최신 스키마 버전을 확인해야 하므로 추가 네트워크 비용이 발생
Schema evolution 난이도 상승 — 호환성 규칙 때문에 필드 rename 같은 단순한 작업도 “새 필드 추가 → 구 필드 deprecate” 같은 우회 경로 필요
Concept
- Schema Compatibility Enforcer : 스키마 변경이 기존 consumer를 깨뜨리지 않도록 호환성 규칙으로 통제하는 패턴
- External Service 모드 : Schema Registry 같은 외부 서비스가 스키마를 버전 관리하고 호환성을 검증. 명시적 호환성 모드 설정 가능
- Implicit with Inserts 모드 : Delta Lake, RDBMS가 현재 테이블 스키마와 다른 데이터 쓰기를 자동 거부. 별도 호환성 모드 없음
- Event-driven for DDL 모드 : DDL 이벤트 트리거로 스키마 변경 시도를 가로채서 검증/롤백. PostgreSQL, SQL Server 지원
- Backward Compatibility : 새 스키마 consumer가 이전 스키마 데이터를 읽을 수 있음. 필드 삭제, optional 필드 추가 허용
- Forward Compatibility : 이전 스키마 consumer가 새 스키마 데이터를 읽을 수 있음. 필드 추가, optional 필드 삭제 허용
- Full Compatibility : backward + forward 모두 보장. optional 필드 추가/삭제만 가능
- Transitive Compatibility : 모든 과거/미래 스키마 버전과 호환성을 보장. Nontransitive보다 엄격하지만 안전
- Nontransitive Compatibility : 직전 버전과의 호환성만 보장. 더 유연하지만 버전 간 간접적 비호환 가능성 존재
- Schema Registry : Apache Kafka 생태계에서 스키마를 중앙 관리하고 호환성을 검증하는 서비스. Confluent Schema Registry가 대표적