Kafka

Kafka における JSON Schema 運用の勘所:メリットと Avro との実務比較

2026-04-19
NicheeLab編集部

Kafka でのスキーマ管理は、データ品質と進化(schema evolution)を両立させる核心機能です。Confluent Schema Registry は Avro/JSON Schema/Protobuf をサポートしますが、JSON Schema は可視性と多言語連携に強みがある一方で、型の厳密さやデータサイズでは Avro に劣ることがあります。

本稿では、JSON Schema の採用判断、互換性モード、命名戦略、進化ルール、監視・性能の要点を、Avro との比較を交えて整理します。CCDAK(Confluent Certified Developer for Apache Kafka)受験者が押さえるべき論点も明示します。

JSON Schema を Kafka で使う理由と前提

JSON Schema は、人間が読みやすい JSON 形式のままスキーマ拘束をかけられる点が強みです。可観測性(目視デバッグ)や、HTTP 系サービスとの親和性が高く、クライアントが軽量な実装でも取り回しやすい特徴があります。一方で Avro のようなバイナリ最適化はなく、ペイロードサイズやシリアライズ CPU コストでは不利になりがちです。

Kafka で JSON Schema を使う場合、Confluent Schema Registry と Confluent の JSON Schema Serializer/Deserializer(KafkaJsonSchemaSerializer / KafkaJsonSchemaDeserializer)を利用するのが一般的です。互換性(BACKWARD/FORWARD/FULL とその transitive)やサブジェクト命名戦略(TopicNameStrategy など)は Avro と同様に運用できます。

  • 長所: 人が読める、ツール不要で検証しやすい、Web/モバイル含む多様なクライアントと相性◎
  • 短所: サイズ増、CPU 負荷増、厳密な型表現(decimal, fixed など)や論理型は Avro ほど豊富でない
  • 前提: Schema Registry 必須。Confluent 実装の互換性チェックに従う(docs.confluent.io を参照)

Kafka × JSON Schema データフロー(概念)

ProducerJSON Schema Serializermagic byte + schema idKafkaSchema RegistryJSON Schema DeserializerConsumerスキーマは Registry に登録され、メッセージには schema id が付与される。互換性モードは Subject ごとに設定可能。

互換性モードとスキーマ進化:JSON Schema の安全な変更

Schema Registry は JSON Schema に対しても BACKWARD / FORWARD / FULL とそれぞれの transitive 互換性を提供します。実装は Confluent の互換性チェッカに依存し、required/optional、enum、型の変更などを中心に安全性を評価します。format や一部の拡張キーワードは互換性判定に影響しない場合がある点に注意してください。

運用では、まず BACKWARD_TRANSITIVE を既定にして、既存コンシューマの破壊を防ぐのが無難です。JSON Schema では additionalProperties の既定が true のため、予期しないフィールド流入を防ぐには false を明示し、許可する追加は properties に列挙します。

  • 安全な追加: optional な新フィールド(required に含めない、あるいは default を与える)
  • 危険な変更: 型の縮小(number → integer など)、必須化、enum 値の削除
  • 互換性設定は Subject 単位。transitive により“全バージョンとの互換”を担保可能

互換性モードの設定(Schema Registry REST API)

curl -s -X PUT \
  -H 'Content-Type: application/json' \
  --data '{"compatibility": "BACKWARD_TRANSITIVE"}' \
  http://localhost:8081/config/my-topic-value

# 互換性の確認
curl -s http://localhost:8081/config/my-topic-value | jq

命名戦略・サブジェクト設計・バージョニング

サブジェクト名は互換性と独立展開の単位です。1 トピックに 1 種類のイベントであれば TopicNameStrategy、複数イベント型を 1 トピックに詰めるなら RecordNameStrategy か TopicRecordNameStrategy を選びます。JSON Schema でも Avro と同様に選べます。

バージョニングは“後方互換を崩さない”を原則に、破壊的変更が必要な場合は新サブジェクトや新トピックに分岐させます。JSON Schema の additionalProperties と required の扱いがバージョン間差分の主因になりやすいため、チーム規約で明文化しておくと事故を減らせます。

  • TopicNameStrategy: <topic>-value / <topic>-key に集約。単一イベント型向き
  • RecordNameStrategy: <fullRecordName> で分離。スキーマ再利用に強い
  • TopicRecordNameStrategy: <topic>-<fullRecordName>。混在トピックの衝突回避

Java Producer(JSON Schema 利用)

import io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient;
import io.confluent.kafka.schemaregistry.client.SchemaRegistryClient;
import io.confluent.kafka.schemaregistry.json.JsonSchema;
import io.confluent.kafka.serializers.json.KafkaJsonSchemaSerializer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.*;

public class JsonSchemaProducerExample {
  public static void main(String[] args) throws Exception {
    Properties props = new Properties();
    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
    props.put("schema.registry.url", "http://localhost:8081");
    props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
    props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, KafkaJsonSchemaSerializer.class.getName());
    // サブジェクト命名戦略(例)
    props.put("value.subject.name.strategy", "io.confluent.kafka.serializers.subject.TopicNameStrategy");

    String schemaStr = "{\n" +
        "  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n" +
        "  \"title\": \"UserCreated\",\n" +
        "  \"type\": \"object\",\n" +
        "  \"additionalProperties\": false,\n" +
        "  \"properties\": {\n" +
        "    \"id\": {\"type\": \"string\"},\n" +
        "    \"age\": {\"type\": \"integer\"},\n" +
        "    \"email\": {\"type\": \"string\", \"format\": \"email\"}\n" +
        "  },\n" +
        "  \"required\": [\"id\"]\n" +
        "}";

    JsonSchema jsonSchema = new JsonSchema(schemaStr);
    // Serializer は送信時に自動登録(auto.register.schemas=true が既定)

    try (KafkaProducer<String, Object> producer = new KafkaProducer<>(props)) {
      Map<String, Object> value = new HashMap<>();
      value.put("id", UUID.randomUUID().toString());
      value.put("age", 34);
      value.put("email", "[email protected]");

      ProducerRecord<String, Object> record = new ProducerRecord<>("user-events", value);
      producer.send(record).get();
    }
  }
}

性能・可観測性:サイズ、CPU、検証コストの現実

JSON はテキストであるため、同等のレコードを Avro バイナリで送る場合と比べてメッセージサイズが大きくなります。ネットワークとストレージのコスト影響、Broker のスループット、クライアントの GC 圧などを事前に計測しましょう。圧縮(lz4、zstd)である程度は相殺できます。

一方で、障害時の切り分けは容易です。メッセージをそのままログや CLI で観察でき、Schema Registry の ID から該当スキーマを素早く引けます。検証コストは Producer/Consumer でのバリデーション有無に依存します。Producer 側で厳格に弾くか、Consumer 側で寛容に取り込むか、役割分担を決めておきます。

  • サイズ最適化: 省略可能フィールドは送らない、フィールド名を短縮しすぎない(可読性とのバランス)
  • CPU 最適化: バリデーションを Producer か Consumer のどちらかで集約、バッチ送信を有効化
  • 監視: スキーマ ID の分布、逆シリアライズ失敗率、レコードサイズ p95/p99 を可視化

Avro との比較と使い分け

両者は Schema Registry と互換性モードの概念を共有しますが、型表現・エンコーディング・検証の性質が異なります。可読性と多言語連携を優先するなら JSON Schema、厳密な型と効率を優先するなら Avro が無難です。混在も可能ですが、トピック単位で統一する方が運用は容易です。

論理型(decimal、timestamp 等)やデフォルト値の扱いは Avro の方が枯れており、データプラットフォーム全体での長期保守を考えると Avro 優位な場面が多いのも事実です。逆に API エッジや PoC、分析前段のイベント収集など、初期のスキーマ探索段階では JSON Schema の取り回しが効きます。

  • 単一イベント型の高スループット: Avro 優先
  • 多様なクライアント/可視性重視・API 近接: JSON Schema 優先
  • 長期アーカイブ・DWH 連携: Avro(論理型・サイズ面で有利)
観点JSON SchemaAvro
エンコーディングテキスト JSON(可読)コンパクトなバイナリ
型の厳密さ緩め(format は互換性判定に影響しないことあり)厳密(論理型が豊富)
サイズ/性能相対的に大(圧縮で緩和)小さく高速になりやすい
互換性モードRegistry で Avro と同等のモードを利用Registry の第一級サポート
ツール/可視性CLI/ログで直読しやすいデコードしないと読みにくい
スキーマ参照Registry の参照機能に対応(実装に依存)対応(成熟度高い)

CCDAK 試験対策と運用の落とし穴

CCDAK では、Schema Registry の互換性モード、命名戦略、スキーマ進化の可否が頻出です。JSON Schema 固有の additionalProperties や required の解釈が Avro と異なる点を言語化できると有利です。

実運用の落とし穴は、互換性モードの過小評価とサブジェクトの乱立です。新規イベントを安易に既存サブジェクトへ追加して required を誤設定すると、突然の互換性違反で登録に失敗します。CI にスキーマ検証を組み込み、失敗を早期に検知しましょう。

  • 覚える: BACKWARD/FORWARD/FULL と transitive の違い、命名戦略 3 種の適用場面
  • 注意: JSON Schema の additionalProperties 既定は true。明示的に false を推奨
  • 試験脈絡: 破壊的変更の扱い方、マルチレコードを 1 トピックに載せる際の戦略選択

問題で確認

CCDAK

問題 1

Kafka で JSON Schema を用いるトピックに、新しい任意フィールド address を追加したい。既存コンシューマを壊さずに進化させる安全な組み合わせはどれか。

  1. 互換性: BACKWARD_TRANSITIVE。address は required に含めず、additionalProperties は false のまま properties に定義する
  2. 互換性: FORWARD。address を required に追加し、default は未設定
  3. 互換性: NONE。address を properties に追加し、additionalProperties は true に変更する
  4. 互換性: FULL_TRANSITIVE。address を required に追加し、format に postal-address を設定する

正解: A

既存コンシューマ保護には BACKWARD(推奨は TRANSITIVE)が適切。新規フィールドは optional にし、additionalProperties は false のまま properties へ明示列挙する。required に入れると後方互換を壊す恐れがある。format の有無は互換性判定に影響しない場合がある。

よくある質問

JSON Schema を使うのに Schema Registry は必須ですか?

Kafka でスキーマ管理と互換性チェック、スキーマ ID によるデシリアライズを行うには Schema Registry の利用が前提です。独自埋め込みも理論上は可能ですが、運用・進化・相互運用性の面で非推奨です。

JSON Schema でもスキーマ参照($ref)は使えますか?

Schema Registry は Avro/JSON Schema/Protobuf のスキーマ参照機能を提供しています。JSON Schema の $ref もサポートされますが、互換性判定の対象や解決方法は実装に依存するため、公式ドキュメントで制約を確認してください。

デフォルト値や format は互換性判定に影響しますか?

互換性判定は主に構造的な変更(required、型、enum など)に基づきます。format や一部の注釈は互換性に影響しないことがあります。デフォルト値の扱いも Avro と異なる点があるため、変更前に Registry で事前検証(/compatibility/subjects/... API)することを推奨します。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Kafka

Kafka Topic と Partition の基礎: 分散とスケーラビリティの要

CCDAK 対策と実務の両立を意識し、Topic/Partition/Replica/Consumer Group の役...

Kafka

CCDAK 試験ガイド:出題範囲・配点・申込み・対策

Confluent Certified Developer for Apache Kafka (CCDAK) の出題範囲...

Kafka

Confluent Certified Administrator (CCAAK) 対策: 出題範囲・配点の考え方・運用観点の要点

CCAAKに向けて、試験領域の押さえどころを運用目線で整理。プロダクションで通用する設定・監視・セキュリティの実践知を、...

Kafka

Kafka の Replica と In-Sync Replicas を正しく設計する: 耐障害性と一貫性

レプリカとISRの仕組みを起点に、acks と min.insync.replicas、クリーン/アンクリーンリーダー選...

Kafka

Kafka の Offset とコミット: ポジション管理と at-least-once の基礎

CCDAK 対策と実務の両立を意識して、Kafka コンシューマのオフセット管理とコミット戦略を整理。at-least-...

Kafkaの記事一覧 (100件)
© 2026 NicheeLab All rights reserved.