Realtime Compute for Apache Flink では、 Kafka コネクタをソース、シンク、または Flink CDC デスティネーションとして使用します。
概要
Apache Kafka は、高性能なデータ処理、ストリーミング分析、データ統合に広く使用されている、オープンソースの分散イベントストリーミングプラットフォームです。Realtime Compute for Apache Flink 用の Kafka コネクタは、オープンソースの Apache Kafka クライアントを使用し、高性能なデータスループットと exactly-once セマンティクスを提供するとともに、複数のデータフォーマットの読み書きをサポートします。
|
カテゴリ |
説明 |
|
サポートタイプ |
SQL ソース、シンク Flink CDC ソース、シンク DataStream ソース、シンク |
|
実行モード |
ストリーミング |
|
データフォーマット |
|
|
メトリクス |
|
|
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 クライアントは、次のようにブローカーに接続します。
-
クライアントは、
bootstrap.serversで指定されたアドレスを使用して、Kafka クラスターへの初期接続を確立します。 -
Kafka クラスターは、各ブローカーのエンドポイントを含むメタデータを返します。
-
その後、クライアントはこれらのエンドポイントを使用してブローカーに接続し、データを読み書きします。
bootstrap.servers のアドレスが到達可能であっても、Kafka が不正なブローカーエンドポイントを返した場合、クライアントはデータを読み書きできません。この問題は、プロキシ、ポートフォワーディング、または専用線を使用するネットワークアーキテクチャでよく発生します。
トラブルシューティングの手順
ApsaraMQ for Kafka
-
エンドポイントタイプの確認
-
デフォルトエンドポイント (内部ネットワーク)
-
SASL エンドポイント (認証付き内部ネットワーク)
-
パブリックエンドポイント (別途申請が必要)
Realtime Compute for Apache Flink 開発コンソールの ネットワークプローブ 機能を使用して、
bootstrap.serversアドレスとの接続性の問題を切り分けます。 -
-
セキュリティグループとホワイトリストの確認
Realtime Compute for Apache Flink ワークスペースの CIDR ブロックを Kafka インスタンスのホワイトリストに追加してください。詳細については、「VPC CIDR ブロックの表示」および「ホワイトリストの設定」をご参照ください。
-
SASL 設定の確認 (有効な場合)
SASL_SSL エンドポイントを使用する場合、JAAS、SSL、および SASL メカニズムが Realtime Compute for Apache Flink のジョブで正しく設定されていることを確認してください。認証情報が不足していると、ハンドシェイクフェーズで接続が失敗する可能性があり、これもタイムアウトとして表示されることがあります。詳細については、「セキュリティと認証」をご参照ください。
セルフマネージド Kafka
-
ネットワークプローブ 機能の使用
この機能は、
bootstrap.serversアドレスとの接続性の問題を切り分け、正しい内部またはパブリックエンドポイントが使用されていることを確認するのに役立ちます。 -
セキュリティグループとホワイトリストの確認
-
Elastic Compute Service (ECS) インスタンスのセキュリティグループは、通常 9092 または 9093 である Kafka エンドポイントポートでのインバウンドトラフィックを許可する必要があります。
-
ECS インスタンス上のファイアウォールが、Realtime Compute for Apache Flink ワークスペースの VPC からのトラフィックを許可していることを確認してください。詳細については、「VPC CIDR ブロックの表示」をご参照ください。
-
-
設定の確認
-
zkCli.sh または zookeeper-shell.sh ツールを使用して、Kafka が使用する ZooKeeper クラスターにログインしてください。
-
コマンドを実行してブローカーのメタデータを取得してください。たとえば、
get /brokers/ids/0を実行します。レスポンスの endpoints フィールドで、Kafka がクライアントにアドバタイズするアドレスを見つけてください。
-
Realtime Compute for Apache Flink 開発コンソールの ネットワークプローブ 機能を使用して、このアドレスがアクセス可能かどうかをテストしてください。
説明-
アドレスにアクセスできない場合は、Kafka の管理者に問い合わせて、
listenersおよびadvertised.listenersの設定を確認し、アドバタイズされたアドレスが Realtime Compute for Apache Flink からアクセス可能であることを確認するように依頼してください。 -
Kafka クライアント接続の詳細については、「接続性のトラブルシューティング」をご参照ください。
-
-
-
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 |
メッセージタイムスタンプタイプ。有効な値は次のとおりです:
|
ソーステーブル |
|
__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-includeをEXCEPT_KEYに設定する必要があります。value.format
Kafka メッセージの値のシリアライズ/デシリアライズに使用するフォーマット。
文字列
いいえ
–
この設定は
formatと同等です。formatとvalue.formatのいずれか一方のみを設定できます。両方を設定した場合、value.formatがformatを上書きします。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.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.modeがspecific-offsetsの場合に、パーティションごとに指定する開始オフセットです。文字列
不要
–
例:
partition:0,offset:42;partition:1,offset:300scan.startup.timestamp-millis
scan.startup.modeがtimestampに設定されている場合に指定する、ミリ秒単位の開始タイムスタンプです。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-guaranteeがexactly-onceの場合に必須です。文字列
はい、
sink.delivery-guaranteeがexactly-onceの場合です。–
sink.delivery-guarantee が
exactly-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.locationとproperties.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は、KafkaConsumerRecordを解析する方法を定義します。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.commitとauto.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.serversparameter 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.modeにspecific-offsetsを設定した場合のパーティションごとの開始オフセット。いいえ
文字列
–
例:
partition:0,offset:42;partition:1,offset:300scan.startup.timestamp-millis
scan.startup.modeにtimestampを設定した場合のミリ秒単位の開始タイムスタンプ。いいえ
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
ダウンストリームのシンクに渡すメタデータ列。
いいえ
文字列
–
利用可能なメタデータ列には、
topic、partition、offset、timestamp、timestamp-type、headers、および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-errorsがtrueに設定されている場合のみ有効です。いいえ
整数
-1
このパラメータは、
ingestion.ignore-errorsがtrueに設定されている場合にのみ適用されます。値 -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.strategyがMYSQL_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 つのスキーマ初期化戦略があります:
-
完全自動のスキーマ推論
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 に設定する必要があります。
-
初期テーブルスキーマの指定
場合によっては、初期テーブルスキーマを明示的に定義する必要があります。たとえば、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 列の初期型を BIGINT、name 列を VARCHAR(10) と指定し、db1.t2 テーブルの id 列の初期型を BIGINT と指定します。
DDL ステートメントは Flink SQL 構文を使用します。
-
特定フィールドの固定型設定
特定のフィールドを特定のデータ型に固定したい場合があります。たとえば、通常は 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で埋められます。列削除イベントは生成されません。 -
同じ名前の列は次のように処理されます:
-
列のデータ型は同じで精度が異なる場合、より大きな精度の型が使用され、列型変更イベントが生成されます。
-
列のデータ型が異なる場合、システムは以下の型階層ツリーから最小の共通親型を見つけます。システムは、その共通親型を列に使用し、列型変更イベントを生成します。

-
-
サポートされているスキーマ進化ポリシー:
-
列の追加:コネクタは新しい列をスキーマの末尾に追加し、そのデータを同期します。新しい列は null 許容に設定されます。
-
列の削除:列削除イベントは生成されません。代わりに、その列の後続のデータは
NULLで埋められます。 -
列名の変更:コネクタはこれを古い列の削除と新しい列の追加として扱います。新しい列はスキーマの末尾に追加され、元の列の値は
NULLで埋められます。 -
列の型の変更:
-
列の型変更をサポートする下流シンクの場合、Flink CDC ジョブは、下流シンクがそれらを処理するように設定されていれば、型変更 (例:
INTからBIGINTへ) を処理できます。この機能は、特定のシンクがサポートする列型変更ルールに依存します。サポートされているルールについては、お使いのシンクのドキュメントをご参照ください。 -
Hologres のように列の型変更をサポートしない下流シンクの場合、型拡張を使用できます。この機能は、ジョブの開始時に下流シンクに、より広いデータ型を持つテーブルを作成します。列の型が変更された場合、新しい型が下流シンクで定義されたより広い型の範囲内であれば、システムはその変更を許容できます。
-
-
-
サポートされていないスキーマ変更:
-
プライマリキーやインデックスなどの制約の変更。
-
列を
NULLABLEからNOT NULLに変更すること。
-
-
Canal JSON スキーマ解析
Canal JSON データには、データ列の正確な型情報を記録するオプションの
sqlTypeフィールドが含まれている場合があります。より正確なスキーマを取得するには、canal-json.infer-schema.strategy をSQL_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.mytable1 と mydb.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.mytable1 と mydb.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.mytable1 と mydb.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 のデータはコンシューマーから不可視です。
これには次の影響があります:
-
通常運用時、データの可視性レイテンシーはチェックポイント間隔とほぼ同じです。
-
ジョブが失敗した場合、そのジョブが書き込んでいたトピックは、ジョブが再起動するかトランザクションがタイムアウトするまで、コンシューマーに対してブロックされます。極端な場合、トランザクションのタイムアウト処理自体が読み取り処理に影響することもあります。
-