CCDAKで頻出のSchema Registryの要点は、スキーマ自体よりも「どのSubjectで互換性を縛るか」です。Subjectの付け方は命名戦略に依存し、スキーマ進化の自由度や再利用性、運用のしやすさを大きく左右します。
本稿では代表的な3戦略(TopicNameStrategy、RecordNameStrategy、TopicRecordNameStrategy)を比較し、実務シナリオ別の選択指針と設定例を示します。公式ドキュメントの挙動に基づき、試験対策と現場適用の両方を意識して解説します。
Schema Registryはスキーマを「Subject」単位でバージョン管理し、互換性もSubject単位で評価します。Producerはシリアライズ時にスキーマをSubjectへ登録し、メッセージにはSchema IDだけを埋め込みます。ConsumerはIDでスキーマを取得します。つまり、ワイヤ形式はSubject名を含まないため、Subjectは登録・互換性管理の境界を決めるための概念です。
命名戦略は、このSubject名をどう決めるかのルールです。主な選択肢は以下の3つです。TopicNameStrategy(既定)、RecordNameStrategy、TopicRecordNameStrategy。選択によって互換性の適用範囲(1トピック限定か、複数トピック横断か)が変わります。
Producer/ConsumerとSubjectの関係
Producer Schema Registry Consumer
| | |
| 1) Serialize(value) | |
|--> subject resolved -----| |
| (by strategy) | |
| | 2) Register or lookup |
|-------------------------> | schema under Subject |
| | -> returns Schema ID |
| 3) Send record (ID+data) | |
|-----------------------------------------------------> |
| | 4) Fetch by Schema ID <----|
| | (subject not in wire) |
TopicNameStrategyは最も安全で既定の戦略です。Subjectは <topic>-key と <topic>-value に分かれ、互換性評価は各トピックのキー/値ごとに独立します。異なるトピック間で同一スキーマを使っても、互いの進化は干渉しません。
利点は、トピック境界で変更影響を閉じ込められることです。欠点は、同一スキーマを複数トピックで共有する場合でもSubjectが分断され、スキーマの重複登録や互換性基準の分散管理が発生する点です。
設定例: 値にRecordNameStrategy、キーにTopicNameStrategyを適用する
Properties p = new Properties();
p.put("bootstrap.servers", "localhost:9092");
p.put("key.serializer", "io.confluent.kafka.serializers.KafkaAvroSerializer");
p.put("value.serializer", "io.confluent.kafka.serializers.KafkaAvroSerializer");
p.put("schema.registry.url", "http://localhost:8081");
// 既定はTopicNameStrategyだが、明示も可能
p.put("key.subject.name.strategy", "io.confluent.kafka.serializers.subject.TopicNameStrategy");
// 値だけRecordNameStrategyに切り替える例(混在可)
p.put("value.subject.name.strategy", "io.confluent.kafka.serializers.subject.RecordNameStrategy");
// 本番では自動登録を止め、最新利用へ切り替える選択肢もある
p.put("auto.register.schemas", false);
p.put("use.latest.version", true);
// 確認: 現在のSubject一覧
// curl http://localhost:8081/subjects
// 例: orders-key, orders-value, com.example.OrderCreated などが列挙されるRecordNameStrategyは、Avroの完全修飾名(namespace.name)やProtobuf/JSON Schemaのメッセージ名でSubjectを決定します。結果として、同一のレコードを複数トピックで用いる場合でも、単一のSubjectに集約され、互換性の基準も一箇所にまとまります。
利点は、スキーマ再利用の促進と互換性ポリシーの一元化です。一方、同一の完全修飾名を不注意に別スキーマで使うと衝突し得ます。名前空間の設計と命名規約、キー/値で同一レコード名を使わない配慮が重要です。
TopicRecordNameStrategyは、トピック名と完全修飾レコード名を結合してSubjectを作ります。トピック境界の独立性を保ちながら、同一トピック内で異なるレコード名を区別しやすいのが特長です。マルチイベント型のトピックを採用する場合にバランスが良い選択です。
以下の比較表では、3戦略を観点別に整理します。CCDAKでは「互換性がどの範囲に及ぶか」「いつ再利用が効くか」を問われやすい点を押さえてください。
| 観点 | TopicNameStrategy | RecordNameStrategy | TopicRecordNameStrategy |
|---|---|---|---|
| Subject例 | <topic>-key / <topic>-value | <namespace.name> | <topic>-<namespace.name> |
| 互換性の適用範囲 | 各トピックのkey/valueごと | レコード名で全トピック横断 | トピック×レコード名の組合せ |
| スキーマ再利用 | 低い(重複登録になりがち) | 高い(単一Subjectへ集約) | 中程度 |
| 衝突リスク | 低い | 中〜高(同名異スキーマで衝突) | 低〜中 |
| 向いているケース | 独立したトピック運用、初期導入 | イベント共通基盤、複数トピックで同一イベントを再利用 | マルチイベント型トピック |
| 試験の着眼点 | 影響範囲の局所化 | 横断的互換性と再利用 | バランス型の適用範囲 |
互換性レベル(Backward/Forward/Full/Transitiveなど)は、グローバル既定とSubject単位の上書きが可能です。どの戦略を採っても、最終的に「そのSubject」で評価されます。したがってRecordNameStrategyを選ぶと、複数トピックで共有する単一Subjectに対して後方互換を守る責務が重くなります。
auto.register.schemas=false と use.latest.version=true の組み合わせは、本番での事前登録・段階的ロールアウトに役立ちます。Producerが勝手に新スキーマを作らないため、互換性の破壊を未然に防ぎやすくなります。
現状のトピックとイベント一覧を作り、どれが複数トピックで共有されるかを確認します。共有が多いならRecordNameStrategy、トピックごとに独立しているならTopicNameStrategyが自然です。マルチイベント型トピックではTopicRecordNameStrategyも検討します。
移行は新しいProducer設定から開始し、既存メッセージはそのままにします。ワイヤ形式はSchema IDで解決されるため、Consumerは影響を受けません。ただし、移行後は新旧のSubjectが並存します。Registry側の互換性ポリシーとSubject数の増加を監視してください。
CCDAK
問題 1
複数のトピック(orders, orders_dlq, orders_analytics)で同一のイベント型 OrderCreated を共有し、スキーマ互換性を1箇所で一元管理したい。適切なSubject命名戦略はどれか?
正解: A
RecordNameStrategyは完全修飾レコード名をSubjectとして用いるため、同一イベント型を複数トピックで共有しても単一Subjectに集約でき、互換性管理を一元化しやすい。TopicNameStrategyはトピックごとにSubjectが分かれ、TopicRecordNameStrategyはトピック×レコード名で分かれるため、一元化の度合いはRecordNameStrategyに劣る。
互換性レベルはどこで設定され、どの範囲に効きますか?
グローバル既定(/config)とSubject単位(/config/{subject})で設定できます。評価はSubject単位で行われるため、どの命名戦略でも最終的には「そのSubject」の互換性ポリシーに従います。
RecordNameStrategyで同一の完全修飾名を別スキーマに使ってしまった場合は?
同一Subjectに衝突として現れ、登録や互換性チェックで問題になります。名前空間を厳格に設計し、レコード名の再利用規約を設け、スキーマレビューを通す運用が必要です。
TopicNameStrategyからRecordNameStrategyへ切り替える際、Consumerに影響はありますか?
通常ありません。メッセージのワイヤ形式はSchema IDのみを含み、ConsumerはIDでスキーマを解決します。新しい戦略は新しいSubjectで登録されますが、既存メッセージは旧Subjectに紐づくIDのままです。移行期間中はSubjectの並存と互換性設定を監視してください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Kafka Topic と Partition の基礎: 分散とスケーラビリティの要
CCDAK 対策と実務の両立を意識し、Topic/Partition/Replica/Consumer Group の役...
CCDAK 試験ガイド:出題範囲・配点・申込み・対策
Confluent Certified Developer for Apache Kafka (CCDAK) の出題範囲...
Confluent Certified Administrator (CCAAK) 対策: 出題範囲・配点の考え方・運用観点の要点
CCAAKに向けて、試験領域の押さえどころを運用目線で整理。プロダクションで通用する設定・監視・セキュリティの実践知を、...
Kafka の Replica と In-Sync Replicas を正しく設計する: 耐障害性と一貫性
レプリカとISRの仕組みを起点に、acks と min.insync.replicas、クリーン/アンクリーンリーダー選...
Kafka の Offset とコミット: ポジション管理と at-least-once の基礎
CCDAK 対策と実務の両立を意識して、Kafka コンシューマのオフセット管理とコミット戦略を整理。at-least-...