すべてのプロダクト
Search
ドキュメントセンター

Realtime Compute for Apache Flink:Kafka connector

最終更新日:Aug 25, 2026

Realtime Compute for Apache Flink で、Kafka コネクタをソース、シンク、または Flink CDC の送信先として使用します。

概要

Apache Kafka は、高性能なデータ処理、ストリーミング分析、データ統合に広く使用されているオープンソースの分散イベントストリーミングプラットフォームです。Realtime Compute for Apache Flink の Kafka コネクタは、オープンソースの Apache Kafka クライアントを使用して、高性能なデータスループットを提供し、複数のデータ形式の読み書きをサポートし、1 回限りのセマンティクスを提供します。

カテゴリ

説明

サポートされるタイプ

SQL ソース、シンク

Flink CDC ソース、シンク

DataStream ソース、シンク

実行モード

ストリーミング

データ形式

サポートされるデータ形式

  • CSV

  • JSON

  • Apache Avro

  • Confluent Avro

  • Debezium JSON

  • Canal JSON

  • Maxwell JSON

  • Raw

  • Protobuf

説明
  • 組み込みの Protobuf データ形式は、Ververica Runtime (VVR) 8.0.9 以降でのみサポートされます。

  • サポートされている各データ形式には、WITH 句で指定できる対応するパラメーターがあります。詳細については、「フォーマット」をご参照ください。

メトリック

メトリック

  • ソーステーブル

    • numRecordsIn

    • numRecordsInPerSecond

    • numBytesIn

    • numBytesInPerSecond

    • currentEmitEventTimeLag

    • currentFetchEventTimeLag

    • sourceIdleTime

    • pendingRecords

  • 結果テーブル

    • numRecordsOut

    • numRecordsOutPerSecond

    • numBytesOut

    • numBytesOutPerSecond

    • currentSendTime

説明

メトリックの詳細については、「メトリック」をご参照ください。

API タイプ

SQL、DataStream、Flink CDC

シンクの更新/削除

コネクタは、結果テーブルへのデータの追加のみをサポートします。更新と削除はサポートされていません。

説明

結果テーブルのデータを更新または削除する方法の詳細については、「Upsert Kafka」をご参照ください。

前提条件

開始する前に、ご利用の Kafka クラスタータイプに応じた前提条件を満たしていることを確認してください:

  • ApsaraMQ for Kafka クラスターへの接続

    • Kafka クラスターのバージョンが 0.11 以降であること。

    • ApsaraMQ for Kafka クラスターを作成済みであること。詳細については、「ステップ 3:リソースの作成」をご参照ください。

    • Flink ワークスペースと Kafka クラスターが同じ Virtual Private Cloud (VPC) 内にあり、Flink ワークスペースの CIDR ブロックを ApsaraMQ for Kafka のホワイトリストに追加済みであること。詳細については、「ホワイトリストの設定」をご参照ください。

    重要

    ApsaraMQ for Kafka へのデータ書き込みに関する制限事項:

    • ApsaraMQ for Kafka は、書き込み時の Zstandard (zstd) 圧縮形式をサポートしていません。

    • ApsaraMQ for Kafka は、べき等性またはトランザクション書き込みをサポートしていないため、Kafka 結果テーブルによって提供される 1 回限りのセマンティクスを使用できません。Ververica Runtime (VVR) 8.0.0 以降、Kafka コネクタは Kafka クライアント 3.x を使用しており、properties.enable.idempotence プロパティはデフォルトで true になります。したがって、Ververica Runtime (VVR) 8.0.0 以降を使用して ApsaraMQ for Kafka に書き込む際の書き込みの失敗を防ぐには、構成 properties.enable.idempotence=false を結果テーブルの定義に追加する必要があります。ApsaraMQ for Kafka のストレージエンジンと機能制限の比較については、「ストレージエンジン間の比較」をご参照ください。

  • セルフマネージド Apache Kafka クラスターへの接続

    • セルフマネージド Apache Kafka クラスターのバージョンが 0.11 以降であること。

    • Flink ワークスペースがセルフマネージド Apache Kafka クラスターへのネットワーク接続を持っていること。パブリックインターネット経由でクラスターに接続する方法の詳細については、「ネットワーク接続に関するよくある質問」をご参照ください。

    • Apache Kafka バージョン 2.8 のクライアント構成オプションのみがサポートされています。詳細については、Apache Kafka のコンシューマー設定およびプロデューサー設定のドキュメントをご参照ください。

注意事項

Apache Flink および Apache Kafka の既知の設計上の制限のため、トランザクション書き込みは推奨されませんsink.delivery-guarantee = 'exactly-once' を設定すると、Kafka コネクタはトランザクション書き込みを有効にしますが、次のような既知の問題があります。

  • 各チェックポイントは新しいトランザクション ID を生成します。チェックポイントの間隔が短すぎると、トランザクション ID が大量に発生し、Kafka クラスターのコーディネーターがメモリ不足になり、クラスターの安定性が損なわれる可能性があります。

  • 各トランザクションは新しいプロデューサーインスタンスを作成します。あまりにも多くのトランザクションが同時にコミットされると、TaskManager がメモリ不足になり、Apache Flink ジョブが不安定になる可能性があります。

  • 複数の Apache Flink ジョブが同じ sink.transactional-id-prefix を使用すると、生成されたトランザクション ID が競合する可能性があります。1つのジョブで書き込み操作が失敗すると、Apache Kafka パーティションのログ開始オフセット (LSO) が進まなくなる可能性があります。これは、そのパーティションのすべてのコンシューマーに影響します。

1 回限りのセマンティクスが必要な場合は、Upsert Kafka コネクタを使用してプライマリキーテーブルに書き込み、べき等性を確保します。トランザクション書き込みを使用する必要がある場合は、「1 回限りのセマンティクスの使用上の注意」をご参照ください。

ネットワーク接続のトラブルシューティング

Realtime Compute for Apache Flink ジョブが起動に失敗したときの Timed out waiting for a node assignment エラーは、通常、Realtime Compute for Apache Flink と Kafka クラスター間のネットワーク接続の問題を示します。

Kafka クライアントは次のようにブローカーに接続します:

  1. クライアントは、bootstrap.servers で指定されたアドレスを使用して、Kafka クラスターへの初期接続を確立します。

  2. Kafka クラスターは、各ブローカーのメタデータ (エンドポイントを含む) を返します。

  3. クライアントは、これらのエンドポイントを使用してブローカーに接続し、データを読み書きします。

bootstrap.servers のアドレスが到達可能であっても、Kafka が不正なブローカーエンドポイントを返した場合、クライアントはデータの読み取りや書き込みができません。この問題は、プロキシ、ポート フォワーディング、または専用回線を使用するネットワークアーキテクチャでよく発生します。

トラブルシューティング手順

ApsaraMQ for Kafka

  1. エンドポイントタイプの確認

    • デフォルトエンドポイント (内部ネットワーク)

    • SASL エンドポイント (認証付き内部ネットワーク)

    • パブリックエンドポイント (別途アプリケーションが必要)

    Realtime Compute for Apache Flink 開発コンソールの[ネットワークプローブ] 機能を使用して、bootstrap.servers アドレスに関する接続性の問題を切り分けます。

  2. セキュリティグループとホワイトリストの確認

    Realtime Compute for Apache Flink ワークスペースの CIDR ブロックを Kafka インスタンスのホワイトリストに追加します。詳細については、「VPC CIDR ブロックの表示」および「ホワイトリストの設定」をご参照ください。

  3. SASL 設定の確認 (有効な場合)

    SASL_SSL エンドポイントを使用する場合、Realtime Compute for Apache Flink ジョブで JAAS、SSL、および SASL メカニズムが正しく設定されていることを確認してください。適切な認証がないと、ハンドシェイクフェーズで接続が失敗し、タイムアウトとして表示されることもあります。詳細については、「セキュリティと認証」をご参照ください。

セルフマネージド Kafka

  1. ネットワークプローブ機能の使用

    この機能は、bootstrap.servers アドレスとの接続性の問題を切り分け、適切な内部またはパブリックエンドポイントが使用されていることを確認するのに役立ちます。

  2. セキュリティグループとホワイトリストの確認

    • Elastic Compute Service (ECS) インスタンスのセキュリティグループは、Kafka エンドポイントポート (通常は 9092 または 9093) でのインバウンドトラフィックを許可する必要があります。

    • ECS インスタンス上のファイアウォールが、ご利用の Realtime Compute for Apache Flink ワークスペースの VPC からのトラフィックを許可していることを確認してください。詳細については、「VPC CIDR ブロックの表示」をご参照ください。

  3. 設定の確認

    1. zkCli.sh または zookeeper-shell.sh ツールを使用して、Kafka が使用する ZooKeeper クラスターにログインします。

    2. ブローカーのメタデータを取得するコマンド (例: get /brokers/ids/0) を実行します。 応答の endpoints フィールドで、Kafka がクライアントに公開するアドレスを見つけます。

      
      # bin/zookeeper-shell.sh localhost:2181
      Connecting to localhost:2181
      Welcome to ZooKeeper!
      JLine support is disabled
      
      WATCHER::
      
      WatchedEvent state:SyncConnected type:None path:null
      get /brokers/ids/0
      {"listener_security_protocol_map":{"PLAINTEXT":"PLAINTEXT"},"endpoints":["PLAINTEXT://116.62.xxx:9092"],"jmx_port":-1,"host":"116.62.xxx","timestamp":"1614840078030","port":9092,"version":4}
      
    3. Realtime Compute for Apache Flink 開発コンソールのネットワークプローブ機能を使用して、このアドレスにアクセスできるかどうかをテストします。

      説明
      • アドレスにアクセスできない場合は、Kafka 管理者に連絡し、listeners および advertised.listeners の構成を確認および修正して、公開されたアドレスが Realtime Compute for Apache Flink からアクセスできるようにしてください。

      • Kafka クライアント接続の詳細については、「接続のトラブルシューティング」をご参照ください。

  4. SASL 設定の確認 (有効な場合)

    SASL_SSL エンドポイントを使用する場合、Realtime Compute for Apache Flink ジョブで JAAS、SSL、および SASL メカニズムが正しく設定されていることを確認してください。適切な認証がないと、ハンドシェイクフェーズで接続が失敗し、タイムアウトとして表示されることもあります。詳細については、「セキュリティと認証」をご参照ください。

SQL

SQL ジョブで Kafka コネクタをソーステーブルまたは結果テーブルとして使用します。

構文

CREATE TABLE KafkaTable (
  `user_id` BIGINT,
  `item_id` BIGINT,
  `behavior` STRING,
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL
) WITH (
  'connector' = 'kafka',
  'topic' = 'user_behavior',
  'properties.bootstrap.servers' = 'localhost:9092',
  'properties.group.id' = 'testGroup',
  'scan.startup.mode' = 'earliest-offset',
  'format' = 'csv'
)

メタデータ列

ソーステーブルまたは結果テーブルにメタデータ列を定義して、Kafka メッセージのメタデータにアクセスします。たとえば、複数のトピックをサブスクライブする場合、メタデータ列を使用して各レコードがどのトピックから来たかを識別できます。

CREATE TABLE kafka_source (
  -- メッセージトピックを `record_topic` 列として読み取る
  `record_topic` STRING NOT NULL METADATA FROM 'topic' VIRTUAL,
  -- ConsumerRecord からタイムスタンプを `ts` 列として読み取る
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
  -- メッセージオフセットを `record_offset` 列として読み取る
  `record_offset` BIGINT NOT NULL METADATA FROM 'offset' VIRTUAL,
  ...
) WITH (
  'connector' = 'kafka',
  ...
);

CREATE TABLE kafka_sink (
  -- `ts` 列のタイムスタンプを ProducerRecord のタイムスタンプとして Kafka に書き込む
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
  ...
) WITH (
  'connector' = 'kafka',
  ...
);

次の表に、Kafka ソーステーブルと結果テーブルがサポートするメタデータ列を示します。

キー

説明

範囲

topic

STRING NOT NULL METADATA VIRTUAL

メッセージトピック。

ソーステーブル

partition

INT NOT NULL METADATA VIRTUAL

メッセージパーティション ID。

ソーステーブル

headers

MAP<STRING, BYTES> NOT NULL METADATA VIRTUAL

メッセージヘッダー。

ソーステーブルと結果テーブル

leader-epoch

INT NOT NULL METADATA VIRTUAL

メッセージの leader-epoch。

ソーステーブル

offset

BIGINT NOT NULL METADATA VIRTUAL

メッセージオフセット。

ソーステーブル

timestamp

TIMESTAMP(3) WITH LOCAL TIME ZONE NOT NULL METADATA VIRTUAL

メッセージタイムスタンプ。

ソーステーブルと結果テーブル

timestamp-type

STRING NOT NULL METADATA VIRTUAL

メッセージタイムスタンプのタイプ。有効な値は次のとおりです:

  • NoTimestampType:メッセージにタイムスタンプが定義されていません。

  • CreateTime:メッセージが作成された時刻。

  • LogAppendTime:メッセージが Kafka ブローカーのログに追加された時刻。

ソーステーブル

__raw_key__

STRING NOT NULL METADATA VIRTUAL

生のメッセージキー。

ソーステーブルと結果テーブル

説明

このパラメーターは、Ververica Runtime (VVR) 11.4 以降でのみサポートされます。

__raw_value__

STRING NOT NULL METADATA VIRTUAL

生のメッセージ値。

ソーステーブルと結果テーブル

説明

このパラメーターは、Ververica Runtime (VVR) 11.4 以降でのみサポートされます。

コネクタオプション

  • 一般

    オプション

    説明

    必須

    デフォルト

    備考

    connector

    コネクタのタイプ。

    String

    はい

    値は kafka である必要があります。

    properties.bootstrap.servers

    Kafka ブローカーアドレスのリスト。

    String

    はい

    フォーマット:host1:port1,host2:port2,...。アドレスはカンマ (,) で区切ります。

    properties.*

    Kafka クライアントの追加プロパティ。

    String

    いいえ

    プロパティキーは、公式の Apache Kafka ドキュメントのプロデューサー設定およびコンシューマー設定で定義されている有効なオプションである必要があります。

    Realtime Compute for Apache Flink は properties. プレフィックスを削除し、残りのキーと値のペアを基盤となる Kafka クライアントに渡します。たとえば、'properties.allow.auto.create.topics' = 'false' を設定して、自動的なトピック作成を無効にできます。

    Kafka コネクタはこれらのオプションを上書きするため、この方法で設定することはできません:

    • key.deserializer

    • value.deserializer

    format

    Kafka メッセージの値のシリアル化および逆シリアル化のためのフォーマット。

    String

    いいえ

    サポートされているフォーマット:

    • csv

    • json

    • avro

    • debezium-json

    • canal-json

    • maxwell-json

    • avro-confluent

    • raw

    説明

    詳細については、「フォーマットオプション」をご参照ください。

    key.format

    Kafka メッセージのキーのシリアル化および逆シリアル化のためのフォーマット。

    String

    いいえ

    サポートされているフォーマット:

    • csv

    • json

    • avro

    • debezium-json

    • canal-json

    • maxwell-json

    • avro-confluent

    • raw

    説明

    この構成を使用する場合、key.options が必須です。

    key.fields

    Kafka メッセージキーとして使用するテーブルスキーマのフィールド。

    String

    いいえ

    複数のフィールド名はセミコロン (;) で区切ります。例:'field1;field2'

    key.fields-prefix

    値フィールドとの名前の競合を防ぐための、すべてのキーフィールドのカスタムプレフィックス。

    String

    いいえ

    このプレフィックスは、キーフィールドと値フィールドを区別するために使用されます。キーをシリアル化する前、または逆シリアル化した後に削除されます。

    説明

    このオプションを使用する場合、value.fields-includeEXCEPT_KEY に設定する必要があります。

    value.format

    Kafka メッセージの値のシリアル化および逆シリアル化のためのフォーマット。

    String

    いいえ

    この構成は format と同等です。format または value.format のいずれか 1 つのみを設定できます。両方が設定されている場合、value.formatformat をオーバーライドします。

    value.fields-include

    キーフィールドが値フォーマットに含まれるかどうかを定義します。

    String

    いいえ

    ALL

    有効な値:

    • ALL: Kafka メッセージの値に、テーブルのすべての列が含まれます。

    • EXCEPT_KEY:Kafka メッセージの値には、key.fields で定義されたものを除くすべてのテーブル列が含まれます。

  • ソーステーブル

    オプション

    説明

    必須

    デフォルト

    備考

    topic

    読み取るトピック。

    String

    いいえ

    複数のトピックをサブスクライブするには、トピック名をセミコロン (;) で区切ります。例:'topic-1;topic-2'

    説明

    このオプションまたは topic-pattern のいずれかを指定できますが、両方を指定することはできません。

    topic-pattern

    サブスクライブするトピックに一致する正規表現。コンシューマーは、このパターンに一致する名前のすべてのトピックをサブスクライブします。

    String

    いいえ

    例:

    • user_event_.*: プレフィックス user_event_ を持つすべてのトピックに一致します。

    • prod\.logs\..*prod.logs. で始まるトピックに一致します(. 文字はエスケープする必要があります)。

    説明

    このオプションまたはトピックのいずれかを指定できますが、両方を指定することはできません。

    properties.group.id

    Kafka ソースコンシューマーグループ ID。

    String

    いいえ

    KafkaSource-{Source-Table-Name}

    初めてコンシューマーグループ ID を使用する場合は、properties.auto.offset.resetearliest または latest のいずれかに設定して、初期起動オフセットを定義する必要もあります。

    scan.startup.mode

    Kafka コンシューマーの開始オフセット。

    String

    いいえ

    group-offsets

    有効な値:

    • earliest-offset: 利用可能な最も早いオフセットから読み取りを開始します。

    • latest-offset: 最大オフセットから読み取りを開始します。

    • group-offsets: 指定された properties.group.id のコミットされたオフセットから読み取りを開始します。

    • タイムスタンプ: 指定された scan.startup.timestamp-millis から読み取りを開始します。

    • specific-offsets: scan.startup.specific-offsets で指定されたオフセットから読み取りを開始します。

    説明

    このオプションは、ジョブがステートなしで開始される場合にのみ適用されます。ジョブがチェックポイントから再開される場合、チェックポイントステートに保存されているオフセットから読み取ります。

    scan.startup.specific-offsets

    scan.startup.modespecific-offsets の場合のパーティションごとの開始オフセット。

    String

    いいえ

    例:partition:0,offset:42;partition:1,offset:300

    scan.startup.timestamp-millis

    scan.startup.modetimestamp に設定されている場合のミリ秒単位の開始タイムスタンプ。

    Long

    いいえ

    単位はミリ秒です。

    scan.topic-partition-discovery.interval

    パーティション検出間隔。

    Duration

    いいえ

    5 分

    コネクタは定期的に新しいパーティションを検出し、そこから読み取ります。topic-pattern を使用する場合、コネクタはパターンに一致する新しいトピックも検出します。この機能を無効にするには、間隔を非正の値に設定します。

    説明

    Ververica Runtime (VVR) 6.0.x では、動的パーティション検出はデフォルトで無効になっています。VVR 8.0 以降、この機能はデフォルトで有効になり、検出間隔は 5 分です。

    scan.header-filter

    Kafka メッセージヘッダーに基づいてメッセージをフィルタリングします。

    String

    いいえ

    ヘッダーキーとその値はコロン (:) で区切られます。複数のヘッダー条件は、論理演算子 (& および |) を使用して接続されます。NOT 論理演算子 (!) もサポートされています。たとえば、ヘッダーに depart=toy または depart=book が含まれ、かつ env=test が含まれていない場合、depart:toy|depart:book&!env:test は Kafka データを保持します。

    説明
    • このオプションは、Ververica Runtime (VVR) 8.0.6 以降でのみサポートされます。

    • 式中の括弧はサポートされていません。

    • 論理演算は左から右に評価されます。

    • ヘッダー値は比較のために UTF-8 文字列に変換されます。

    scan.check.duplicated.group.id

    他のアクティブなコンシューマーが properties.group.id をすでに使用しているかどうかを確認します。

    Boolean

    いいえ

    false

    有効な値:

    • true:ジョブを開始する前に、重複するコンシューマーグループをチェックします。見つかった場合、競合を防ぐためにジョブは失敗します。

    • false:競合をチェックせずにジョブを開始します。

    説明

    このオプションは、Ververica Runtime (VVR) 6.0.4 以降でのみサポートされます。

  • シンクテーブル

    オプション

    説明

    必須

    デフォルト

    備考

    topic

    ターゲットトピック。

    String

    はい

    sink.partitioner

    並列シンクインスタンスからのレコードを Kafka パーティションにマッピングします。

    String

    いいえ

    default

    有効な値:

    • default: デフォルトの Kafka partitioner を使用します。

    • fixed: 各並列 sink インスタンスは、固定の Kafka パーティションに書き込みます。

    • round-robin: レコードはラウンドロビン方式でパーティションに分散されます。

    • カスタム partitioner: カスタム partitioner を使用するには、FlinkKafkaPartitioner サブクラスの完全修飾クラス名を指定します。たとえば、org.mycompany.MyPartitioner などです。

    sink.delivery-guarantee

    シンクの配信保証。

    String

    いいえ

    at-least-once

    有効な値:

    • none:保証はありません。レコードが失われたり、重複したりする可能性があります。

    • at-least-once: レコードが失われないことを保証しますが、重複する可能性があります。

    • exactly-once: Kafka トランザクションを使用して 1 回限りのセマンティクスを提供し、レコードが失われたり重複したりしないことを保証します。

    説明

    exactly-once セマンティクスを使用する場合、sink.transactional-id-prefix も指定する必要があります。

    sink.transactional-id-prefix

    トランザクション ID プレフィックス。 sink.delivery-guaranteeexactly-once の場合に必須です。

    String

    はい、sink.delivery-guaranteeexactly-once の場合です。

    sink.delivery-guaranteeexactly-once にセットされている場合にのみ必須です。

    sink.parallelism

    シンク演算子の並列度。

    Integer

    いいえ

    デフォルトでは、フレームワークは上流の演算子に基づいて並列度を決定します。

セキュリティと認証

Kafka クラスターが安全な接続または認証を必要とする場合、関連するセキュリティおよび認証構成の前に properties. を付け、WITH パラメーターで設定します。次の例では、Kafka テーブルを PLAIN を SASL メカニズムとして使用し、JAAS 構成で設定します。

CREATE TABLE KafkaTable (
  `user_id` BIGINT,
  `item_id` BIGINT,
  `behavior` STRING,
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp'
) WITH (
  'connector' = 'kafka',
  ...
  'properties.security.protocol' = 'SASL_PLAINTEXT',
  'properties.sasl.mechanism' = 'PLAIN',
  'properties.sasl.jaas.config' = 'org.apache.flink.kafka.shaded.org.apache.kafka.common.security.plain.PlainLoginModule required username="username" password="password";'
)

次の例は、セキュリティプロトコルとして SASL_SSL を、SASL メカニズムとして SCRAM-SHA-256 を使用する方法を示しています。

CREATE TABLE KafkaTable (
  `user_id` BIGINT,
  `item_id` BIGINT,
  `behavior` STRING,
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp'
) WITH (
  'connector' = 'kafka',
  ...
  'properties.security.protocol' = 'SASL_SSL',
  /* SSL 構成 */
  /* サーバーの CA 証明書のトラストストアへのパス。 */
  /* アーティファクトを使用してアップロードされたファイルは /flink/usrlib/ ディレクトリに保存されます。 */
  'properties.ssl.truststore.location' = '/flink/usrlib/kafka.client.truststore.jks',
  'properties.ssl.truststore.password' = 'test1234',
  /* クライアント認証が必要な場合は、キーストア (秘密鍵) へのパスも構成する必要があります。 */
  'properties.ssl.keystore.location' = '/flink/usrlib/kafka.client.keystore.jks',
  'properties.ssl.keystore.password' = 'test1234',
  /* サーバーのホスト名を検証するために使用されるアルゴリズム。空の文字列はホスト名の検証を無効にします。 */
  'properties.ssl.endpoint.identification.algorithm' = '',
  /* SASL 構成 */
  /* SASL メカニズムを SCRAM-SHA-256 に設定します。 */
  'properties.sasl.mechanism' = 'SCRAM-SHA-256',
  /* JAAS を構成します。 */
  'properties.sasl.jaas.config' = 'org.apache.flink.kafka.shaded.org.apache.kafka.common.security.scram.ScramLoginModule required username="username" password="password";'
)

Realtime Compute for Apache Flink コンソールの [アーティファクト] 機能を使用して、例で説明されている CA 証明書と秘密鍵をアップロードできます。 アップロードされたファイルは /flink/usrlib ディレクトリに保存されます。 my-truststore.jks という名前の CA 証明書ファイルを使用するには、WITH 句で 'properties.ssl.truststore.location' プロパティを次の 2 つの方法のいずれかで設定できます。

  • 'properties.ssl.truststore.location' = '/flink/usrlib/my-truststore.jks' を設定します。この方法は、ランタイム時に Object Storage Service (OSS) からファイルを動的にダウンロードすることを回避しますが、デバッグモードをサポートしません。

  • リアルタイムコンピューティングエンジンのバージョンが VVR 11.5 以降の場合、properties.ssl.truststore.locationproperties.ssl.keystore.location を絶対 OSS パスに設定できます。ファイルパス形式は oss://flink-fullymanaged-<Workspace ID>/artifacts/namespaces/<Namespace name>/<file name> です。この方法では、Flink ランタイム時に OSS ファイルを動的にダウンロードし、デバッグモードをサポートします。

説明
  • 構成の確認:このトピックの例は一般的な構成を示しています。Kafka コネクタを構成する前に、Kafka の O&M チームに連絡して、正しいセキュリティおよび認証設定を入手してください。

  • エスケープ: ネイティブ Apache Flink とは異なり、Realtime Compute for Apache Flink SQL エディターでは、デフォルトでダブルクォーテーションマーク (") がエスケープされます。したがって、properties.sasl.jaas.config オプションでユーザー名とパスワードに使用されるダブルクォーテーションマークをエスケープするために、バックスラッシュ (\) を追加する必要はありません。

ソーステーブルの開始オフセット

起動モード

scan.startup.mode オプションを構成して、Kafka ソーステーブルがデータの読み取りを開始するオフセットを指定できます。有効な値は次のとおりです:

  • earliest-offset:最も古いオフセットから読み取りを開始します。

  • latest-offset:最新のオフセットから読み取りを開始します。

  • group-offsets:properties.group.id で指定されたコンシューマーグループのコミット済みオフセットから読み取りを開始します。

  • timestamp:scan.startup.timestamp-millis で指定された値以上のタイムスタンプを持つ最初のメッセージから読み取りを開始します。

  • specific-offsets:scan.startup.specific-offsets で指定された特定のパーティションオフセットから読み取りを開始します。

説明
  • 起動モードを指定しない場合、デフォルトは 'group-offsets' です。

  • scan.startup.mode オプションは、ステートレスジョブにのみ適用されます。ステートフルジョブが開始されると、常にそのステートに保存されているオフセットから消費します。

例:

CREATE TEMPORARY TABLE kafka_source (
  ...
) WITH (
  'connector' = 'kafka',
  ...
  -- 最も古いオフセットから消費する。
  'scan.startup.mode' = 'earliest-offset',
  -- 最新のオフセットから消費する。
  'scan.startup.mode' = 'latest-offset',
  -- コンシューマーグループ "my-group" のコミット済みオフセットから消費する。
  'properties.group.id' = 'my-group',
  'scan.startup.mode' = 'group-offsets',
  'properties.auto.offset.reset' = 'earliest', -- "my-group" が初めて使用される場合、消費は最も古いオフセットから開始される。
  'properties.auto.offset.reset' = 'latest', -- "my-group" が初めて使用される場合、消費は最新のオフセットから開始される。
  -- 指定されたタイムスタンプ (ミリ秒) から消費する:1655395200000。
  'scan.startup.mode' = 'timestamp',
  'scan.startup.timestamp-millis' = '1655395200000',
  -- 特定のオフセットから消費する。
  'scan.startup.mode' = 'specific-offsets',
  'scan.startup.specific-offsets' = 'partition:0,offset:42;partition:1,offset:300'
);

開始オフセットの優先度

ソーステーブルの開始オフセットは、優先度の高い順に次のルールによって決定されます:

優先度 (高い順)

チェックポイントまたはセーブポイントに保存されているオフセット。

ジョブ起動時に Realtime Compute for Apache Flink コンソールで選択された開始時刻。

WITH 句の scan.startup.mode で指定された開始オフセット。

scan.startup.mode が指定されていない場合、group-offsets が使用され、対応するコンシューマーグループのオフセットから消費が開始されます。

これらのステップのいずれかで決定されたオフセットが無効な場合、たとえば、期限切れになったり、Kafka クラスターで問題が発生したりした場合、システムは properties.auto.offset.reset で指定されたポリシーに従ってオフセットをリセットします。このオプションが構成されていない場合、システムはユーザーの介入が必要な例外をスローします。

一般的なシナリオとして、新しいコンシューマーグループ ID で消費を開始する場合があります。ソーステーブルはまず、そのグループのコミット済みオフセットを Kafka クラスターにクエリします。グループ ID が新しいため、有効なオフセットは見つかりません。その結果、システムは properties.auto.offset.reset で指定されたポリシーに従ってオフセットをリセットします。したがって、新しいグループ ID で消費する場合は、properties.auto.offset.reset オプションを構成する必要があります。

ソースオフセットのコミット

Kafka ソーステーブルは、チェックポイントが成功した後にのみコンシューマーオフセットを Kafka クラスターにコミットするため、チェックポイントの間隔が長いとコミットされたオフセットが遅れます。ソーステーブルは、実際の読み取り進捗をチェックポイントステートに保存し、システムはこれを障害復旧に使用します。コミットされたオフセットは進捗モニターとしてのみ機能し、回復には使用されないため、コミットの失敗はデータの精度に影響しません。

カスタムシンクパーティショナー

Kafka の組み込みパーティショニング戦略が要件を満たさない場合は、FlinkKafkaPartitioner クラスを拡張してカスタムパーティショナーを実装できます。開発が完了したら、コードを JAR パッケージにコンパイルし、Realtime Compute コンソールのアーティファクト機能を使用してアップロードします。JAR パッケージがアップロードされて参照された後、WITH 句の sink.partitioner パラメーターをパーティショナーの完全修飾クラス名 (例:org.mycompany.MyPartitioner) に設定します。

Kafka、Upsert Kafka、および Kafka JSON カタログ

Kafka は追加専用のイベントストリーミングプラットフォームであり、データの更新や削除をサポートしていません。ストリーミング SQL では、標準の Kafka 結果テーブルは、上流の Change Data Capture (CDC) データや、集計や結合などの演算子のリトラクションロジックを処理できません。変更やリトラクションを含むデータを書き込む必要がある場合は、Upsert Kafka 結果テーブルを使用します。

1 つまたは複数の上流データベーステーブルから Kafka への Change Data Capture (CDC) データのバッチ同期を簡素化するために、Kafka JSON カタログを使用できます。Kafka に保存されているデータが JSON 形式の場合、Kafka JSON カタログを使用すると、スキーマと WITH パラメーターを定義するステップをスキップできます。詳細については、「Kafka JSON カタログの管理」をご参照ください。

例 1:Kafka からの読み取りと Kafka への書き込み

この例では、ソース Kafka トピックからデータを読み取り、それをシンクトピックに書き込みます。データは CSV 形式です。

CREATE TEMPORARY TABLE kafka_source (
  id INT,
  name STRING,
  age INT
) WITH (
  'connector' = 'kafka',
  'topic' = 'source',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'properties.group.id' = '<yourKafkaConsumerGroupId>',
  'format' = 'csv'
);

CREATE TEMPORARY TABLE kafka_sink (
  id INT,
  name STRING,
  age INT
) WITH (
  'connector' = 'kafka',
  'topic' = 'sink',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'properties.group.id' = '<yourKafkaConsumerGroupId>',
  'format' = 'csv'
);

INSERT INTO kafka_sink SELECT id, name, age FROM kafka_source;

例 2:テーブルスキーマとデータの同期

Kafka コネクタを使用して、Kafka トピックから Hologres にメッセージをリアルタイムで同期できます。フェールオーバー中に Hologres でメッセージが重複するのを防ぐために、Kafka メッセージのオフセットとパーティション ID を複合プライマリキーとして使用できます。

CREATE TEMPORARY TABLE kafkaTable (
  `offset` INT NOT NULL METADATA,
  `part` BIGINT NOT NULL METADATA FROM 'partition',
  PRIMARY KEY (`part`, `offset`) NOT ENFORCED
) WITH (
  'connector' = 'kafka',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'topic' = 'kafka_evolution_demo',
  'scan.startup.mode' = 'earliest-offset',
  'format' = 'json',
  'json.infer-schema.flatten-nested-columns.enable' = 'true'
    -- オプション。すべてのネストされた列をフラット化します。
);

CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka`
WITH (
  'connector' = 'hologres'
) AS TABLE vvp.`default`.kafkaTable;

例 3:Kafka のキーと値の同期

Kafka メッセージキーに関連情報が含まれている場合は、キーと値の両方を同期できます。

CREATE TEMPORARY TABLE kafkaTable (
  `key_id` INT NOT NULL,
  `val_name` VARCHAR(200)
) WITH (
  'connector' = 'kafka',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'topic' = 'kafka_evolution_demo',
  'scan.startup.mode' = 'earliest-offset',
  'key.format' = 'json',
  'value.format' = 'json',
  'key.fields' = 'key_id',
  'key.fields-prefix' = 'key_',
  'value.fields-prefix' = 'val_',
  'value.fields-include' = 'EXCEPT_KEY'
);

CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka`(
WITH (
  'connector' = 'hologres'
) AS TABLE vvp.`default`.kafkaTable;
説明

Kafka メッセージキーは、スキーマ進化や自動型解析をサポートしていません。スキーマを手動で宣言する必要があります。

例 4:データの同期と計算の実行

Kafka から Hologres にデータを同期する際に、軽量な変換が必要になる場合があります。

CREATE TEMPORARY TABLE kafkaTable (
  `distinct_id` INT NOT NULL,
  `properties` STRING,
  `timestamp` TIMESTAMP_LTZ METADATA,
  `date` AS CAST(`timestamp` AS DATE)
) WITH (
  'connector' = 'kafka',
  'properties.bootstrap.servers' = '<yourKafkaBrokers>',
  'topic' = 'kafka_evolution_demo',
  'scan.startup.mode' = 'earliest-offset',
  'key.format' = 'json',
  'value.format' = 'json',
  'key.fields' = 'key_id',
  'key.fields-prefix' = 'key_'
);

CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka` WITH (
   'connector' = 'hologres'
) AS TABLE vvp.`default`.kafkaTable
ADD COLUMN
  `order_id` AS COALESCE(JSON_VALUE(`properties`, '$.order_id'), 'default');
--COALESCE を使用して null 値を処理します。

例 5:ネストされた JSON の解析

以下は JSON メッセージのサンプルです:

{
  "id": 101,
  "name": "VVP",
  "properties": {
    "owner": "Alibaba Cloud",
    "engine": "Flink"
  }
}

JSON_VALUE(payload, '$.properties.owner') などの関数を使用してフィールドを解析するのではなく、ソース DDL で構造を直接定義できます:

CREATE TEMPORARY TABLE kafka_source (
  id          VARCHAR,
  `name`      VARCHAR,
  properties  ROW<`owner` STRING, engine STRING>
) WITH (
  'connector' = 'kafka',
  'topic' = 'xxx',
  'properties.bootstrap.servers' = 'xxx',
  'scan.startup.mode' = 'earliest-offset',
  'format' = 'json'
);

このアプローチでは、Flink は読み取りフェーズ中に JSON を構造化されたフィールドに解析します。後続の SQL クエリは、追加の関数呼び出しなしで properties.owner を直接参照できるため、全体的なパフォーマンスが向上します。

DataStream API

重要

DataStream API を使用してデータを読み書きするには、対応する DataStream コネクタを使用して Realtime Compute for Apache Flink に接続します。DataStream コネクタの設定方法の詳細については、「DataStream コネクタの統合」をご参照ください。

  • Kafka ソースの構築

    Kafka Sourceは、Kafka Source インスタンスを作成するためのビルダー クラスを提供します。 次のサンプル コードは、input-topic Topicの最も古いOffsetからデータを消費するKafka Sourceをビルドします。 コンシューマー グループmy-groupで、Kafka メッセージは文字列として逆シリアル化されます。

    Java

    KafkaSource<String> source = KafkaSource.<String>builder()
        .setBootstrapServers(brokers)
        .setTopics("input-topic")
        .setGroupId("my-group")
        .setStartingOffsets(OffsetsInitializer.earliest())
        .setValueOnlyDeserializer(new SimpleStringSchema())
        .build();
    
    env.fromSource(source, WatermarkStrategy.noWatermarks(), "Kafka Source");

    Kafka ソースを構築するには、次のプロパティを指定する必要があります。

    パラメーター

    説明

    BootstrapServers

    Kafka ブローカーアドレスのリストです。このプロパティは、setBootstrapServers(String) メソッドを呼び出して設定します。

    GroupId

    [コンシューマーグループ] の ID です。このプロパティは、setGroupId(String) メソッドを呼び出して設定します。

    トピックまたはパーティション

    サブスクライブするトピックまたはパーティション。Kafka ソースは、トピックまたはパーティションをサブスクライブするための次の 3 つの方法をサポートしています:

    • リスト内のトピックのすべてのパーティションをサブスクライブします。

      KafkaSource.builder().setTopics("topic-a","topic-b")
    • トピックパターン:指定された正規表現に一致する名前のトピックのすべてのパーティションをサブスクライブします。

      KafkaSource.builder().setTopicPattern("topic.*")
    • パーティションのリスト。指定されたパーティションをサブスクライブできます。

      final HashSet<TopicPartition> partitionSet = new HashSet<>(Arrays.asList(
              new TopicPartition("topic-a", 0),    // トピック "topic-a" のパーティション 0
              new TopicPartition("topic-b", 5)));  // トピック "topic-b" のパーティション 5
      KafkaSource.builder().setPartitions(partitionSet)

    デシリアライザー

    Kafka メッセージを解析するために使用されるデシリアライザー。

    setDeserializer(KafkaRecordDeserializationSchema) メソッドを使用してデシリアライザーを指定します。 KafkaRecordDeserializationSchema は、Kafka ConsumerRecord を解析する方法を定義します。 Kafka メッセージのみを解析する必要がある場合は、次のいずれかのメソッドを使用できます。

    • ビルダー クラスの setValueOnlyDeserializer(DeserializationSchema) メソッドを使用します。DeserializationSchema は、Kafka メッセージ のバイナリデータを解析する方法を定義します。

    • Kafka の Deserializer インターフェイスを実装するクラスを使用します。たとえば、StringDeserializer を使用して Kafka メッセージを文字列に解析できます。

      import org.apache.kafka.common.serialization.StringDeserializer;
      
      KafkaSource.<String>builder()
              .setDeserializer(KafkaRecordDeserializationSchema.valueOnly(StringDeserializer.class));
    説明

    完全な ConsumerRecord を解析するには、KafkaRecordDeserializationSchema インターフェイスを実装する必要があります。

    POM

    Kafka DataStream コネクタは Maven Central リポジトリで入手できます。

    <dependency>
        <groupId>com.alibaba.ververica</groupId>
        <artifactId>ververica-connector-kafka</artifactId>
        <version>${vvr-version}</version>
    </dependency>

    Kafka DataStream コネクタを使用する際は、次のプロパティを考慮してください:

    • 開始オフセット

      Kafka ソースは、オフセットイニシャライザ (OffsetsInitializer) を使用して、その開始オフセットを指定します。組み込みのイニシャライザは次のとおりです。

      オフセット初期化子

      コード

      最も古いオフセットから消費を開始します。

      KafkaSource.builder().setStartingOffsets(OffsetsInitializer.earliest())

      最新のオフセットから消費を開始します。

      KafkaSource.builder().setStartingOffsets(OffsetsInitializer.latest())

      指定された時刻以上のタイムスタンプを持つデータの消費を開始します。単位はミリ秒です。

      KafkaSource.builder().setStartingOffsets(OffsetsInitializer.timestamp(1592323200000L))

      コンシューマーグループのコミット済みオフセットから消費を開始します。コミット済みオフセットが存在しない場合は、指定されたリセット戦略 (例:最も古いオフセット) を使用します。

      KafkaSource.builder().setStartingOffsets(OffsetsInitializer.committedOffsets(OffsetResetStrategy.EARLIEST))

      消費はコンシューマーグループによってコミットされたオフセットから開始され、オフセットリセットポリシーは指定されません。

      KafkaSource.builder().setStartingOffsets(OffsetsInitializer.committedOffsets())

      説明
      • 組み込みの初期化子が要件を満たさない場合は、カスタムのオフセット初期化子を実装できます。

      • オフセットイニシャライザーを指定しない場合、デフォルトは OffsetsInitializer.earliest() です。

    • ストリーミングモードとバッチモード

      Kafka ソースは、ストリーミングモードバッチモードの両方をサポートしています。デフォルトではストリーミングモードで動作し、ジョブは失敗するかキャンセルされるまで無期限に実行されます。Kafka ソースバッチモードで実行するように設定するには、setBounded(OffsetsInitializer) を使用して停止オフセットを指定できます。すべてのパーティションが指定された停止オフセットに達すると、Kafka ソースは終了します。

      説明

      ストリーミングモードKafka ソースには、通常、停止 Offset はありません。ただし、テスト目的で、setUnbounded(OffsetsInitializer) を使用して、ストリーミングモードでも停止 Offset を指定できます。停止 Offset を指定するためのメソッド名が異なることに注意してください。ストリーミングモードの場合は setUnboundedバッチモードの場合は setBounded です。

    • 動的パーティション検出

      Flink ジョブを再起動せずにトピックのスケーリングや新しいトピックの作成を処理するために、パターンでトピックをサブスクライブする際に動的パーティション検出を有効にできます。この機能はデフォルトで無効になっており、明示的に有効にする必要があります:

      KafkaSource.builder()
          .setProperty("partition.discovery.interval.ms", "10000") // 10 秒ごとに新しいパーティションを検出します。
      重要

      動的パーティション検出機能は、Kafka クラスターのメタデータ更新メカニズムに依存します。Kafka クラスターがパーティション情報をタイムリーに更新しない場合、新しいパーティションが検出されない可能性があります。Kafka クラスターの partition.discovery.interval.ms 構成が実際のシナリオと一致していることを確認してください。

    • イベント時間とウォーターマーク

      デフォルトでは、Kafka ソースは Kafka メッセージのタイムスタンプをイベント時間として使用します。カスタムのウォーターマーク戦略を定義して、メッセージ本文からイベント時間を抽出し、下流にウォーターマークを送信できます。

      env.fromSource(kafkaSource, new CustomWatermarkStrategy(), "Kafka Source With Custom Watermark Strategy")

      カスタムウォーターマーク戦略の詳細については、「ウォーターマークの生成」をご参照ください。

      説明

      ソースサブタスクがアイドル状態の場合 (たとえば、Kafka パーティションに新しいデータがない場合や、ソースの並列度が Kafka パーティションの数より高い場合)、そのサブタスクのウォーターマークは進みません。これにより、下流のウィンドウ計算がブロックされる可能性があります。

      この問題を解決するには、次のソリューションを検討してください:

      • ソースアイドルタイムアウトの構成:table.exec.source.idle-timeout プロパティを有効にして、アイドル状態のソースを一時的にアイドルとしてマークします。これにより、下流のウォーターマークが進むことができます。

      • 適切な並列度の設定:ソースの並列度が Kafka パーティションの数を超えないようにします。

    • オフセットコミット

      チェックポイントが有効な場合、Kafka ソースチェックポイントが完了したときに現在のコンシューマーオフセットを Kafka にコミットします。これにより、Flink チェックポイントステートが Kafka ブローカー上のコミット済みオフセットと一致することが保証されます。チェックポイントが無効な場合、Kafka ソースは Kafka コンシューマーの内部的な自動定期オフセットコミットメカニズムに依存します。この機能は、enable.auto.commit および auto.commit.interval.ms Kafka コンシューマープロパティによって制御されます。

      説明

      Kafka ソースは、フォールトトレランスと回復のためにコミットされたオフセットに依存しません。オフセットのコミットは、Kafka コンシューマーとコンシューマーグループの進捗を監視するためだけです。

    • その他のプロパティ

      前述のプロパティに加えて、setProperties(Properties) および setProperty(String, String) を使用すると、Kafka ソース とその基盤となる Kafka コンシューマーに任意の プロパティ を設定できます。 Kafka ソース は、次の特定のプロパティを提供します。

      パラメーター

      説明

      client.id.prefix

      Kafka コンシューマーのクライアント ID プレフィックス。

      partition.discovery.interval.ms

      パーティション検出の間隔 (ミリ秒)。値に -1 を指定すると、動的パーティション検出が無効になります。

      説明

      [バッチモード] では、このプロパティは自動的に -1 に設定されます。

      register.consumer.metrics

      Flink に Kafka コンシューマーメトリックを登録します。

      その他の Kafka コンシューマー構成

      Kafka コンシューマー構成の完全なリストについては、公式の Apache Kafka ドキュメントをご参照ください。

      重要

      正しい操作を保証するために、Kafka DataStream コネクタは、手動で構成された次のプロパティを上書きします:

      • key.deserializer は、常に org.apache.kafka.common.serialization.ByteArrayDeserializer に上書きされます。

      • value.deserializer は常に org.apache.kafka.common.serialization.ByteArrayDeserializer に上書きされます。

      • auto.offset.reset.strategy は、OffsetsInitializer が提供するストラテジーによって上書きされます。

      次の例は、Kafka コンシューマーを PLAIN SASL メカニズムを使用し、JAAS 構成を提供するように構成する方法を示しています。

      KafkaSource.builder()
          .setProperty("sasl.mechanism", "PLAIN")
          .setProperty("sasl.jaas.config", "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"username\" password=\"password\";")
    • モニタリング

      Kafka ソースは、モニタリングと診断のために Flink のメトリックシステムを通じてメトリックを公開します。

      • メトリックスコープ

        Kafka ソースリーダーのすべてのメトリックは、演算子のメトリックグループのサブグループである KafkaSourceReader メトリックグループに登録されます。特定のトピックパーティションに関連するメトリックは、KafkaSourceReader.topic.<topic_name>.partition.<partition_id> サブグループに登録されます。

        例えば、「my-topic」 トピックのパーティション 1 の現在のコンシューマーオフセットメトリック (currentOffset) は、.operator.KafkaSourceReader.topic.my-topic.partition.1.currentOffset で利用可能です。成功したコミット数 (commitsSucceeded) は、.operator.KafkaSourceReader.commitsSucceeded で利用可能です。

      • メトリックのリスト

        メトリック

        説明

        範囲

        currentOffset

        パーティションの現在のコンシューマーオフセット

        TopicPartition

        committedOffset

        パーティションの最後にコミットされたオフセット

        TopicPartition

        commitsSucceeded

        成功したオフセットコミットの総数。

        KafkaSourceReader

        commitsFailed

        失敗したコミット数

        KafkaSourceReader

      • Kafka コンシューマーメトリック

        基盤となる Kafka コンシューマーのメトリックは、KafkaSourceReader.KafkaConsumer メトリックグループに登録されます。たとえば、records-consumed-total メトリックは .operator.KafkaSourceReader.KafkaConsumer.records-consumed-total に登録されます。

        register.consumer.metrics プロパティを使用して、Kafka コンシューマーメトリックを登録するかどうかを指定できます。このオプションはデフォルトで有効になっています (true)。Kafka コンシューマーメトリックの詳細については、「Apache Kafka ドキュメント」をご参照ください。

  • Kafka シンクの構築

    Flink Kafka シンクは、データストリームを 1 つ以上の Kafka トピックに書き込みます。

    DataStream<String> stream = ...
    
    Properties kafkaProperties = new Properties();
    kafkaProperties.setProperty("bootstrap.servers", "localhost:9092");
    
    KafkaSink<String> sink = KafkaSink.<String>builder()
            .setKafkaProducerConfig(kafkaProperties)
            .setRecordSerializer(
                    KafkaRecordSerializationSchema.builder()
                            .setTopic("my-topic")
                            .setValueSerializationSchema(new SimpleStringSchema())
                            .build())
            .setDeliveryGuarantee(DeliveryGuarantee.AT_LEAST_ONCE)
            .build();
    
    stream.sinkTo(sink);

    Kafka シンクを構築するには、次のプロパティを構成する必要があります。

    パラメーター

    説明

    Kafka クライアントプロパティ

    bootstrap.servers プロパティは必須です。これには、カンマ区切りの Kafka ブローカーのリストを指定します。

    レコードシリアライザー

    入力データを Kafka の ProducerRecord に変換するには、KafkaRecordSerializationSchema を提供する必要があります。 Flink は、メッセージキーと値のシリアル化、トピックの選択、メッセージのパーティショニングなどの一般的なコンポーネントを提供するスキーマビルダーを提供します。 また、対応するインターフェイスを実装して、よりきめ細かな制御を行うことも可能です。 Kafka に書き込む ProducerRecord を生成するために、受信レコードごとに ProducerRecord<byte[], byte[]> serialize(T element, KafkaSinkContext context, Long timestamp) メソッドが呼び出されます。

    ProducerRecord は、各レコードを Kafka に書き込む方法を詳細にコントロールし、次の操作を可能にします。

    • 送信先トピックの設定。

    • メッセージキーの設定。

    • 送信先パーティションの指定。

    配信保証

    bootstrap.servers パラメーターは必須であり、カンマ区切りの Kafka ブローカーのリストを指定します。

    配信保証

    Flink のチェックポイントが有効な場合、Flink Kafka シンクは 1 回限りのセマンティクスを提供できます。チェックポイントを有効にすることに加えて、DeliveryGuarantee パラメーターを使用して異なる配信保証を指定できます。DeliveryGuarantee パラメーターは次のオプションを提供します:

    • DeliveryGuarantee.NONE:(デフォルト) Flink は保証を提供しません。データが失われたり、重複したりする可能性があります。

    • DeliveryGuarantee.AT_LEAST_ONCE:データが失われないことを保証しますが、重複が発生する可能性があります。

    • DeliveryGuarantee.EXACTLY_ONCE:Kafka トランザクションを使用して 1 回限りのセマンティクスを提供します。

      説明

      EXACTLY_ONCE セマンティクスを使用する場合は、「1 回限りのセマンティクスに関する考慮事項」をご参照ください。

Flink CDC

Kafka コネクタをソースまたはシンクとして使用して、Flink CDC の YAML ジョブを作成します。

制限事項

  • Kafka データソースから Flink CDC データをインジェストするには、Realtime Compute for Apache Flink (VVR) 11.1 以降を使用します。

  • JSON、Debezium JSON、および Canal JSON のみがサポートされています。

  • 複数のパーティションに分散された単一テーブルからデータを読み取るのは、Realtime Compute for Apache Flink (VVR) 8.0.11 以降でのみサポートされています。

構文

source:
  type: kafka
  name: Kafka source
  properties.bootstrap.servers: localhost:9092
  topic: ${kafka.topic}
sink:
  type: kafka
  name: Kafka Sink
  properties.bootstrap.servers: localhost:9092

パラメーター

  • 一般

    パラメーター

    説明

    必須

    デフォルト

    備考

    type

    ソースまたはシンクのタイプ。

    はい

    String

    値は kafka にする必要があります。

    name

    ソースまたはシンクの名前。

    いいえ

    String

    なし

    properties.bootstrap.servers

    Kafka ブローカーアドレス。

    はい

    String

    フォーマットはhost1:port1,host2:port2,host3:port3で、区切り文字はカンマ (,) です。

    properties.*

    Kafka クライアントの構成プロパティ。

    いいえ

    String

    プロパティキーは、公式の Apache Kafka ドキュメントのプロデューサー設定およびコンシューマー設定で定義されている有効なオプションである必要があります。

    Realtime Compute for Apache Flink (VVR) は、残りのキーと値のペアを基盤となる Kafka クライアントに渡す前に、properties. プレフィックスを削除します。たとえば、トピックの自動作成を無効にするには、'properties.allow.auto.create.topics' = 'false' と設定します。

    key.format

    Kafka メッセージキーのシリアル化および逆シリアル化フォーマット。

    いいえ

    String

    • ソースについては、json フォーマットのみがサポートされています。

    • シンクの場合、有効な値は次のとおりです:

      • csv

      • json

    説明

    このオプションは、Realtime Compute for Apache Flink (VVR) 11.0.0 以降でのみサポートされます。

    value.format

    Kafka メッセージ値のシリアル化および逆シリアル化フォーマット。

    いいえ

    String

    debezium-json

    • ソースの場合、有効な値は次のとおりです:

      • debezium-json 

      • canal-json

      • json

    • シンクの場合、有効な値は次のとおりです:

      • debezium-json 

      • canal-json

      • canal-protobuf

    説明
    • debezium-json および canal-json フォーマットは、Realtime Compute for Apache Flink (VVR) のバージョン 8.0.10 以降を必要とします。

    • json フォーマットには、Realtime Compute for Apache Flink (VVR) のバージョン 11.0.0 以降が必要です。

  • ソースパラメーター

    パラメーター

    説明

    必須

    デフォルト

    備考

    topic

    読み取るトピック。

    いいえ

    String

    複数のトピックをサブスクライブするには、トピック名をセミコロン (;) で区切ります。例:topic-1;topic-2

    説明

    このパラメーター、または topic-pattern のいずれか一方を指定します。

    topic-pattern

    サブスクライブするトピックの名前に一致する正規表現。

    いいえ

    String

    例:

    • user_event_.*: user_event_ をプレフィックスとするすべてのトピックに一致します。

    • prod\.logs\..*: prod.logs. をプレフィックスとするトピックに一致します (. 文字はエスケープする必要があります)。

    説明

    このパラメーター、または topic のいずれか一方を指定します。

    properties.group.id

    コンシューマーグループ ID。

    いいえ

    String

    新しいコンシューマーグループ ID を指定する場合、初期の開始オフセットを定義するために、properties.auto.offset.reset パラメーターを earliest または latest に設定する必要があります。

    scan.startup.mode

    Kafka コンシューマーの開始オフセット。

    いいえ

    String

    group-offsets

    有効な値:

    • earliest-offset:利用可能な最も古いオフセットから読み取りを開始します。

    • latest-offset:最新のオフセットから読み取りを開始します。

    • group-offsets (デフォルト値):指定された properties.group.id のコミット済みオフセットから読み取りを開始します。

    • timestamp:scan.startup.timestamp-millis で指定されたタイムスタンプから読み取りを開始します。

    • specific-offsets:scan.startup.specific-offsets で指定されたオフセットから読み取りを開始します。

    説明

    このパラメーターは、ジョブがステートレスで起動する場合にのみ適用されます。ステートフルなジョブが起動すると、常にそのステートに保存されているオフセットから消費します。

    scan.startup.specific-offsets

    scan.startup.modespecific-offsets に設定されている場合の、各パーティションの開始オフセット。

    いいえ

    String

    例:partition:0,offset:42;partition:1,offset:300

    scan.startup.timestamp-millis

    scan.startup.modetimestamp に設定されている場合の、ミリ秒単位の開始タイムスタンプです。

    いいえ

    Long

    単位はミリ秒です。

    scan.topic-partition-discovery.interval

    トピック内の新しいパーティションを動的に検出する間隔。

    いいえ

    Duration

    5 分

    コネクタは定期的に新しいパーティションを検出し、読み取ります。topic-pattern を使用する場合、コネクタはパターンに一致する新しいトピックも検出します。検出を無効にするには、この値を 0 以下に設定します。

    scan.check.duplicated.group.id

    properties.group.id で指定されたコンシューマーグループが重複しているかどうかを確認します。

    いいえ

    Boolean

    false

    有効な値:

    • true:ジョブが開始される前に重複するコンシューマーグループをチェックします。重複が見つかった場合、ジョブは失敗します。

    • false:競合をチェックせずにジョブを開始します。

    schema.inference.strategy

    スキーマ解析戦略。

    いいえ

    String

    continuous

    有効な値:

    • continuous:各データレコードのスキーマを解析します。スキーマに互換性がない場合、システムはより広いスキーマを推論し、スキーマ変更イベントを生成します。

    • static:ジョブの開始時にスキーマ解析を 1 回だけ実行します。データはこの初期スキーマに基づいて解析され、スキーマ変更イベントは生成されません。

    説明
    • スキーマ解析の詳細については、「スキーマ解析と進化のポリシー」をご参照ください。

    • この構成オプションは、Ververica Runtime (VVR) 8.0.11 以降でのみサポートされます。

    scan.max.pre.fetch.records

    初期スキーマ推論のためにパーティションごとに消費される最大メッセージ数。

    いいえ

    Int

    50

    データ処理が開始される前に、システムはスキーマを初期化するために、各パーティションから指定された数の最新メッセージを事前にフェッチして消費します。

    key.fields-prefix

    名前の競合を避けるためのメッセージキーフィールド名のプレフィックス。

    いいえ

    String

    例えば、このパラメーターが key_ に設定され、メッセージキーに a という名前のフィールドが含まれている場合、解析されたフィールド名は key_a になります。

    説明

    key.fields-prefix の値は、value.fields-prefix の値のプレフィックスであってはなりません。

    value.fields-prefix

    名前の競合を避けるためのメッセージ値フィールド名のプレフィックス。

    いいえ

    String

    たとえば、このパラメーターが value_ に設定されていて、メッセージの値に b という名前のフィールドが含まれている場合、解析されたフィールド名は value_b になります。

    説明

    value.fields-prefix の値は、key.fields-prefix の値のプレフィックスにすることはできません。

    metadata.list

    下流のシンクに渡されるメタデータ列。

    いいえ

    String

    利用可能なメタデータ列には、topicpartitionoffsettimestamptimestamp-typeheaders、および leader-epoch が含まれます。列名はコンマで区切ります。

    scan.value.initial-schemas.ddls

    特定のテーブルの初期スキーマを定義する DDL 文。

    いいえ

    String

    複数の DDL 文はセミコロン (;) で区切ります。たとえば、CREATE TABLE db1.t1 (id BIGINT, name VARCHAR(10)); CREATE TABLE db1.t2 (id BIGINT); を使用して、テーブル db1.t1 と db1.t2 の初期スキーマをそれぞれ指定します。

    DDL で定義されたテーブルスキーマは、ターゲットシンクテーブルと一致し、Flink SQL 構文に準拠している必要があります。

    説明

    この構成オプションは、Ververica Runtime (VVR) 11.5 以降でのみサポートされます。

    ingestion.ignore-errors

    データ解析エラーを無視します。

    いいえ

    Boolean

    false

    説明

    この構成オプションは、Ververica Runtime (VVR) 11.5 以降でのみサポートされます。

    ingestion.error-tolerance.max-count

    ジョブが失敗するまでに許容される解析エラーの最大数。 ingestion.ignore-errorstrue の場合にのみ有効です。

    いいえ

    Integer

    -1

    このパラメーターは、ingestion.ignore-errorstrue に設定されている場合にのみ適用されます。値 -1 は無制限の許容範囲を示します。つまり、解析例外によってジョブが失敗することはありません。

    説明

    この構成オプションは、Ververica Runtime (VVR) 11.5 以降でのみサポートされます。

    scan.duplicate-field.strategy

    キーと値の部分から解析された重複するフィールド名をどのように処理するかを指定します。

    いいえ

    String

    EXCEPTION

    有効な値:

    • EXCEPTION:キーと値に重複するフィールドが存在する場合に例外をスローします。これは VVR 11.6 以前のデフォルトの動作です。

    • PREFER_KEY:フィールドが重複している場合、キーフィールドの値を使用します。

    • PREFER_VALUE:フィールドが重複している場合、値フィールドの値を使用します。

    説明

    この構成オプションは、Ververica Runtime (VVR) 11.7 以降でのみサポートされます。

    • Debezium JSON フォーマットパラメーター

      パラメーター

      必須

      デフォルト

      説明

      debezium-json.distributed-tables

      いいえ

      Boolean

      false

      単一の Debezium JSON テーブルのデータが複数のパーティションに分散している場合は、true に設定します。

      説明

      この構成オプションは、Ververica Runtime (VVR) 8.0.11 以降でのみサポートされます。

      重要

      このパラメーターを変更するには、ステートレスでの起動が必要です。

      debezium-json.schema-include

      いいえ

      Boolean

      false

      Debezium JSON メッセージにスキーマを含めます。これは、Debezium Kafka Connect 構成の value.converter.schemas.enable プロパティに対応しています。

      有効な値:

      • true:Debezium JSON メッセージにはスキーマが含まれます。

      • false:Debezium JSON メッセージにはスキーマが含まれません。

      debezium-json.ignore-parse-errors

      いいえ

      Boolean

      false

      有効な値:

      • true:解析例外を引き起こす行をスキップします。

      • false:エラーをスローし、ジョブは失敗します。

      debezium-json.infer-schema.primitive-as-string

      いいえ

      Boolean

      false

      テーブルスキーマの解析時に、すべてのプリミティブ型を String として解析します。

      有効な値:

      • true: すべてのプリミティブ型を String として解析します。

      • false:デフォルトのルールに基づいて型を解析します。

      debezium-json.infer-schema.string-type-inference

      いいえ

      Boolean

      true

      文字列フィールドを TIME、DATE、または TIMESTAMP として推論するかどうかを指定します。このパラメーターを false に設定した場合、コネクタはこの推論をスキップし、フィールドを STRING として保持します。

      説明

      このパラメーターは、Ververica Runtime (VVR) 11.8 以降でのみサポートされます。

    • Canal JSON フォーマットパラメーター

      パラメーター

      必須

      デフォルト

      説明

      canal-json.distributed-tables

      いいえ

      Boolean

      false

      Canal JSON の単一テーブルのデータが複数のパーティションに分散している場合は、このオプションを有効にする必要があります。

      説明

      この構成オプションは、Ververica Runtime (VVR) 8.0.11 以降でのみサポートされます。

      重要

      このパラメーターを変更するには、ステートレスでの起動が必要です。

      canal-json.database.include

      いいえ

      String

      Canal レコードの database メタデータフィールドによってチェンジログをフィルタリングするための、オプションの正規表現です。一致するデータベースのレコードのみが処理されます。この正規表現は、Java の Pattern クラスと互換です。

      canal-json.table.include

      いいえ

      String

      Canal レコードの table メタデータフィールドを使用して変更ログをフィルターするためのオプションの正規表現です。一致するテーブルのレコードのみが処理されます。この正規表現は、Java の Pattern クラスと互換性があります。

      canal-json.ignore-parse-errors

      いいえ

      Boolean

      false

      有効な値:

      • true:解析例外が発生した場合、現在の行をスキップします。

      • false:エラーをスローし、ジョブは起動に失敗します。

      canal-json.infer-schema.primitive-as-string

      いいえ

      Boolean

      false

      テーブルスキーマの解析時に、すべてのプリミティブ型を String として解析します。

      有効な値:

      • true: すべてのプリミティブ型を String として解析します。

      • false:デフォルトのルールに基づいて型を解析します。

      canal-json.infer-schema.string-type-inference

      いいえ

      Boolean

      true

      文字列フィールドを TIME、DATE、または TIMESTAMP として推論するかどうかを指定します。このパラメーターを false に設定した場合、コネクタはこの推論をスキップし、フィールドを STRING のままにします。

      説明

      このパラメーターは、Ververica Runtime (VVR) 11.8 以降でのみサポートされます。

      canal-json.infer-schema.strategy

      いいえ

      String

      AUTO

      テーブルスキーマの解析戦略。

      有効な値:

      • AUTO: JSON データからスキーマを自動的に解析します。解析エラーを防ぐため、データに sqlType フィールドが含まれていない場合に推奨されます。

      • SQL_TYPE: Canal JSON データ内の sqlType 配列からスキーマを解析します。データに sqlType フィールドが含まれている場合、より正確な型を取得するために、これを SQL_TYPE に設定することをお勧めします。

      • MYSQL_TYPE: Canal JSON データ内の mysqlType 配列からスキーマを解析します。

      Kafka の Canal JSON データに sqlType フィールドが含まれており、より正確な型マッピングが必要な場合は、canal-json.infer-schema.strategy を SQL_TYPE に設定します。

      sqlType 型マッピングルールの詳細については、「Canal JSON のスキーマ解析」をご参照ください。

      説明
      • この構成は、Ververica Runtime (VVR) 11.1 以降でのみサポートされます。

      • MYSQL_TYPE 値は、Ververica Runtime (VVR) 11.3 以降でサポートされています。

      canal-json.mysql.treat-mysql-timestamp-as-datetime-enabled

      いいえ

      Boolean

      true

      MySQL の TIMESTAMP 型を CDC の TIMESTAMP 型にマッピングします。

      • true: MySQL TIMESTAMP 型は CDC TIMESTAMP 型にマップされます。

      • false: MySQL の TIMESTAMP タイプは、CDC の TIMESTAMP_LTZ タイプにマップされます。

      canal-json.mysql.treat-tinyint1-as-boolean.enabled

      いいえ

      Boolean

      true

      MYSQL_TYPE 解析ストラテジーを使用する場合、MySQL の TINYINT(1) 型を CDC の BOOLEAN 型にマッピングするかどうかを制御します。

      • true: MySQL の TINYINT(1) 型は、CDC の BOOLEAN 型にマッピングされます。

      • false: MySQL の TINYINT(1) 型は、CDC の TINYINT(1) 型にマッピングされます。

      このオプションは、canal-json.infer-schema.strategyMYSQL_TYPE に設定されている場合にのみ適用されます。

    • JSON フォーマットパラメーター

      パラメーター

      必須

      デフォルト

      説明

      json.timestamp-format.standard

      いいえ

      String

      SQL

      入出力データのタイムスタンプフォーマット。

      • SQL: yyyy-MM-dd HH:mm:ss.s{precision} フォーマット(例: 2020-12-30 12:13:14.123)で入力タイムスタンプを解析します。

      • ISO-8601: yyyy-MM-ddTHH:mm:ss.s{precision} フォーマット (2020-12-30T12:13:14.123 など) で入力タイムスタンプを解析します。

      json.ignore-parse-errors

      いいえ

      Boolean

      false

      有効な値:

      • true:解析例外が発生した場合、現在の行をスキップします。

      • false:エラーをスローし、ジョブは起動に失敗します。

      json.infer-schema.primitive-as-string

      いいえ

      Boolean

      false

      テーブルスキーマの解析時に、すべてのプリミティブ型を String として解析します。

      有効な値:

      • true: すべてのプリミティブ型を String として解析します。

      • false:デフォルトのルールに基づいて型を解析します。

      json.infer-schema.string-type-inference

      いいえ

      Boolean

      true

      文字列フィールドを TIME、DATE、または TIMESTAMP として推論するかどうかを指定します。このパラメーターを false に設定した場合、コネクタはこの推論をスキップし、フィールドを STRING として保持します。

      説明

      このパラメーターは、Ververica Runtime (VVR) 11.8 以降でのみサポートされます。

      json.infer-schema.flatten-nested-columns.enable

      いいえ

      Boolean

      false

      JSON データのネストされた列を再帰的に展開します。有効な値:

      • true:ネストされた列を再帰的に展開します。

      • false: ネストされたカラムを String として扱います。

      json.decode.parser-table-id.fields

      いいえ

      String

      JSON 形式のデータを解析する際に、指定された JSON フィールドの値を使用して tableId を生成します。複数のフィールドの値は英語のカンマ , で連結されます。たとえば、JSON データが {"col0":"a", "col1","b", "col2","c"} の場合、生成される結果は次のようになります:

      構成

      tableId

      col0

      a

      col0,col1

      a.b

      col0,col1,col2

      a.b.c

      json.infer-schema.fixed-types

      いいえ

      String

      JSON データを解析するとき、特定のフィールドのデータの型を指定できます。カンマ , を使用して複数のフィールドを区切ります。たとえば、id BIGINT, name VARCHAR(10) は、id フィールドが BIGINT 型であり、name フィールドが VARCHAR(10) 型であることを指定します。

      説明
      • この構成オプションは、Ververica Runtime (VVR) 11.5 以降でのみサポートされます。

      • Ververica Runtime (VVR) バージョン 11.5 でこの構成を使用する場合、構成 scan.max.pre.fetch.records: 0 も追加する必要があります。

      json.decode.empty-value-as-delete.enabled

      いいえ

      Boolean

      false

      Kafka の圧縮トピック内のトゥームストーンメッセージ (空の値を持つ) を DELETE イベントとして解析するかどうかを指定します。空の値が削除セマンティクスを表すシナリオ (圧縮トピックのミラーリングや CDC の削除シグナルなど) で使用されます。

      説明

      この構成オプションは、Ververica Runtime (VVR) 11.7 以降でのみサポートされます。

  • シンクテーブルのパラメーター

    パラメーター

    説明

    必須

    デフォルト

    備考

    type

    シンクのタイプ。

    はい

    String

    値は kafka である必要があります。

    name

    シンクの名前。

    いいえ

    String

    なし

    topic

    Kafka トピック名。

    いいえ

    String

    このパラメーターが指定されている場合、すべてのデータはこのトピックに書き込まれます。

    説明

    このパラメーターが指定されていない場合、各レコードは TableID にちなんで名付けられたトピックに書き込まれます。TableID は、データベース名とテーブル名をピリオド (.) で結合して構築されます。例:databaseName.tableName

    partition.strategy

    Kafka パーティションの書き込み戦略。

    いいえ

    String

    all-to-zero

    有効な値:

    • all-to-zero (デフォルト):すべてのデータをパーティション 0 に書き込みます。

    • hash-by-key:プライマリキーのハッシュ値に基づいてデータをパーティションに書き込みます。これにより、同じプライマリキーを持つレコードが同じパーティションに書き込まれ、順序が保持されます。

    sink.tableId-to-topic.mapping

    上流のテーブル名から下流の Kafka トピック名へのマッピング。

    いいえ

    String

    マッピングはセミコロン (;) で区切ります。各マッピング内で、上流のテーブル名と下流の Kafka トピック名をコロン (:) で区切ります。テーブル名には正規表現を使用できます。複数のテーブルを同じトピックにマッピングするには、テーブル名をカンマ (,) で区切ります。例:mydb.mytable1:topic1;mydb.mytable2:topic2

    説明

    このパラメーターを使用すると、元のテーブル名情報を保持したまま、マッピングされたトピックを変更できます。

    • Canal JSON フォーマットパラメーター

      パラメーター

      必須

      デフォルト

      説明

      canal-json.serialize.update.keep-changed-fields-only

      いいえ

      Boolean

      false

      Canal JSON フォーマットの UPDATE メッセージの old セクションに、変更されたフィールドの以前の値のみを含めるかどうかを指定します。

      説明

      このパラメーターは、Ververica Runtime (VVR) 11.8 以降でのみサポートされます。

    • Debezium JSON フォーマットパラメーター

      パラメーター

      必須

      デフォルト

      説明

      debezium-json.include-schema.enabled

      いいえ

      Boolean

      false

      Debezium JSON データにスキーマ情報を含めます。

      debezium-json.emit.full-table-id.enabled

      いいえ

      Boolean

      false

      完全な 3 部構成のテーブル ID を Debezium JSON メタデータフィールドに書き込みます。

      このパラメーターが有効な場合、マッピングは次のようになります:

      CDC テーブル ID の部分

      Debezium JSON キー

      名前空間

      db

      スキーマ

      schema

      テーブル

      table

      このパラメーターが無効な場合、マッピングは次のようになります:

      CDC テーブル ID の部分

      Debezium JSON キー

      名前空間

      マッピングされていません

      スキーマ

      db

      テーブル

      table

      説明

      このパラメーターは、Ververica Runtime (VVR) 11.6 以降でのみサポートされます。

  • Kafka を Flink CDC ソースとして使用する:

    source:
      type: kafka
      name: Kafka source
      properties.bootstrap.servers: ${kafka.bootstraps.server}
      topic: ${kafka.topic}
      value.format: ${value.format}
      scan.startup.mode: ${scan.startup.mode}
     
    sink:
      type: hologres
      name: Hologres sink
      endpoint: <yourEndpoint>
      dbname: <yourDbname>
      username: ${secret_values.ak_id}
      password: ${secret_values.ak_secret}
      sink.type-normalize-strategy: BROADEN
  • Kafka を Flink CDC シンクとして使用する:

    source:
      type: mysql
      name: MySQL Source
      hostname: ${secret_values.mysql.hostname}
      port: ${mysql.port}
      username: ${secret_values.mysql.username}
      password: ${secret_values.mysql.password}
      tables: ${mysql.source.table}
      server-id: 8601-8604
    
    sink:
      type: kafka
      name: Kafka Sink
      properties.bootstrap.servers: ${kafka.bootstraps.server}
    
    route:
      - source-table: ${mysql.source.table}
        sink-table: ${kafka.topic}

    route モジュールは、ソーステーブルの送信先 Kafka トピックを指定します。

説明

デフォルトでは、ApsaraMQ for Kafka の自動トピック作成機能は無効になっています。詳細については、「自動トピック作成に関するよくある質問」をご参照ください。ApsaraMQ for Kafka にデータを書き込む前に、トピックを作成する必要があります。詳細については、「ステップ 3:リソースの作成」をご参照ください。

スキーマ解析と進化のポリシー

Kafka コネクタは、現在既知のすべてのテーブルのスキーマを維持します。

テーブルスキーマの初期化

テーブルスキーマには、列とデータ型、データベースとテーブル名、およびプライマリキーが含まれます。次のセクションでは、これらのそれぞれを初期化する方法について説明します。

  • 列とデータ型の情報

Flink CDC ジョブはデータから列とデータ型を自動的に推論できますが、特定のテーブルに対して明示的に定義したい場合があります。型をどの程度制御する必要があるかに応じて、3 つのスキーマ初期化戦略があります:

  1. 完全自動スキーマ推論

Kafka からデータを読み取る前に、Kafka コネクタは各パーティションから最大 scan.max.pre.fetch.records 個のメッセージを消費しようとし、各メッセージのスキーマを解析し、これらのスキーマをマージしてテーブルスキーマを初期化します。その後、データが実際に消費される前に、この初期化されたスキーマに基づいてテーブル作成イベントが生成されます。

説明

Debezium JSON および Canal JSON フォーマットの場合、テーブル情報は各メッセージ内に含まれています。scan.max.pre.fetch.records パラメーターに基づいて事前にフェッチされたメッセージには、複数のテーブルのデータが含まれている可能性があります。したがって、単一のテーブルに対して事前にフェッチされたレコードの数は決定できません。事前フェッチとスキーマの初期化は、メッセージが消費されて処理される前に、各パーティションに対して 1 回だけ実行されます。後で新しいテーブルのデータが表示された場合、そのテーブルの最初のレコードから解析されたスキーマが初期スキーマとして使用され、スキーマは再度事前フェッチまたは初期化されません。

重要

単一テーブルのデータを複数のパーティションに分散させることは、Ververica Runtime (VVR) 8.0.11 以降でのみサポートされており、debezium-json.distributed-tables または canal-json.distributed-tables 構成オプションを true に設定する必要があります。

  1. 初期テーブルスキーマの指定

場合によっては、初期テーブルスキーマを明示的に定義する必要があります。たとえば、Kafka から既存の下流テーブルにデータを書き込む場合などです。この場合、scan.value.initial-schemas.ddls パラメーターを追加することで行うことができます。以下は構成例です:

source:
  type: kafka
  name: Kafka Source
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # 初期テーブルスキーマを設定
  scan.value.initial-schemas.ddls: CREATE TABLE db1.t1 (id BIGINT, name VARCHAR(10)); CREATE TABLE db1.t2 (id BIGINT);

DDL 文は、ターゲットテーブルのスキーマと一致している必要があります。この構成では、db1.t1 テーブルの id 列の初期型を BIGINTname 列を VARCHAR(10) と指定し、db1.t2 テーブルの id 列の初期型を BIGINT と指定します。

DDL 文は Flink SQL 構文を使用します。

  1. 特定フィールドの固定型の設定

特定のフィールドを固定データ型にロックしたい場合があります。たとえば、通常は TIMESTAMP として推論されるフィールドを、代わりに文字列として出力する必要がある場合などです。この場合、json.infer-schema.fixed-types パラメーターを追加して、初期テーブルスキーマを指定できます。このパラメーターは、メッセージ形式が JSON の場合にのみ有効です。以下は構成例です:

source:
  type: kafka
  name: Kafka Source
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # 特定のフィールドを固定型に設定
  json.infer-schema.fixed-types: id BIGINT, name VARCHAR(10)
  scan.max.pre.fetch.records: 0

この構成では、すべての id フィールドが BIGINT 型であり、すべての name フィールドが VARCHAR(10) 型であることが指定されます。

データ型は Flink SQL 型と一致しています。

  • データベースとテーブルの情報

    • Canal JSON および Debezium JSON フォーマットの場合、コネクタは各メッセージからデータベースとテーブル名を含むテーブル情報を解析します。

    • JSON フォーマットの場合、デフォルトでは、テーブル情報にはテーブル名のみが含まれ、これはデータを含むトピックの名前です。データにデータベースとテーブル情報が含まれている場合は、json.infer-schema.fixed-types パラメーターを使用して、この情報を含むフィールドを指定できます。これらのフィールドは、データベース名とテーブル名にマッピングされます。以下は構成例です:

      source:
        type: kafka
        name: Kafka Source
        properties.bootstrap.servers: host:9092
        topic: test-topic
        value.format: json
        scan.startup.mode: earliest-offset
        # col1 フィールドの値をデータベース名として、col2 フィールドの値をテーブル名として使用
        json.decode.parser-table-id.fields: col1,col2

      この構成では、コネクタは各レコードを、データベース名が col1 フィールドの値、テーブル名が col2 フィールドの値であるテーブルに送信します。

  • プライマリキー情報

    • Canal JSON フォーマットの場合、JSON データの pkNames フィールドがテーブルのプライマリキーを定義します。

    • Debezium JSON および JSON フォーマットの場合、データにはプライマリキー情報が含まれていません。transform ルールを使用して、テーブルにプライマリキーを手動で追加できます:

      transform:
        - source-table: \.*.\.*
          projection: \*
          primary-keys: key1, key2

スキーマ解析とスキーマ進化

テーブルスキーマが初期化された後、schema.inference.strategy が static に設定されている場合、Kafka コネクタは初期テーブルスキーマに基づいて各メッセージのメッセージ値を解析し、スキーマ変更イベントを生成しません。schema.inference.strategy が continuous に設定されている場合、Kafka コネクタは各 Kafka メッセージのメッセージ値を解析し、その物理列を識別し、結果のスキーマを現在維持されているスキーマと比較します。スキーマが一致しない場合、コネクタはそれらをマージしようとし、対応するテーブルスキーマ変更イベントを生成します。マージルールは次のとおりです:

  • 解析された物理列に現在のスキーマに存在しないフィールドが含まれている場合、これらのフィールドはスキーマに追加され、それらを null 許容列として追加するイベントが生成されます。

  • 解析された物理列が、現在のスキーマに存在するフィールドを含まない場合、それらのフィールドは保持され、その値には NULL が設定されます。列削除イベントは生成されません。

  • 同じ名前の列は次のように処理されます:

    • 列のデータ型は同じだが精度が異なる場合、精度の大きい方の型が使用され、列の型変更イベントが生成されます。

    • 列のデータ型が異なる場合、システムは以下の型階層ツリーで最小の共通親型を見つけます。システムはその後、この共通親型を列に使用し、列の型変更イベントを生成します。

      image

  • サポートされているスキーマ進化ポリシー:

    • 列の追加:コネクタは新しい列をスキーマの末尾に追加し、そのデータを同期します。新しい列は null 許容として設定されます。

    • 列の削除:列削除イベントは生成されません。代わりに、その列の後続のデータには NULL が設定されます。

    • 列の名前変更:コネクタはこれを、古い列を削除して新しい列を追加する処理として扱います。新しい列はスキーマの末尾に追加され、元の列の値には NULL が入力されます。

    • 列の型の変更:

      • カラムタイプの変更をサポートするダウンストリーム sink が、その変更を処理するように設定されている場合、Flink CDC ジョブはその変更 (たとえば、INT から BIGINT へ) に対応できます。 この機能は、特定の sink でサポートされているカラムタイプ変更ルールに依存します。 サポートされているルールについては、ご使用の sink のドキュメントを参照してください。

      • Hologres のように列の型の変更をサポートしない下流のシンクの場合、型の拡張を使用できます。この機能は、ジョブの開始時に下流のシンクに広いデータ型を持つテーブルを作成します。列の型が変更された場合、新しい型が下流のシンクで定義された広い型に収まる限り、システムはその変更を許容できます。

  • サポートされていないスキーマ変更:

    • プライマリキーやインデックスなどの制約の変更。

    • 列を NOT NULL から NULLABLE に変更すること。

  • Canal JSON スキーマ解析

    Canal JSON データには、データ列の正確な型情報を記録するオプションの sqlType フィールドが含まれる場合があります。より正確なスキーマを取得するには、canal-json.infer-schema.strategySQL_TYPE に設定して、sqlType フィールドの型を使用できます。型マッピングは次のとおりです。

    JDBC 型

    型コード

    CDC 型

    BIT

    -7

    BOOLEAN

    BOOLEAN

    16

    TINYINT

    -6

    TINYINT

    SMALLINT

    5

    SMALLINT

    INTEGER

    4

    INT

    BIGINT

    -5

    BIGINT

    DECIMAL

    3

    DECIMAL(38,18)

    NUMERIC

    2

    REAL

    7

    FLOAT

    FLOAT

    6

    DOUBLE

    8

    DOUBLE

    BINARY

    -2

    BYTES

    VARBINARY

    -3

    LONGVARBINARY

    -4

    BLOB

    2004

    DATE

    91

    DATE

    TIME

    92

    TIME

    TIMESTAMP

    93

    TIMESTAMP

    CHAR

    1

    STRING

    VARCHAR

    12

    LONGVARCHAR

    -1

    その他のデータ型

ダーティデータの許容範囲とコレクション

ご利用の Kafka データソースには、一般的にダーティデータと呼ばれる不正なレコードが含まれている場合があります。ジョブの度重なる失敗や再起動を防ぐため、これらの無効なレコードをスキップするように構成できます。以下に例を示します。

source:
  type: kafka
  name: Kafka Source
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # Enable Dirty Data Tolerance
  ingestion.ignore-errors: true
  # Tolerate up to 1000 dirty data records
  ingestion.error-tolerance.max-count: 1000

この構成では、ジョブは 1,000 件以下のダーティレコードを検出する限り、実行を継続します。その数がしきい値を超えると、ジョブは失敗するため、データを調査できます。

ダーティデータによってジョブが決して失敗しないようにするには、以下の構成を使用します。

source:
  type: kafka
  name: Kafka Source
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # Enable Dirty Data Tolerance
  ingestion.ignore-errors: true
  # Tolerate all dirty data records
  ingestion.error-tolerance.max-count: -1

ダーティデータの許容範囲を設定することでジョブは実行し続けますが、問題のあるレコードを検査したい場合もあるでしょう。また、ダーティデータを分析して Kafka プロデューサーを改善することもできます。「ダーティデータのコレクション」で説明されているように、TaskManager のログでジョブのダーティデータを確認できます。以下に例を示します。

source:
  type: kafka
  name: Kafka Source
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # Enable Dirty Data Tolerance
  ingestion.ignore-errors: true
  # Tolerate all dirty data records
  ingestion.error-tolerance.max-count: -1

pipeline:
  dirty-data.collector:
    # Write dirty data to the TaskManager log file
    type: logger

テーブル名とトピックのマッピング

Kafka が Flink CDC の sink として機能する場合、メッセージフォーマット (Debezium JSON や Canal JSON など) には元のテーブル名が埋め込まれます。下流のコンシューマーは通常、トピック名ではなく、この埋め込まれた名前をテーブル識別子として使用するため、テーブル名とトピック間のマッピングを正しく設定することが重要です。

MySQL データベースから 2 つのテーブル、mydb.mytable1mydb.mytable2 を同期する必要があるとします。次のマッピング戦略を利用できます:

1. マッピング戦略なし

マッピング戦略がない場合、各テーブルのデータは「<データベース名>.<テーブル名>」というフォーマットで命名されたトピックに書き込まれます。したがって、mydb.mytable1 のデータは mydb.mytable1 という名前のトピックに、mydb.mytable2 のデータは mydb.mytable2 という名前のトピックに書き込まれます。以下に構成例を示します:

source:
  type: mysql
  name: MySQL Source
  hostname: ${secret_values.mysql.hostname}
  port: ${mysql.port}
  username: ${secret_values.mysql.username}
  password: ${secret_values.mysql.password}
  tables: mydb.mytable1,mydb.mytable2
  server-id: 8601-8604

sink:
  type: kafka
  name: Kafka Sink
  properties.bootstrap.servers: ${kafka.bootstraps.server}

2. ルートルールによるマッピング (非推奨)

デフォルトの「<データベース名>.<テーブル名>」フォーマットを使用する代わりに、特定のトピックにデータを書き込みたい場合があります。その場合、ルートルールを設定できます。以下に構成例を示します:

source:
  type: mysql
  name: MySQL Source
  hostname: ${secret_values.mysql.hostname}
  port: ${mysql.port}
  username: ${secret_values.mysql.username}
  password: ${secret_values.mysql.password}
  tables: mydb.mytable1,mydb.mytable2
  server-id: 8601-8604

sink:
  type: kafka
  name: Kafka Sink
  properties.bootstrap.servers: ${kafka.bootstraps.server}
  
 route:
  - source-table: mydb.mytable1,mydb.mytable2
    sink-table: mytable

この場合、mydb.mytable1mydb.mytable2 からのすべてのデータは、mytable という名前の単一のトピックに書き込まれます。

ただし、送信先トピックを変更するルートルールは、Kafka メッセージ (Debezium JSON または Canal JSON フォーマット) 内のテーブル名も変更してしまいます。すべての Kafka メッセージ内のテーブル名が mytable となり、このトピックからメッセージを消費するシステムで予期しない動作を引き起こす可能性があります。

3. sink.tableId-to-topic.mapping によるマッピング (推奨)

元のソーステーブル名を保持したままテーブル名をトピックにマッピングするには、`sink.tableId-to-topic.mapping` パラメーターを使用します。以下に構成例を示します:

source:
  type: mysql
  name: MySQL Source
  hostname: ${secret_values.mysql.hostname}
  port: ${mysql.port}
  username: ${secret_values.mysql.username}
  password: ${secret_values.mysql.password}
  tables: mydb.mytable1,mydb.mytable2
  server-id: 8601-8604
  sink.tableId-to-topic.mapping: mydb.mytable1,mydb.mytable2:mytable

sink:
  type: kafka
  name: Kafka Sink
  properties.bootstrap.servers: ${kafka.bootstraps.server}

または、以下の構成を使用することもできます:

source:
  type: mysql
  name: MySQL Source
  hostname: ${secret_values.mysql.hostname}
  port: ${mysql.port}
  username: ${secret_values.mysql.username}
  password: ${secret_values.mysql.password}
  tables: mydb.mytable1,mydb.mytable2
  server-id: 8601-8604
  sink.tableId-to-topic.mapping: mydb.mytable1:mytable;mydb.mytable2:mytable

sink:
  type: kafka
  name: Kafka Sink
  properties.bootstrap.servers: ${kafka.bootstraps.server}

この場合、mydb.mytable1mydb.mytable2 からのすべてのデータは mytable トピックに書き込まれ、Kafka メッセージ (Debezium JSON または Canal JSON フォーマット) 内のテーブル名は mydb.mytable1 または mydb.mytable2 として保持されます。これにより、下流のシステムは各レコードの元のソーステーブルを識別し続けることができます。

設定例

以下の例では、一般的なユースケースの設定を示します。

単一トピックからの読み取り

以下の例では、customers トピックを読み取り、データを Alibaba Cloud データレイク に書き込みます。

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
  schema.inference.strategy: continuous

sink:
  type: paimon
  name: Paimon Sink
  catalog.properties.metastore: rest
  catalog.properties.uri: dlf_uri
  catalog.properties.warehouse: your_warehouse
  catalog.properties.token.provider: dlf
  # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
  commit.user: your_job_name
  # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
  table.properties.deletion-vectors.enabled: true

JSON フォーマットの場合、生成されるテーブル名はデフォルトでトピック名と同じになります。

複数トピックからの読み取り

以下の例では、名前が正規表現に一致するトピックを読み取り、データを StarRocks に書き込みます。

source:
  type: kafka
  topic-pattern: user_event_.*
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
  schema.inference.strategy: continuous

sink:
  type: starrocks
  jdbc-url: jdbc:mysql://<yourFeHostname>:9030
  load-url: <yourFeHostname>:8030
  username: <yourUsername>
  password: ${secret_values.starrocks_password}
 
  # オプション: データ量が少ないジョブの場合、フラッシュ間隔を短くして、データが長時間書き込まれないままになるのを防ぎます。デフォルトは 300000 ミリ秒 (5 分) です。
  sink.buffer-flush.interval-ms: 5000
  # オプション: アップストリームの文字セットが utf8mb4 の場合、テキストの切り捨てを防ぐためにこのパラメーターを 4 に設定します。デフォルトは 3 です。
  unicode-char.max-bytes: 4
  # オプション: 自動作成されるテーブルのバケット数を指定します。StarRocks バージョン 2.5.7 より前では、このパラメーターを明示的に設定する必要があります。それ以降のバージョンでは値を推論できます。
  table.create.num-buckets: 8
  # オプション: クラスター構成に基づいて、自動作成されるテーブルのレプリカ数を指定します。
  table.create.properties.replication_num: 3
  # オプション: StarRocks 3.2 以降では、この機能を有効にしてスキーマ変更を高速化します。
  table.create.properties.fast_schema_evolution: true
  # 注: 変換によってプライマリキーが変更された場合は、sink.ignore.update-before も false に設定する必要があります。
  # そうしないと、古いプライマリキーを使用する行がダウンストリームシステムに残ってしまいます。

JSON フォーマットの場合、生成されるテーブル名はデフォルトでトピック名と同じになります。

キーの読み取りとフィールド競合の防止

キーと値でフィールド名が重複することによって発生するエラーは、以下のいずれかの方法で防ぐことができます。

  1. フィールドにプレフィックスを追加して競合を防ぎます。

    source:
      type: kafka
      topic: ${kafka.topic}
      properties.bootstrap.servers: localhost:9092
      properties.group.id: ${kafka.group.id}
      key.format: json
      value.format: json
      # キーのフィールド名に key_ プレフィックスを追加します。
      key.fields-prefix: key_
      # 値のフィールド名に value_ プレフィックスを追加します。
      value.fields-prefix: value_
      # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
      schema.inference.strategy: continuous
    
    sink:
      type: paimon
      name: Paimon Sink
      catalog.properties.metastore: rest
      catalog.properties.uri: dlf_uri
      catalog.properties.warehouse: your_warehouse
      catalog.properties.token.provider: dlf
      # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
      commit.user: your_job_name
      # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
      table.properties.deletion-vectors.enabled: true
  2. 競合解決ポリシーを設定します。詳細については、「scan.duplicate-field.strategy」をご参照ください。以下の設定では、キーのフィールドを優先し、値の中の同じ名前のフィールドは無視します。

    source:
      type: kafka
      topic: ${kafka.topic}
      properties.bootstrap.servers: localhost:9092
      properties.group.id: ${kafka.group.id}
      key.format: json
      value.format: json
      # キーのフィールドを優先し、値の中の同じ名前のフィールドは無視します。
      scan.duplicate-field.strategy: PREFER_KEY
      # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
      schema.inference.strategy: continuous
    
    sink:
      type: paimon
      name: Paimon Sink
      catalog.properties.metastore: rest
      catalog.properties.uri: dlf_uri
      catalog.properties.warehouse: your_warehouse
      catalog.properties.token.provider: dlf
      # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
      commit.user: your_job_name
      # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
      table.properties.deletion-vectors.enabled: true

メタデータ列の追加

以下の例では、customers トピックを読み取り、topicpartition のメタデータ列を追加します。

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
  schema.inference.strategy: continuous
  metadata.list: topic,partition

sink:
  type: paimon
  name: Paimon Sink
  catalog.properties.metastore: rest
  catalog.properties.uri: dlf_uri
  catalog.properties.warehouse: your_warehouse
  catalog.properties.token.provider: dlf
  # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
  commit.user: your_job_name
  # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
  table.properties.deletion-vectors.enabled: true

解析エラーの処理

解析エラーが発生するとジョブは失敗します。ジョブが解析エラーを許容するように設定できます。この機能は、一般的に ダーティデータ収集 と組み合わせて使用されます。

以下の例では、すべての解析エラーを無視します。

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
  schema.inference.strategy: continuous
  # 解析エラーを無視します。この機能を有効にすると、デフォルトですべての解析エラーが無視されます。
  ingestion.ignore-errors: true

sink:
  type: paimon
  name: Paimon Sink
  catalog.properties.metastore: rest
  catalog.properties.uri: dlf_uri
  catalog.properties.warehouse: your_warehouse
  catalog.properties.token.provider: dlf
  # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
  commit.user: your_job_name
  # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
  table.properties.deletion-vectors.enabled: true
  
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

以下の例では、30 回の解析エラーが発生した後にジョブを失敗させます。

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
  schema.inference.strategy: continuous
  # 解析エラーを無視します。
  ingestion.ignore-errors: true
  # 30 回の解析エラーが発生した後にジョブを失敗させます。
  ingestion.error-tolerance.max-count: 30
  
sink:
  type: paimon
  name: Paimon Sink
  catalog.properties.metastore: rest
  catalog.properties.uri: dlf_uri
  catalog.properties.warehouse: your_warehouse
  catalog.properties.token.provider: dlf
  # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
  commit.user: your_job_name
  # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
  table.properties.deletion-vectors.enabled: true
  
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

JSON データの読み取り

以下のセクションでは、JSON フォーマットのデータを読み取る一般的な方法について説明します。

テーブル ID の解析方法の指定

デフォルトでは、JSON データのテーブル ID はトピック名です。データ内のフィールド値をテーブル ID として使用できます。以下の例では、db フィールドと tbl フィールドをテーブル ID として使用します。

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
  schema.inference.strategy: continuous
  # db フィールドと tbl フィールドをテーブル ID として使用します。
  value.json.decode.parser-table-id.fields: db,tbl

sink:
  type: paimon
  name: Paimon Sink
  catalog.properties.metastore: rest
  catalog.properties.uri: dlf_uri
  catalog.properties.warehouse: your_warehouse
  catalog.properties.token.provider: dlf
  # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
  commit.user: your_job_name
  # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
  table.properties.deletion-vectors.enabled: true
  
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

フィールドタイプの指定

フィールドタイプはフィールド値から推論されますが、推論されたタイプが期待するタイプではない場合があります。選択したフィールドに固定タイプを指定し、それらのフィールドに対する後続の型推論と進化をスキップできます。

以下の例では、4 つのフィールドのタイプを固定します。

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # db フィールドと tbl フィールドをテーブル ID として使用します。
  value.json.decode.parser-table-id.fields: db,tbl
  # 選択したフィールドに固定タイプを指定します。
  value.json.infer-schema.fixed-types: 'db STRING, tbl STRING, id BIGINT, amount DECIMAL(18, 2)'
  # 宣言されていないフィールドは引き続き動的に推論します。
  schema.inference.strategy: continuous

sink:
  type: paimon
  name: Paimon Sink
  catalog.properties.metastore: rest
  catalog.properties.uri: dlf_uri
  catalog.properties.warehouse: your_warehouse
  catalog.properties.token.provider: dlf
  # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
  commit.user: your_job_name
  # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
  table.properties.deletion-vectors.enabled: true
  
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

Canal JSON データの読み取り

以下のセクションでは、Canal JSON フォーマットのデータを読み取る一般的な方法について説明します。

型推論ポリシーの設定

デフォルトでは、コネクタは Canal JSON データを読み取る際に、フィールド値からスキーマタイプを推論します。

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: canal-json
  # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
  schema.inference.strategy: continuous

sink:
  type: paimon
  name: Paimon Sink
  catalog.properties.metastore: rest
  catalog.properties.uri: dlf_uri
  catalog.properties.warehouse: your_warehouse
  catalog.properties.token.provider: dlf
  # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
  commit.user: your_job_name
  # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
  table.properties.deletion-vectors.enabled: true
  
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

Canal JSON データに記録されている SQL 型や MySQL 型などのスキーマ情報からスキーマを推論することもできます。以下の例では、MySQL 型を使用してスキーマを推論します。

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: canal-json
  # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
  schema.inference.strategy: continuous
  # MySQL 型情報からスキーマを推論します。このパラメーターを SQL_TYPE に設定して、代わりに SQL 型情報を使用することもできます。
  value.canal-json.infer-schema.strategy: MYSQL_TYPE

sink:
  type: paimon
  name: Paimon Sink
  catalog.properties.metastore: rest
  catalog.properties.uri: dlf_uri
  catalog.properties.warehouse: your_warehouse
  catalog.properties.token.provider: dlf
  # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
  commit.user: your_job_name
  # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
  table.properties.deletion-vectors.enabled: true
  
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

Debezium JSON データの読み取り

以下の例では、customers トピックを読み取り、データを Alibaba Cloud データレイク に書き込みます。

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: debezium-json
  # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
  schema.inference.strategy: continuous

sink:
  type: paimon
  name: Paimon Sink
  catalog.properties.metastore: rest
  catalog.properties.uri: dlf_uri
  catalog.properties.warehouse: your_warehouse
  catalog.properties.token.provider: dlf
  # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
  commit.user: your_job_name
  # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
  table.properties.deletion-vectors.enabled: true

生の MySQL binlog の Kafka への同期

Flink CDC データインジェストは、生の MySQL binlog データを Canal JSON フォーマットで同期できます。以下のジョブは、複数のテーブルから order_dw_tables トピックに binlog を同期します。

source:
  type: mysql
  hostname: #{hostname}
  port: 3306
  username: #{username}
  password: #{password}
  tables: order_dw.\.*
  server-id: 28601-28604
  # オプション: 増分フェーズで作成されたテーブルからデータを同期します。
  scan.binlog.newly-added-table.enabled: true
  # オプション: テーブルと列のコメントを同期します。
  include-comments.enabled: true
  # オプション: TaskManager のメモリ不足エラーの可能性を防ぐために、まず非有界チャンクを処理します。
  scan.incremental.snapshot.unbounded-chunk-first.enabled: true
  # オプション: 解析フィルターを有効にして読み取りを高速化します。
  scan.only.deserialize.captured.tables.changelog.enabled: true
  # mysqlType、sqlType、sql、isDdl、およびその他のメタデータを Canal JSON データに追加します。
  include-binlog-meta.enable: true
  
sink:
  type: kafka
  properties.bootstrap.servers: localhost:9092
  topic: order_dw_tables
  # Kafka の値に Canal JSON チェンジログフォーマットを使用します。
  value.format: canal-json
  # 日付と時刻データのシリアル化に使用するフォーマットを指定します。
  value.canal-json.timestamp-format.standard: SQL
  # binlog の順序を維持するために、すべてのデータをパーティション 0 に書き込みます。
  partition.strategy: all-to-zero

Exactly-once セマンティクス

  • コンシューマーの分離レベルの設定

    Kafka データを消費するすべてのアプリケーションでは、isolation.level プロパティを設定する必要があります。

    • read_committed:コミット済みのデータのみを読み取ります。

    • read_uncommitted (デフォルト):コミットされていないデータも読み取ることができます。

    EXACTLY_ONCE は read_committed に依存します。そうでない場合、コンシューマーがコミットされていないデータを読み取り、一貫性が損なわれる可能性があります。

  • トランザクションタイムアウトとデータ損失

    チェックポイントから回復する際、Realtime Compute for Apache Flink は、そのチェックポイントが開始される前にコミットされたトランザクションのみを考慮します。ジョブの障害発生から再起動までの時間が Kafka のトランザクションタイムアウトを超えると、Kafka は開いているトランザクションを自動的に中止し、データ損失が発生する可能性があります。

    • Kafka ブローカーの transaction.max.timeout.ms のデフォルト値は 15 分です。

    • デフォルトでは、Flink Kafka Sink は transaction.timeout.ms パラメーターを 1 時間に設定します。

    • ブローカーの transaction.max.timeout.ms を、Flink での設定値以上に増やす必要があります。

  • プロデューサープールと同時チェックポイント

    EXACTLY_ONCE モードでは、固定サイズの Kafka プロデューサープールが使用されます。各チェックポイントは、このプールから 1 つのプロデューサーを使用します。同時チェックポイントの数がプールサイズを超えると、ジョブは失敗します。

    同時チェックポイントの最大数に基づいて、プロデューサープールのサイズを設定してください。

  • 並列度のスケールダウンに関する制約

    最初のチェックポイントが完了する前にジョブが失敗した場合、再起動時に元のプロデューサープールの情報が失われます。そのため、最初のチェックポイントが完了するまでは、ジョブの並列度をスケールダウンしないでください。スケールダウンが必要な場合でも、新しい並列度は FlinkKafkaProducer.SAFE_SCALE_DOWN_FACTOR 未満にすることはできません。

  • トランザクションによる読み取りのブロック

    read_committed モードでは、コミットも中止もされていないトランザクションがあると、トピック全体の読み取り操作がブロックされます。

    例:

    • トランザクション 1 がデータを書き込みます。

    • トランザクション 2 がさらにデータを書き込み、コミットされます。

    • トランザクション 1 が開いている限り、コミット済みのトランザクション 2 のデータはコンシューマーには表示されません。

    これには、以下の影響があります。

    • 通常の操作中、データが表示されるまでのレイテンシーは、おおよそチェックポイントの間隔と等しくなります。

    • ジョブが失敗した場合、そのジョブが書き込んでいたトピックは、ジョブが再起動するかトランザクションがタイムアウトするまで、コンシューマーに対してブロックされます。極端なケースでは、トランザクションのタイムアウト処理自体が読み取り操作に影響を与えることもあります。

よくある質問