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

Realtime Compute for Apache Flink:Kafka connector

最終更新日:May 23, 2026
[INFO] Doc info: docId=7454534, topicId=2306029, spaceId=133 [INFO] Document content read: nodeId=4073624, 327952 chars Kafka

Realtime Compute for Apache Flink では、 Kafka コネクタをソース、シンク、または Flink CDC デスティネーションとして使用します。

概要

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

カテゴリ

説明

サポートタイプ

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 シンクテーブルが提供する exactly-once セマンティクスを使用できません。Ververica Runtime (VVR) 8.0.0 以降、Kafka コネクタは Kafka クライアント 3.x を使用します。このクライアントでは、properties.enable.idempotence プロパティはデフォルトで true に設定されています。したがって、VVR 8.0.0 以降を使用して ApsaraMQ for Kafka に書き込む際の失敗を防ぐには、設定 properties.enable.idempotence=false をシンクテーブルの定義に追加する必要があります。ApsaraMQ for Kafka のストレージエンジンと機能制限の比較については、「ストレージエンジン間の比較」をご参照ください。

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

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

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

    • サポートされているのは、Apache Kafka バージョン 2.8 のクライアント設定オプションのみです。詳細については、Apache Kafka のドキュメント「Consumer Configs」および「Producer Configs」をご参照ください。

注意

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) の進行が妨げられる可能性があります。これにより、そのパーティションのすべてのコンシューマーが影響を受けます。

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

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

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

セルフマネージド Kafka

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

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

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

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

    • 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 がクライアントにアドバタイズするアドレスを見つけてください。

      example

    3. Realtime Compute for Apache Flink 開発コンソールの ネットワークプローブ 機能を使用して、このアドレスがアクセス可能かどうかをテストしてください。

      説明
      • アドレスにアクセスできない場合は、Kafka の管理者に問い合わせて、listeners および advertised.listeners の設定を確認し、アドバタイズされたアドレスが Realtime Compute for Apache Flink からアクセス可能であることを確認するように依頼してください。

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

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

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

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

メッセージのリーダーエポック。

ソーステーブル

offset

BIGINT NOT NULL METADATA VIRTUAL

メッセージオフセット。

ソーステーブル

timestamp

TIMESTAMP_LTZ(3) NOT NULL METADATA VIRTUAL

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

ソーステーブルとシンクテーブル

timestamp-type

STRING NOT NULL METADATA VIRTUAL

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

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

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

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

ソーステーブル

__raw_key__

BYTES NOT NULL METADATA VIRTUAL

RAW メッセージキー。

ソーステーブルとシンクテーブル

説明

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

__raw_value__

BYTES NOT NULL METADATA VIRTUAL

RAW メッセージ値。

ソーステーブルとシンクテーブル

説明

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

コネクタ オプション

  • 一般

    オプション

    説明

    タイプ

    必須

    デフォルト

    備考

    connector

    コネクタのタイプ。

    文字列

    はい

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

    properties.bootstrap.servers

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

    文字列

    はい

    フォーマット: host:port,host:port,...。アドレスはコンマ (,) で区切ります。

    properties.*

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

    文字列

    いいえ

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

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

    以下のオプションは Kafka コネクタによって上書きされるため、この方法では設定できません。

    • key.deserializer

    • value.deserializer

    format

    Kafka メッセージの値のシリアライズ/デシリアライズに使用するフォーマット。

    文字列

    いいえ

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

    • csv

    • json

    • avro

    • debezium-json

    • canal-json

    • maxwell-json

    • avro-confluent

    • raw

    説明

    詳細については、「Format options」をご参照ください。

    key.format

    Kafka メッセージのキーのシリアライズ/デシリアライズに使用するフォーマット。

    文字列

    いいえ

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

    • csv

    • json

    • avro

    • debezium-json

    • canal-json

    • maxwell-json

    • avro-confluent

    • raw

    説明

    この設定を使用する場合、key.options は必須です。

    key.fields

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

    文字列

    いいえ

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

    key.fields-prefix

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

    文字列

    いいえ

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

    説明

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

    value.format

    Kafka メッセージの値のシリアライズ/デシリアライズに使用するフォーマット。

    文字列

    いいえ

    この設定は format と同等です。formatvalue.format のいずれか一方のみを設定できます。両方を設定した場合、value.formatformat を上書きします。

    value.fields-include

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

    文字列

    いいえ

    ALL

    有効な値:

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

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

  • ソーステーブル

    オプション

    説明

    タイプ

    必須

    デフォルト

    備考

    topic

    読み込み元のトピックです。

    文字列

    不要

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

    説明

    このオプションと topic-pattern は、どちらか一方のみ指定できます。

    topic-pattern

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

    文字列

    不要

    例:

    • user_event_.*user_event_ で始まるすべてのトピックに一致します。

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

    説明

    このオプションと topic は、どちらか一方のみ指定できます。

    properties.group.id

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

    文字列

    不要

    KafkaSource-{Source-Table-Name}

    コンシューマーグループ ID を初めて使用する場合は、properties.auto.offset.resetearliest または latest に設定して、初期開始オフセットを指定する必要があります。

    scan.startup.mode

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

    文字列

    不要

    group-offsets

    有効な値:

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

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

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

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

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

    説明

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

    scan.startup.specific-offsets

    scan.startup.modespecific-offsets の場合に、パーティションごとに指定する開始オフセットです。

    文字列

    不要

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

    scan.startup.timestamp-millis

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

    Long

    不要

    単位はミリ秒です。

    scan.topic-partition-discovery.interval

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

    期間

    不要

    5 分

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

    説明

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

    scan.header-filter

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

    文字列

    不要

    ヘッダーキーとその値はコロン (:) で区切られます。複数のヘッダー条件は論理演算子 (& および |) を使用して接続されます。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 を使用しているかどうかを確認します。

    ブール

    不要

    false

    有効な値:

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

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

    説明

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

  • シンクテーブル

    オプション

    説明

    タイプ

    必須

    デフォルト

    備考

    topic

    ターゲットトピック

    文字列

    はい

    sink.partitioner

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

    文字列

    いいえ

    default

    有効な値:

    • default :デフォルトの Kafka パーティショナーを使用します。

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

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

    • カスタムパーティショナー:カスタムパーティショナーを使用するには、 FlinkKafkaPartitioner のサブクラスの完全修飾クラス名を指定します。例: org.mycompany.MyPartitioner

    sink.delivery-guarantee

    シンクの配信保証

    文字列

    いいえ

    at-least-once

    有効な値:

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

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

    • exactly-once :Kafka トランザクションを使用して exactly-once セマンティクスを提供し、レコードの消失や重複を防ぎます。

    説明

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

    sink.transactional-id-prefix

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

    文字列

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

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

    sink.parallelism

    シンクオペレーターの並列度

    整数

    いいえ

    デフォルトでは、フレームワークがアップストリームオペレーターに基づいて並列度を決定します。

セキュリティと認証

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

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) からファイルを動的にダウンロードする必要がなくなりますが、デバッグモードはサポートされません。

  • Realtime Compute のエンジンバージョンが 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 の運用保守チームに問い合わせて、正しいセキュリティと認証の設定を入手してください。

  • エスケープ:ネイティブの 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 シンクテーブルは、上流の変更データキャプチャ (CDC) データや、集計、結合などのオペレーターの撤回ロジックを処理できません。変更または撤回を含むデータを書き込む必要がある場合は、Upsert Kafka シンクテーブルを使用してください。

1 つ以上の上流データベーステーブルから Kafka への変更データキャプチャ (CDC) データのバッチ同期を簡素化するには、Kafka JSON カタログを使用できます。Kafka に保存されるデータが JSON フォーマットの場合、Kafka JSON カタログを使用すると、スキーマと WITH パラメーターを定義する手順を省略できます。詳細については、「Manage Kafka JSON catalogs」をご参照ください。

例 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');
-- null 値を処理するために COALESCE を使用します。

例 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 ソース は、Kafka ソース インスタンスを作成するためのビルダークラスを提供します。次の サンプルコード は、input-topic トピック の最も古い オフセット からデータを 消費する Kafka ソース を構築します。コンシューマーグループ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 Connectorは、Maven セントラルリポジトリで入手できます。

    <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 ソース には、通常、停止 オフセット はありません。ただし、テスト目的で、ストリーミングモード であっても setUnbounded(OffsetsInitializer) を使用して停止 オフセット を指定できます。停止 オフセット を指定するメソッド名が異なることに注意してください: ストリーミングモード では setUnboundedバッチモード では setBounded です。

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

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

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

      動的パーティション検出機能は、定期的に 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 コンシューマーの内部的な自動定期 オフセット コミットメカニズムに依存します。この機能は、Kafka コンシューマープロパティの enable.auto.commitauto.commit.interval.ms によって制御されます。

      説明

      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 は、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 は、メッセージキーと値のシリアライズ、トピックの選択、メッセージのパーティショニングなど、一般的なコンポーネントを提供するスキーマビルダーを提供します。より詳細な制御のために、対応するインターフェイスを実装することもできます。受信レコードごとに ProducerRecord<byte[], byte[]> serialize(T element, KafkaSinkContext context, Long timestamp) メソッドが呼び出され、Kafka に書き込む ProducerRecord が生成されます。

    ProducerRecord は、各レコードが Kafka に書き込まれる方法をきめ細かく制御し、次のことを可能にします:

    • 宛先 トピック を設定します。

    • メッセージキー を設定します。

    • 宛先 パーティション を指定します。

    Delivery guarantee

    The bootstrap.servers parameter is required and specifies a comma-separated list of Kafka brokers.

    配信保証

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

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

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

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

      説明

      EXACTLY_ONCE セマンティクスを使用する場合、「exactly-once セマンティクスの考慮事項」をご参照ください。

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 ソース
  properties.bootstrap.servers: localhost:9092
  topic: ${kafka.topic}
sink:
  type: kafka
  name: Kafka Sink
  properties.bootstrap.servers: localhost:9092

パラメーター

  • 一般

    パラメーター

    説明

    必須

    タイプ

    デフォルト

    備考

    type

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

    はい

    文字列

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

    name

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

    いいえ

    文字列

    properties.bootstrap.servers

    Kafka ブローカーのアドレスです。

    はい

    文字列

    形式は host:port,host:port,host:port で、コンマ (,) で区切ります。

    properties.*

    Kafka クライアントの設定プロパティです。

    いいえ

    文字列

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

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

    key.format

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

    いいえ

    文字列

    • ソースの場合、json フォーマットのみサポートされます。

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

      • csv

      • json

    説明

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

    value.format

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

    いいえ

    文字列

    debezium-json

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

      • debezium-json

      • canal-json

      • json

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

      • debezium-json

      • canal-json

      • canal-protobuf

    説明
    • debezium-json および canal-json フォーマットは、Realtime Compute for Apache Flink バージョン 8.0.10 以降でサポートされます。

    • json フォーマットは、Realtime Compute for Apache Flink バージョン 11.0.0 以降でサポートされます。

  • ソース パラメーター

    パラメータ

    説明

    必須

    デフォルト

    備考

    topic

    読み込むトピック。

    いいえ

    文字列

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

    説明

    このパラメータまたは topic-pattern のいずれかを指定する必要がありますが、両方を指定することはできません。

    topic-pattern

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

    いいえ

    文字列

    例:

    • user_event_.*user_event_ で始まるすべてのトピックに一致します。

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

    説明

    このパラメータまたは topic のいずれかを指定する必要がありますが、両方を指定することはできません。

    properties.group.id

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

    いいえ

    文字列

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

    scan.startup.mode

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

    いいえ

    文字列

    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 を設定した場合のパーティションごとの開始オフセット。

    いいえ

    文字列

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

    scan.startup.timestamp-millis

    scan.startup.modetimestamp を設定した場合のミリ秒単位の開始タイムスタンプ。

    いいえ

    Long

    単位はミリ秒です。

    scan.topic-partition-discovery.interval

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

    いいえ

    期間

    5min

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

    scan.check.duplicated.group.id

    properties.group.id で指定されたコンシューマーグループの重複をチェックするかどうかを指定します。

    いいえ

    Boolean

    false

    有効な値:

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

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

    schema.inference.strategy

    スキーマ推論戦略。

    いいえ

    文字列

    continuous

    有効な値:

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

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

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

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

    scan.max.pre.fetch.records

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

    いいえ

    整数

    50

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

    key.fields-prefix

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

    いいえ

    文字列

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

    説明

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

    value.fields-prefix

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

    いいえ

    文字列

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

    説明

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

    metadata.list

    ダウンストリームのシンクに渡すメタデータ列。

    いいえ

    文字列

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

    scan.value.initial-schemas.ddls

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

    いいえ

    文字列

    セミコロン(;)を使用して複数の 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 に設定されている場合のみ有効です。

    いいえ

    整数

    -1

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

    説明

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

    scan.duplicate-field.strategy

    キーと値から解析された、重複するフィールド名の処理方法を指定します。

    いいえ

    文字列

    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:デフォルトルールに基づいて型を解析します。

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

      パラメーター

      必須

      タイプ

      デフォルト

      説明

      canal-json.distributed-tables

      不要

      Boolean

      false

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

      説明

      この設定オプションは、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.strategy

      不要

      String

      AUTO

      テーブルスキーマの解析ストラテジー。

      有効な値:

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

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

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

      sqlType の型マッピングルールの詳細については、「Canal JSON's Schema parse」をご参照ください。

      説明
      • この設定オプションは、VVR 11.1 以降でのみサポートされています。

      • MYSQL_TYPE の値は、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.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) 型であることを指定します。

      説明
      • この設定オプションは、VVR 11.5 以降でのみサポートされています。

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

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

      不要

      Boolean

      false

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

      説明

      この設定オプションは、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

    説明

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

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

      パラメーター

      必須

      タイプ

      デフォルト

      説明

      debezium-json.include-schema.enabled

      いいえ

      ブール

      false

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

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

      いいえ

      ブール

      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 パラメーターに基づいてプリフェッチされたメッセージには、複数のテーブルのデータが含まれている可能性があります。したがって、単一のテーブルに対してプリフェッチされるレコードの数は特定できません。プリフェッチとスキーマの初期化は、メッセージが消費され処理される前に、各パーティションに対して一度だけ実行されます。新しいテーブルのデータが後で出現した場合、そのテーブルの最初のレコードから解析されたスキーマが初期スキーマとして使用され、スキーマは再度プリフェッチされたり初期化されたりしません。

重要

単一テーブルのデータが複数のパーティションに分散されるのは、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.decode.parser-table-id.fields パラメーターを使用して、この情報を含むフィールドを指定できます。これらのフィールドは、データベース名とテーブル名にマッピングされます。以下は設定例です:

      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 で埋められます。

    • 列の型の変更:

      • 列の型変更をサポートする下流シンクの場合、Flink CDC ジョブは、下流シンクがそれらを処理するように設定されていれば、型変更 (例:INT から BIGINT へ) を処理できます。この機能は、特定のシンクがサポートする列型変更ルールに依存します。サポートされているルールについては、お使いのシンクのドキュメントをご参照ください。

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

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

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

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

  • 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 ソース
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # ダーティデータ耐性を有効化
  ingestion.ignore-errors: true
  # 最大 1000 件のダーティデータレコードを許容
  ingestion.error-tolerance.max-count: 1000

この設定により、ジョブは 1,000 件までのダーティデータレコードであれば、実行を継続します。カウントがしきい値を超えるとジョブは失敗するため、データを調査できます。

ダーティデータが原因でジョブが失敗しないようにするには、次の設定を使用します。

source:
  type: kafka
  name: Kafka ソース
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # ダーティデータ耐性を有効化
  ingestion.ignore-errors: true
  # すべてのダーティデータレコードを許容
  ingestion.error-tolerance.max-count: -1

ダーティデータ耐性によりジョブは実行を継続できますが、問題のあるレコードを検査したい場合もあるでしょう。また、Kafka プロデューサーを改善するためにダーティデータを分析することも考えられます。「ダーティデータ収集」で説明されているように、TaskManager のログでジョブのダーティデータを確認できます。例:

source:
  type: kafka
  name: Kafka ソース
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # ダーティデータ耐性を有効化
  ingestion.ignore-errors: true
  # すべてのダーティデータレコードを許容
  ingestion.error-tolerance.max-count: -1

pipeline:
  dirty-data.collector:
    # ダーティデータを TaskManager ログファイルに書き込む
    type: logger

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

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

MySQL データベースの 2 つのテーブル mydb.mytable1mydb.mytable2 を同期する必要があるとします。使用可能なマッピング戦略は次のとおりです:

1. マッピング戦略なし

マッピング戦略を使用しない場合、各テーブルのデータは <Database Name>.<Table Name> 形式の名前のトピックに書き込まれます。そのため、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. ルート ルールによるマッピング (非推奨)

デフォルトの <Database Name>.<Table Name> 形式ではなく、特定のトピックにデータを書き込みたい場合があります。これを行うには、ルート ルールを設定します。設定例を次に示します:

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 という名前の 1 つのトピックに書き込まれます。

ただし、宛先トピックを変更するルート ルールは、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:
  type: kafka
  name: Kafka Sink
  properties.bootstrap.servers: ${kafka.bootstraps.server}
  sink.tableId-to-topic.mapping: mydb.mytable1,mydb.mytable2:mytable

または、次の設定を使用できます:

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}
  sink.tableId-to-topic.mapping: mydb.mytable1:mytable;mydb.mytable2:mytable

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

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 シンクは transaction.timeout.ms パラメーターを 1 時間に設定します。

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

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

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

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

  • 並列度のスケールダウン制約

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

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

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

    例:

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

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

    • トランザクション 1 が未完了のままである限り、コミット済みのトランザクション 2 のデータはコンシューマーから不可視です。

    これには次の影響があります:

    • 通常運用時、データの可視性レイテンシーはチェックポイント間隔とほぼ同じです。

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

よくある質問