Realtime Compute for Apache Flink で、Kafka コネクタをソース、シンク、または Flink CDC の送信先として使用します。
概要
Apache Kafka は、高性能なデータ処理、ストリーミング分析、データ統合に広く使用されているオープンソースの分散イベントストリーミングプラットフォームです。Realtime Compute for Apache Flink の Kafka コネクタは、オープンソースの Apache Kafka クライアントを使用して、高性能なデータスループットを提供し、複数のデータ形式の読み書きをサポートし、1 回限りのセマンティクスを提供します。
|
カテゴリ |
説明 |
|
サポートされるタイプ |
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 結果テーブルによって提供される 1 回限りのセマンティクスを使用できません。Ververica Runtime (VVR) 8.0.0 以降、Kafka コネクタは Kafka クライアント 3.x を使用しており、
properties.enable.idempotenceプロパティはデフォルトでtrueになります。したがって、Ververica Runtime (VVR) 8.0.0 以降を使用して ApsaraMQ for Kafka に書き込む際の書き込みの失敗を防ぐには、構成properties.enable.idempotence=falseを結果テーブルの定義に追加する必要があります。ApsaraMQ for Kafka のストレージエンジンと機能制限の比較については、「ストレージエンジン間の比較」をご参照ください。
-
-
セルフマネージド Apache Kafka クラスターへの接続
-
セルフマネージド Apache Kafka クラスターのバージョンが 0.11 以降であること。
-
Flink ワークスペースがセルフマネージド Apache Kafka クラスターへのネットワーク接続を持っていること。パブリックインターネット経由でクラスターに接続する方法の詳細については、「ネットワーク接続に関するよくある質問」をご参照ください。
-
Apache Kafka バージョン 2.8 のクライアント構成オプションのみがサポートされています。詳細については、Apache Kafka のコンシューマー設定およびプロデューサー設定のドキュメントをご参照ください。
-
注意事項
Apache Flink および Apache Kafka の既知の設計上の制限のため、トランザクション書き込みは推奨されません。sink.delivery-guarantee = 'exactly-once' を設定すると、Kafka コネクタはトランザクション書き込みを有効にしますが、次のような既知の問題があります。
-
各チェックポイントは新しいトランザクション ID を生成します。チェックポイントの間隔が短すぎると、トランザクション ID が大量に発生し、Kafka クラスターのコーディネーターがメモリ不足になり、クラスターの安定性が損なわれる可能性があります。
-
各トランザクションは新しいプロデューサーインスタンスを作成します。あまりにも多くのトランザクションが同時にコミットされると、TaskManager がメモリ不足になり、Apache Flink ジョブが不安定になる可能性があります。
-
複数の Apache Flink ジョブが同じ
sink.transactional-id-prefixを使用すると、生成されたトランザクション ID が競合する可能性があります。1つのジョブで書き込み操作が失敗すると、Apache Kafka パーティションのログ開始オフセット (LSO) が進まなくなる可能性があります。これは、そのパーティションのすべてのコンシューマーに影響します。
1 回限りのセマンティクスが必要な場合は、Upsert Kafka コネクタを使用してプライマリキーテーブルに書き込み、べき等性を確保します。トランザクション書き込みを使用する必要がある場合は、「1 回限りのセマンティクスの使用上の注意」をご参照ください。
ネットワーク接続のトラブルシューティング
Realtime Compute for Apache Flink ジョブが起動に失敗したときの Timed out waiting for a node assignment エラーは、通常、Realtime Compute for Apache Flink と Kafka クラスター間のネットワーク接続の問題を示します。
Kafka クライアントは次のようにブローカーに接続します:
-
クライアントは、
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 エンドポイントを使用する場合、Realtime Compute for Apache Flink ジョブで JAAS、SSL、および SASL メカニズムが正しく設定されていることを確認してください。適切な認証がないと、ハンドシェイクフェーズで接続が失敗し、タイムアウトとして表示されることもあります。詳細については、「セキュリティと認証」をご参照ください。
セルフマネージド Kafka
-
ネットワークプローブ機能の使用
この機能は、
bootstrap.serversアドレスとの接続性の問題を切り分け、適切な内部またはパブリックエンドポイントが使用されていることを確認するのに役立ちます。 -
セキュリティグループとホワイトリストの確認
-
Elastic Compute Service (ECS) インスタンスのセキュリティグループは、Kafka エンドポイントポート (通常は 9092 または 9093) でのインバウンドトラフィックを許可する必要があります。
-
ECS インスタンス上のファイアウォールが、ご利用の Realtime Compute for Apache Flink ワークスペースの VPC からのトラフィックを許可していることを確認してください。詳細については、「VPC CIDR ブロックの表示」をご参照ください。
-
-
設定の確認
-
zkCli.sh または zookeeper-shell.sh ツールを使用して、Kafka が使用する ZooKeeper クラスターにログインします。
-
ブローカーのメタデータを取得するコマンド (例:
get /brokers/ids/0) を実行します。 応答の endpoints フィールドで、Kafka がクライアントに公開するアドレスを見つけます。# bin/zookeeper-shell.sh localhost:2181 Connecting to localhost:2181 Welcome to ZooKeeper! JLine support is disabled WATCHER:: WatchedEvent state:SyncConnected type:None path:null get /brokers/ids/0 {"listener_security_protocol_map":{"PLAINTEXT":"PLAINTEXT"},"endpoints":["PLAINTEXT://116.62.xxx:9092"],"jmx_port":-1,"host":"116.62.xxx","timestamp":"1614840078030","port":9092,"version":4} -
Realtime Compute for Apache Flink 開発コンソールのネットワークプローブ機能を使用して、このアドレスにアクセスできるかどうかをテストします。
説明-
アドレスにアクセスできない場合は、Kafka 管理者に連絡し、
listenersおよびadvertised.listenersの構成を確認および修正して、公開されたアドレスが Realtime Compute for Apache Flink からアクセスできるようにしてください。 -
Kafka クライアント接続の詳細については、「接続のトラブルシューティング」をご参照ください。
-
-
-
SASL 設定の確認 (有効な場合)
SASL_SSL エンドポイントを使用する場合、Realtime Compute for Apache Flink ジョブで JAAS、SSL、および SASL メカニズムが正しく設定されていることを確認してください。適切な認証がないと、ハンドシェイクフェーズで接続が失敗し、タイムアウトとして表示されることもあります。詳細については、「セキュリティと認証」をご参照ください。
SQL
SQL ジョブで Kafka コネクタをソーステーブルまたは結果テーブルとして使用します。
構文
CREATE TABLE KafkaTable (
`user_id` BIGINT,
`item_id` BIGINT,
`behavior` STRING,
`ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL
) WITH (
'connector' = 'kafka',
'topic' = 'user_behavior',
'properties.bootstrap.servers' = 'localhost:9092',
'properties.group.id' = 'testGroup',
'scan.startup.mode' = 'earliest-offset',
'format' = 'csv'
)
メタデータ列
ソーステーブルまたは結果テーブルにメタデータ列を定義して、Kafka メッセージのメタデータにアクセスします。たとえば、複数のトピックをサブスクライブする場合、メタデータ列を使用して各レコードがどのトピックから来たかを識別できます。
CREATE TABLE kafka_source (
-- メッセージトピックを `record_topic` 列として読み取る
`record_topic` STRING NOT NULL METADATA FROM 'topic' VIRTUAL,
-- ConsumerRecord からタイムスタンプを `ts` 列として読み取る
`ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
-- メッセージオフセットを `record_offset` 列として読み取る
`record_offset` BIGINT NOT NULL METADATA FROM 'offset' VIRTUAL,
...
) WITH (
'connector' = 'kafka',
...
);
CREATE TABLE kafka_sink (
-- `ts` 列のタイムスタンプを ProducerRecord のタイムスタンプとして Kafka に書き込む
`ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
...
) WITH (
'connector' = 'kafka',
...
);
次の表に、Kafka ソーステーブルと結果テーブルがサポートするメタデータ列を示します。
|
キー |
型 |
説明 |
範囲 |
|
topic |
STRING NOT NULL METADATA VIRTUAL |
メッセージトピック。 |
ソーステーブル |
|
partition |
INT NOT NULL METADATA VIRTUAL |
メッセージパーティション ID。 |
ソーステーブル |
|
headers |
MAP<STRING, BYTES> NOT NULL METADATA VIRTUAL |
メッセージヘッダー。 |
ソーステーブルと結果テーブル |
|
leader-epoch |
INT NOT NULL METADATA VIRTUAL |
メッセージの leader-epoch。 |
ソーステーブル |
|
offset |
BIGINT NOT NULL METADATA VIRTUAL |
メッセージオフセット。 |
ソーステーブル |
|
timestamp |
TIMESTAMP(3) WITH LOCAL TIME ZONE NOT NULL METADATA VIRTUAL |
メッセージタイムスタンプ。 |
ソーステーブルと結果テーブル |
|
timestamp-type |
STRING NOT NULL METADATA VIRTUAL |
メッセージタイムスタンプのタイプ。有効な値は次のとおりです:
|
ソーステーブル |
|
__raw_key__ |
STRING NOT NULL METADATA VIRTUAL |
生のメッセージキー。 |
ソーステーブルと結果テーブル 説明
このパラメーターは、Ververica Runtime (VVR) 11.4 以降でのみサポートされます。 |
|
__raw_value__ |
STRING NOT NULL METADATA VIRTUAL |
生のメッセージ値。 |
ソーステーブルと結果テーブル 説明
このパラメーターは、Ververica Runtime (VVR) 11.4 以降でのみサポートされます。 |
コネクタオプション
-
一般
オプション
説明
型
必須
デフォルト
備考
connector
コネクタのタイプ。
String
はい
–
値は
kafkaである必要があります。properties.bootstrap.servers
Kafka ブローカーアドレスのリスト。
String
はい
–
フォーマット:
host1:port1,host2:port2,...。アドレスはカンマ (,) で区切ります。properties.*
Kafka クライアントの追加プロパティ。
String
いいえ
–
プロパティキーは、公式の Apache Kafka ドキュメントのプロデューサー設定およびコンシューマー設定で定義されている有効なオプションである必要があります。
Realtime Compute for Apache Flink は properties. プレフィックスを削除し、残りのキーと値のペアを基盤となる Kafka クライアントに渡します。たとえば、
'properties.allow.auto.create.topics' = 'false'を設定して、自動的なトピック作成を無効にできます。Kafka コネクタはこれらのオプションを上書きするため、この方法で設定することはできません:
-
key.deserializer
-
value.deserializer
format
Kafka メッセージの値のシリアル化および逆シリアル化のためのフォーマット。
String
いいえ
–
サポートされているフォーマット:
-
csv
-
json
-
avro
-
debezium-json
-
canal-json
-
maxwell-json
-
avro-confluent
-
raw
説明詳細については、「フォーマットオプション」をご参照ください。
key.format
Kafka メッセージのキーのシリアル化および逆シリアル化のためのフォーマット。
String
いいえ
–
サポートされているフォーマット:
-
csv
-
json
-
avro
-
debezium-json
-
canal-json
-
maxwell-json
-
avro-confluent
-
raw
説明この構成を使用する場合、key.options が必須です。
key.fields
Kafka メッセージキーとして使用するテーブルスキーマのフィールド。
String
いいえ
–
複数のフィールド名はセミコロン (;) で区切ります。例:
'field1;field2'。key.fields-prefix
値フィールドとの名前の競合を防ぐための、すべてのキーフィールドのカスタムプレフィックス。
String
いいえ
–
このプレフィックスは、キーフィールドと値フィールドを区別するために使用されます。キーをシリアル化する前、または逆シリアル化した後に削除されます。
説明このオプションを使用する場合、
value.fields-includeはEXCEPT_KEYに設定する必要があります。value.format
Kafka メッセージの値のシリアル化および逆シリアル化のためのフォーマット。
String
いいえ
–
この構成は
formatと同等です。formatまたはvalue.formatのいずれか 1 つのみを設定できます。両方が設定されている場合、value.formatがformatをオーバーライドします。value.fields-include
キーフィールドが値フォーマットに含まれるかどうかを定義します。
String
いいえ
ALL
有効な値:
-
ALL: Kafka メッセージの値に、テーブルのすべての列が含まれます。 -
EXCEPT_KEY:Kafka メッセージの値には、key.fieldsで定義されたものを除くすべてのテーブル列が含まれます。
-
-
ソーステーブル
オプション
説明
型
必須
デフォルト
備考
topic
読み取るトピック。
String
いいえ
–
複数のトピックをサブスクライブするには、トピック名をセミコロン (;) で区切ります。例:
'topic-1;topic-2'。説明このオプションまたは
topic-patternのいずれかを指定できますが、両方を指定することはできません。topic-pattern
サブスクライブするトピックに一致する正規表現。コンシューマーは、このパターンに一致する名前のすべてのトピックをサブスクライブします。
String
いいえ
–
例:
-
user_event_.*: プレフィックスuser_event_を持つすべてのトピックに一致します。 -
prod\.logs\..*:prod.logs.で始まるトピックに一致します(.文字はエスケープする必要があります)。
説明このオプションまたは
トピックのいずれかを指定できますが、両方を指定することはできません。properties.group.id
Kafka ソースコンシューマーグループ ID。
String
いいえ
KafkaSource-{Source-Table-Name}
初めてコンシューマーグループ ID を使用する場合は、properties.auto.offset.reset を
earliestまたはlatestのいずれかに設定して、初期起動オフセットを定義する必要もあります。scan.startup.mode
Kafka コンシューマーの開始オフセット。
String
いいえ
group-offsets
有効な値:
-
earliest-offset: 利用可能な最も早いオフセットから読み取りを開始します。 -
latest-offset: 最大オフセットから読み取りを開始します。 -
group-offsets: 指定された properties.group.id のコミットされたオフセットから読み取りを開始します。 -
タイムスタンプ: 指定された scan.startup.timestamp-millis から読み取りを開始します。 -
specific-offsets: scan.startup.specific-offsets で指定されたオフセットから読み取りを開始します。
説明このオプションは、ジョブがステートなしで開始される場合にのみ適用されます。ジョブがチェックポイントから再開される場合、チェックポイントステートに保存されているオフセットから読み取ります。
scan.startup.specific-offsets
scan.startup.modeがspecific-offsetsの場合のパーティションごとの開始オフセット。String
いいえ
–
例:
partition:0,offset:42;partition:1,offset:300scan.startup.timestamp-millis
scan.startup.modeがtimestampに設定されている場合のミリ秒単位の開始タイムスタンプ。Long
いいえ
–
単位はミリ秒です。
scan.topic-partition-discovery.interval
パーティション検出間隔。
Duration
いいえ
5 分
コネクタは定期的に新しいパーティションを検出し、そこから読み取ります。topic-pattern を使用する場合、コネクタはパターンに一致する新しいトピックも検出します。この機能を無効にするには、間隔を非正の値に設定します。
説明Ververica Runtime (VVR) 6.0.x では、動的パーティション検出はデフォルトで無効になっています。VVR 8.0 以降、この機能はデフォルトで有効になり、検出間隔は 5 分です。
scan.header-filter
Kafka メッセージヘッダーに基づいてメッセージをフィルタリングします。
String
いいえ
–
ヘッダーキーとその値はコロン (:) で区切られます。複数のヘッダー条件は、論理演算子 (& および |) を使用して接続されます。NOT 論理演算子 (!) もサポートされています。たとえば、ヘッダーに
depart=toyまたはdepart=bookが含まれ、かつenv=testが含まれていない場合、depart:toy|depart:book&!env:testは Kafka データを保持します。説明-
このオプションは、Ververica Runtime (VVR) 8.0.6 以降でのみサポートされます。
-
式中の括弧はサポートされていません。
-
論理演算は左から右に評価されます。
-
ヘッダー値は比較のために UTF-8 文字列に変換されます。
scan.check.duplicated.group.id
他のアクティブなコンシューマーが
properties.group.idをすでに使用しているかどうかを確認します。Boolean
いいえ
false
有効な値:
-
true:ジョブを開始する前に、重複するコンシューマーグループをチェックします。見つかった場合、競合を防ぐためにジョブは失敗します。
-
false:競合をチェックせずにジョブを開始します。
説明このオプションは、Ververica Runtime (VVR) 6.0.4 以降でのみサポートされます。
-
-
シンクテーブル
オプション
説明
型
必須
デフォルト
備考
topic
ターゲットトピック。
String
はい
–
–
sink.partitioner
並列シンクインスタンスからのレコードを Kafka パーティションにマッピングします。
String
いいえ
default
有効な値:
-
default: デフォルトの Kafka partitioner を使用します。 -
fixed: 各並列 sink インスタンスは、固定の Kafka パーティションに書き込みます。 -
round-robin: レコードはラウンドロビン方式でパーティションに分散されます。 -
カスタム partitioner: カスタム partitioner を使用するには、
FlinkKafkaPartitionerサブクラスの完全修飾クラス名を指定します。たとえば、org.mycompany.MyPartitionerなどです。
sink.delivery-guarantee
シンクの配信保証。
String
いいえ
at-least-once
有効な値:
-
none:保証はありません。レコードが失われたり、重複したりする可能性があります。 -
at-least-once: レコードが失われないことを保証しますが、重複する可能性があります。 -
exactly-once: Kafka トランザクションを使用して 1 回限りのセマンティクスを提供し、レコードが失われたり重複したりしないことを保証します。
説明exactly-onceセマンティクスを使用する場合、sink.transactional-id-prefix も指定する必要があります。sink.transactional-id-prefix
トランザクション ID プレフィックス。
sink.delivery-guaranteeがexactly-onceの場合に必須です。String
はい、
sink.delivery-guaranteeがexactly-onceの場合です。–
sink.delivery-guarantee が
exactly-onceにセットされている場合にのみ必須です。sink.parallelism
シンク演算子の並列度。
Integer
いいえ
–
デフォルトでは、フレームワークは上流の演算子に基づいて並列度を決定します。
-
セキュリティと認証
Kafka クラスターが安全な接続または認証を必要とする場合、関連するセキュリティおよび認証構成の前に properties. を付け、WITH パラメーターで設定します。次の例では、Kafka テーブルを PLAIN を SASL メカニズムとして使用し、JAAS 構成で設定します。
CREATE TABLE KafkaTable (
`user_id` BIGINT,
`item_id` BIGINT,
`behavior` STRING,
`ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp'
) WITH (
'connector' = 'kafka',
...
'properties.security.protocol' = 'SASL_PLAINTEXT',
'properties.sasl.mechanism' = 'PLAIN',
'properties.sasl.jaas.config' = 'org.apache.flink.kafka.shaded.org.apache.kafka.common.security.plain.PlainLoginModule required username="username" password="password";'
)
次の例は、セキュリティプロトコルとして SASL_SSL を、SASL メカニズムとして SCRAM-SHA-256 を使用する方法を示しています。
CREATE TABLE KafkaTable (
`user_id` BIGINT,
`item_id` BIGINT,
`behavior` STRING,
`ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp'
) WITH (
'connector' = 'kafka',
...
'properties.security.protocol' = 'SASL_SSL',
/* SSL 構成 */
/* サーバーの CA 証明書のトラストストアへのパス。 */
/* アーティファクトを使用してアップロードされたファイルは /flink/usrlib/ ディレクトリに保存されます。 */
'properties.ssl.truststore.location' = '/flink/usrlib/kafka.client.truststore.jks',
'properties.ssl.truststore.password' = 'test1234',
/* クライアント認証が必要な場合は、キーストア (秘密鍵) へのパスも構成する必要があります。 */
'properties.ssl.keystore.location' = '/flink/usrlib/kafka.client.keystore.jks',
'properties.ssl.keystore.password' = 'test1234',
/* サーバーのホスト名を検証するために使用されるアルゴリズム。空の文字列はホスト名の検証を無効にします。 */
'properties.ssl.endpoint.identification.algorithm' = '',
/* SASL 構成 */
/* SASL メカニズムを SCRAM-SHA-256 に設定します。 */
'properties.sasl.mechanism' = 'SCRAM-SHA-256',
/* JAAS を構成します。 */
'properties.sasl.jaas.config' = 'org.apache.flink.kafka.shaded.org.apache.kafka.common.security.scram.ScramLoginModule required username="username" password="password";'
)
Realtime Compute for Apache Flink コンソールの [アーティファクト] 機能を使用して、例で説明されている CA 証明書と秘密鍵をアップロードできます。 アップロードされたファイルは /flink/usrlib ディレクトリに保存されます。 my-truststore.jks という名前の CA 証明書ファイルを使用するには、WITH 句で 'properties.ssl.truststore.location' プロパティを次の 2 つの方法のいずれかで設定できます。
-
'properties.ssl.truststore.location' = '/flink/usrlib/my-truststore.jks'を設定します。この方法は、ランタイム時に Object Storage Service (OSS) からファイルを動的にダウンロードすることを回避しますが、デバッグモードをサポートしません。 -
リアルタイムコンピューティングエンジンのバージョンが VVR 11.5 以降の場合、
properties.ssl.truststore.locationとproperties.ssl.keystore.locationを絶対 OSS パスに設定できます。ファイルパス形式は oss://flink-fullymanaged-<Workspace ID>/artifacts/namespaces/<Namespace name>/<file name> です。この方法では、Flink ランタイム時に OSS ファイルを動的にダウンロードし、デバッグモードをサポートします。
-
構成の確認:このトピックの例は一般的な構成を示しています。Kafka コネクタを構成する前に、Kafka の O&M チームに連絡して、正しいセキュリティおよび認証設定を入手してください。
-
エスケープ: ネイティブ Apache Flink とは異なり、Realtime Compute for Apache Flink SQL エディターでは、デフォルトでダブルクォーテーションマーク (") がエスケープされます。したがって、
properties.sasl.jaas.configオプションでユーザー名とパスワードに使用されるダブルクォーテーションマークをエスケープするために、バックスラッシュ (\) を追加する必要はありません。
ソーステーブルの開始オフセット
起動モード
scan.startup.mode オプションを構成して、Kafka ソーステーブルがデータの読み取りを開始するオフセットを指定できます。有効な値は次のとおりです:
-
earliest-offset:最も古いオフセットから読み取りを開始します。
-
latest-offset:最新のオフセットから読み取りを開始します。
-
group-offsets:properties.group.id で指定されたコンシューマーグループのコミット済みオフセットから読み取りを開始します。
-
timestamp:scan.startup.timestamp-millis で指定された値以上のタイムスタンプを持つ最初のメッセージから読み取りを開始します。
-
specific-offsets:scan.startup.specific-offsets で指定された特定のパーティションオフセットから読み取りを開始します。
-
起動モードを指定しない場合、デフォルトは 'group-offsets' です。
-
scan.startup.mode オプションは、ステートレスジョブにのみ適用されます。ステートフルジョブが開始されると、常にそのステートに保存されているオフセットから消費します。
例:
CREATE TEMPORARY TABLE kafka_source (
...
) WITH (
'connector' = 'kafka',
...
-- 最も古いオフセットから消費する。
'scan.startup.mode' = 'earliest-offset',
-- 最新のオフセットから消費する。
'scan.startup.mode' = 'latest-offset',
-- コンシューマーグループ "my-group" のコミット済みオフセットから消費する。
'properties.group.id' = 'my-group',
'scan.startup.mode' = 'group-offsets',
'properties.auto.offset.reset' = 'earliest', -- "my-group" が初めて使用される場合、消費は最も古いオフセットから開始される。
'properties.auto.offset.reset' = 'latest', -- "my-group" が初めて使用される場合、消費は最新のオフセットから開始される。
-- 指定されたタイムスタンプ (ミリ秒) から消費する:1655395200000。
'scan.startup.mode' = 'timestamp',
'scan.startup.timestamp-millis' = '1655395200000',
-- 特定のオフセットから消費する。
'scan.startup.mode' = 'specific-offsets',
'scan.startup.specific-offsets' = 'partition:0,offset:42;partition:1,offset:300'
);
開始オフセットの優先度
ソーステーブルの開始オフセットは、優先度の高い順に次のルールによって決定されます:
|
優先度 (高い順) |
チェックポイントまたはセーブポイントに保存されているオフセット。 |
|
ジョブ起動時に Realtime Compute for Apache Flink コンソールで選択された開始時刻。 |
|
|
WITH 句の scan.startup.mode で指定された開始オフセット。 |
|
|
scan.startup.mode が指定されていない場合、group-offsets が使用され、対応するコンシューマーグループのオフセットから消費が開始されます。 |
これらのステップのいずれかで決定されたオフセットが無効な場合、たとえば、期限切れになったり、Kafka クラスターで問題が発生したりした場合、システムは properties.auto.offset.reset で指定されたポリシーに従ってオフセットをリセットします。このオプションが構成されていない場合、システムはユーザーの介入が必要な例外をスローします。
一般的なシナリオとして、新しいコンシューマーグループ ID で消費を開始する場合があります。ソーステーブルはまず、そのグループのコミット済みオフセットを Kafka クラスターにクエリします。グループ ID が新しいため、有効なオフセットは見つかりません。その結果、システムは properties.auto.offset.reset で指定されたポリシーに従ってオフセットをリセットします。したがって、新しいグループ ID で消費する場合は、properties.auto.offset.reset オプションを構成する必要があります。
ソースオフセットのコミット
Kafka ソーステーブルは、チェックポイントが成功した後にのみコンシューマーオフセットを Kafka クラスターにコミットするため、チェックポイントの間隔が長いとコミットされたオフセットが遅れます。ソーステーブルは、実際の読み取り進捗をチェックポイントステートに保存し、システムはこれを障害復旧に使用します。コミットされたオフセットは進捗モニターとしてのみ機能し、回復には使用されないため、コミットの失敗はデータの精度に影響しません。
カスタムシンクパーティショナー
Kafka の組み込みパーティショニング戦略が要件を満たさない場合は、FlinkKafkaPartitioner クラスを拡張してカスタムパーティショナーを実装できます。開発が完了したら、コードを JAR パッケージにコンパイルし、Realtime Compute コンソールのアーティファクト機能を使用してアップロードします。JAR パッケージがアップロードされて参照された後、WITH 句の sink.partitioner パラメーターをパーティショナーの完全修飾クラス名 (例:org.mycompany.MyPartitioner) に設定します。
Kafka、Upsert Kafka、および Kafka JSON カタログ
Kafka は追加専用のイベントストリーミングプラットフォームであり、データの更新や削除をサポートしていません。ストリーミング SQL では、標準の Kafka 結果テーブルは、上流の Change Data Capture (CDC) データや、集計や結合などの演算子のリトラクションロジックを処理できません。変更やリトラクションを含むデータを書き込む必要がある場合は、Upsert Kafka 結果テーブルを使用します。
1 つまたは複数の上流データベーステーブルから Kafka への Change Data Capture (CDC) データのバッチ同期を簡素化するために、Kafka JSON カタログを使用できます。Kafka に保存されているデータが JSON 形式の場合、Kafka JSON カタログを使用すると、スキーマと WITH パラメーターを定義するステップをスキップできます。詳細については、「Kafka JSON カタログの管理」をご参照ください。
例
例 1:Kafka からの読み取りと Kafka への書き込み
この例では、ソース Kafka トピックからデータを読み取り、それをシンクトピックに書き込みます。データは CSV 形式です。
CREATE TEMPORARY TABLE kafka_source (
id INT,
name STRING,
age INT
) WITH (
'connector' = 'kafka',
'topic' = 'source',
'properties.bootstrap.servers' = '<yourKafkaBrokers>',
'properties.group.id' = '<yourKafkaConsumerGroupId>',
'format' = 'csv'
);
CREATE TEMPORARY TABLE kafka_sink (
id INT,
name STRING,
age INT
) WITH (
'connector' = 'kafka',
'topic' = 'sink',
'properties.bootstrap.servers' = '<yourKafkaBrokers>',
'properties.group.id' = '<yourKafkaConsumerGroupId>',
'format' = 'csv'
);
INSERT INTO kafka_sink SELECT id, name, age FROM kafka_source;
例 2:テーブルスキーマとデータの同期
Kafka コネクタを使用して、Kafka トピックから Hologres にメッセージをリアルタイムで同期できます。フェールオーバー中に Hologres でメッセージが重複するのを防ぐために、Kafka メッセージのオフセットとパーティション ID を複合プライマリキーとして使用できます。
CREATE TEMPORARY TABLE kafkaTable (
`offset` INT NOT NULL METADATA,
`part` BIGINT NOT NULL METADATA FROM 'partition',
PRIMARY KEY (`part`, `offset`) NOT ENFORCED
) WITH (
'connector' = 'kafka',
'properties.bootstrap.servers' = '<yourKafkaBrokers>',
'topic' = 'kafka_evolution_demo',
'scan.startup.mode' = 'earliest-offset',
'format' = 'json',
'json.infer-schema.flatten-nested-columns.enable' = 'true'
-- オプション。すべてのネストされた列をフラット化します。
);
CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka`
WITH (
'connector' = 'hologres'
) AS TABLE vvp.`default`.kafkaTable;
例 3:Kafka のキーと値の同期
Kafka メッセージキーに関連情報が含まれている場合は、キーと値の両方を同期できます。
CREATE TEMPORARY TABLE kafkaTable (
`key_id` INT NOT NULL,
`val_name` VARCHAR(200)
) WITH (
'connector' = 'kafka',
'properties.bootstrap.servers' = '<yourKafkaBrokers>',
'topic' = 'kafka_evolution_demo',
'scan.startup.mode' = 'earliest-offset',
'key.format' = 'json',
'value.format' = 'json',
'key.fields' = 'key_id',
'key.fields-prefix' = 'key_',
'value.fields-prefix' = 'val_',
'value.fields-include' = 'EXCEPT_KEY'
);
CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka`(
WITH (
'connector' = 'hologres'
) AS TABLE vvp.`default`.kafkaTable;
Kafka メッセージキーは、スキーマ進化や自動型解析をサポートしていません。スキーマを手動で宣言する必要があります。
例 4:データの同期と計算の実行
Kafka から Hologres にデータを同期する際に、軽量な変換が必要になる場合があります。
CREATE TEMPORARY TABLE kafkaTable (
`distinct_id` INT NOT NULL,
`properties` STRING,
`timestamp` TIMESTAMP_LTZ METADATA,
`date` AS CAST(`timestamp` AS DATE)
) WITH (
'connector' = 'kafka',
'properties.bootstrap.servers' = '<yourKafkaBrokers>',
'topic' = 'kafka_evolution_demo',
'scan.startup.mode' = 'earliest-offset',
'key.format' = 'json',
'value.format' = 'json',
'key.fields' = 'key_id',
'key.fields-prefix' = 'key_'
);
CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka` WITH (
'connector' = 'hologres'
) AS TABLE vvp.`default`.kafkaTable
ADD COLUMN
`order_id` AS COALESCE(JSON_VALUE(`properties`, '$.order_id'), 'default');
--COALESCE を使用して null 値を処理します。
例 5:ネストされた JSON の解析
以下は JSON メッセージのサンプルです:
{
"id": 101,
"name": "VVP",
"properties": {
"owner": "Alibaba Cloud",
"engine": "Flink"
}
}
JSON_VALUE(payload, '$.properties.owner') などの関数を使用してフィールドを解析するのではなく、ソース DDL で構造を直接定義できます:
CREATE TEMPORARY TABLE kafka_source (
id VARCHAR,
`name` VARCHAR,
properties ROW<`owner` STRING, engine STRING>
) WITH (
'connector' = 'kafka',
'topic' = 'xxx',
'properties.bootstrap.servers' = 'xxx',
'scan.startup.mode' = 'earliest-offset',
'format' = 'json'
);
このアプローチでは、Flink は読み取りフェーズ中に JSON を構造化されたフィールドに解析します。後続の SQL クエリは、追加の関数呼び出しなしで properties.owner を直接参照できるため、全体的なパフォーマンスが向上します。
DataStream API
DataStream API を使用してデータを読み書きするには、対応する DataStream コネクタを使用して Realtime Compute for Apache Flink に接続します。DataStream コネクタの設定方法の詳細については、「DataStream コネクタの統合」をご参照ください。
-
Kafka ソースの構築
Kafka Sourceは、Kafka Source インスタンスを作成するためのビルダー クラスを提供します。 次のサンプル コードは、
input-topicTopicの最も古いOffsetからデータを消費するKafka Sourceをビルドします。 コンシューマー グループはmy-groupで、Kafka メッセージの値は文字列として逆シリアル化されます。Java
KafkaSource<String> source = KafkaSource.<String>builder() .setBootstrapServers(brokers) .setTopics("input-topic") .setGroupId("my-group") .setStartingOffsets(OffsetsInitializer.earliest()) .setValueOnlyDeserializer(new SimpleStringSchema()) .build(); env.fromSource(source, WatermarkStrategy.noWatermarks(), "Kafka Source");Kafka ソースを構築するには、次のプロパティを指定する必要があります。
パラメーター
説明
BootstrapServers
Kafka ブローカーアドレスのリストです。このプロパティは、
setBootstrapServers(String)メソッドを呼び出して設定します。GroupId
[コンシューマーグループ] の ID です。このプロパティは、
setGroupId(String)メソッドを呼び出して設定します。トピックまたはパーティション
サブスクライブするトピックまたはパーティション。Kafka ソースは、トピックまたはパーティションをサブスクライブするための次の 3 つの方法をサポートしています:
-
リスト内のトピックのすべてのパーティションをサブスクライブします。
KafkaSource.builder().setTopics("topic-a","topic-b") -
トピックパターン:指定された正規表現に一致する名前のトピックのすべてのパーティションをサブスクライブします。
KafkaSource.builder().setTopicPattern("topic.*") -
パーティションのリスト。指定されたパーティションをサブスクライブできます。
final HashSet<TopicPartition> partitionSet = new HashSet<>(Arrays.asList( new TopicPartition("topic-a", 0), // トピック "topic-a" のパーティション 0 new TopicPartition("topic-b", 5))); // トピック "topic-b" のパーティション 5 KafkaSource.builder().setPartitions(partitionSet)
デシリアライザー
Kafka メッセージを解析するために使用されるデシリアライザー。
setDeserializer(KafkaRecordDeserializationSchema)メソッドを使用してデシリアライザーを指定します。KafkaRecordDeserializationSchemaは、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 コネクタは Maven Central リポジトリで入手できます。
<dependency> <groupId>com.alibaba.ververica</groupId> <artifactId>ververica-connector-kafka</artifactId> <version>${vvr-version}</version> </dependency>Kafka DataStream コネクタを使用する際は、次のプロパティを考慮してください:
-
開始オフセット
Kafka ソースは、オフセットイニシャライザ (
OffsetsInitializer) を使用して、その開始オフセットを指定します。組み込みのイニシャライザは次のとおりです。オフセット初期化子
コード
最も古いオフセットから消費を開始します。
KafkaSource.builder().setStartingOffsets(OffsetsInitializer.earliest())最新のオフセットから消費を開始します。
KafkaSource.builder().setStartingOffsets(OffsetsInitializer.latest())指定された時刻以上のタイムスタンプを持つデータの消費を開始します。単位はミリ秒です。
KafkaSource.builder().setStartingOffsets(OffsetsInitializer.timestamp(1592323200000L))コンシューマーグループのコミット済みオフセットから消費を開始します。コミット済みオフセットが存在しない場合は、指定されたリセット戦略 (例:最も古いオフセット) を使用します。
KafkaSource.builder().setStartingOffsets(OffsetsInitializer.committedOffsets(OffsetResetStrategy.EARLIEST))消費はコンシューマーグループによってコミットされたオフセットから開始され、オフセットリセットポリシーは指定されません。
KafkaSource.builder().setStartingOffsets(OffsetsInitializer.committedOffsets())説明-
組み込みの初期化子が要件を満たさない場合は、カスタムのオフセット初期化子を実装できます。
-
オフセットイニシャライザーを指定しない場合、デフォルトは
OffsetsInitializer.earliest()です。
-
-
ストリーミングモードとバッチモード
Kafka ソースは、ストリーミングモードとバッチモードの両方をサポートしています。デフォルトではストリーミングモードで動作し、ジョブは失敗するかキャンセルされるまで無期限に実行されます。Kafka ソースをバッチモードで実行するように設定するには、
setBounded(OffsetsInitializer)を使用して停止オフセットを指定できます。すべてのパーティションが指定された停止オフセットに達すると、Kafka ソースは終了します。説明ストリーミングモードの Kafka ソースには、通常、停止 Offset はありません。ただし、テスト目的で、
setUnbounded(OffsetsInitializer)を使用して、ストリーミングモードでも停止 Offset を指定できます。停止 Offset を指定するためのメソッド名が異なることに注意してください。ストリーミングモードの場合はsetUnbounded、バッチモードの場合はsetBoundedです。 -
動的パーティション検出
Flink ジョブを再起動せずにトピックのスケーリングや新しいトピックの作成を処理するために、パターンでトピックをサブスクライブする際に動的パーティション検出を有効にできます。この機能はデフォルトで無効になっており、明示的に有効にする必要があります:
KafkaSource.builder() .setProperty("partition.discovery.interval.ms", "10000") // 10 秒ごとに新しいパーティションを検出します。重要動的パーティション検出機能は、Kafka クラスターのメタデータ更新メカニズムに依存します。Kafka クラスターがパーティション情報をタイムリーに更新しない場合、新しいパーティションが検出されない可能性があります。Kafka クラスターの partition.discovery.interval.ms 構成が実際のシナリオと一致していることを確認してください。
-
イベント時間とウォーターマーク
デフォルトでは、Kafka ソースは Kafka メッセージのタイムスタンプをイベント時間として使用します。カスタムのウォーターマーク戦略を定義して、メッセージ本文からイベント時間を抽出し、下流にウォーターマークを送信できます。
env.fromSource(kafkaSource, new CustomWatermarkStrategy(), "Kafka Source With Custom Watermark Strategy")カスタムウォーターマーク戦略の詳細については、「ウォーターマークの生成」をご参照ください。
説明ソースサブタスクがアイドル状態の場合 (たとえば、Kafka パーティションに新しいデータがない場合や、ソースの並列度が Kafka パーティションの数より高い場合)、そのサブタスクのウォーターマークは進みません。これにより、下流のウィンドウ計算がブロックされる可能性があります。
この問題を解決するには、次のソリューションを検討してください:
-
ソースアイドルタイムアウトの構成:table.exec.source.idle-timeout プロパティを有効にして、アイドル状態のソースを一時的にアイドルとしてマークします。これにより、下流のウォーターマークが進むことができます。
-
適切な並列度の設定:ソースの並列度が Kafka パーティションの数を超えないようにします。
-
-
オフセットコミット
チェックポイントが有効な場合、Kafka ソースはチェックポイントが完了したときに現在のコンシューマーオフセットを Kafka にコミットします。これにより、Flink チェックポイントステートが Kafka ブローカー上のコミット済みオフセットと一致することが保証されます。チェックポイントが無効な場合、Kafka ソースは Kafka コンシューマーの内部的な自動定期オフセットコミットメカニズムに依存します。この機能は、
enable.auto.commitおよびauto.commit.interval.msKafka コンシューマープロパティによって制御されます。説明Kafka ソースは、フォールトトレランスと回復のためにコミットされたオフセットに依存しません。オフセットのコミットは、Kafka コンシューマーとコンシューマーグループの進捗を監視するためだけです。
-
その他のプロパティ
前述のプロパティに加えて、
setProperties(Properties)およびsetProperty(String, String)を使用すると、Kafka ソース とその基盤となる Kafka コンシューマーに任意の プロパティ を設定できます。 Kafka ソース は、次の特定のプロパティを提供します。パラメーター
説明
client.id.prefix
Kafka コンシューマーのクライアント ID プレフィックス。
partition.discovery.interval.ms
パーティション検出の間隔 (ミリ秒)。値に
-1を指定すると、動的パーティション検出が無効になります。説明[バッチモード] では、このプロパティは自動的に
-1に設定されます。register.consumer.metrics
Flink に Kafka コンシューマーメトリックを登録します。
その他の Kafka コンシューマー構成
Kafka コンシューマー構成の完全なリストについては、公式の Apache Kafka ドキュメントをご参照ください。
重要正しい操作を保証するために、Kafka DataStream コネクタは、手動で構成された次のプロパティを上書きします:
-
key.deserializerは、常に org.apache.kafka.common.serialization.ByteArrayDeserializer に上書きされます。 -
value.deserializerは常に org.apache.kafka.common.serialization.ByteArrayDeserializer に上書きされます。 -
auto.offset.reset.strategyは、OffsetsInitializerが提供するストラテジーによって上書きされます。
次の例は、Kafka コンシューマーを PLAIN SASL メカニズムを使用し、JAAS 構成を提供するように構成する方法を示しています。
KafkaSource.builder() .setProperty("sasl.mechanism", "PLAIN") .setProperty("sasl.jaas.config", "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"username\" password=\"password\";") -
-
モニタリング
Kafka ソースは、モニタリングと診断のために Flink のメトリックシステムを通じてメトリックを公開します。
-
メトリックスコープ
Kafka ソースリーダーのすべてのメトリックは、演算子のメトリックグループのサブグループである
KafkaSourceReaderメトリックグループに登録されます。特定のトピックパーティションに関連するメトリックは、KafkaSourceReader.topic.<topic_name>.partition.<partition_id>サブグループに登録されます。例えば、「my-topic」 トピックのパーティション 1 の現在のコンシューマーオフセットメトリック (
currentOffset) は、.operator.KafkaSourceReader.topic.my-topic.partition.1.currentOffset で利用可能です。成功したコミット数 (commitsSucceeded) は、.operator.KafkaSourceReader.commitsSucceeded で利用可能です。 -
メトリックのリスト
メトリック
説明
範囲
currentOffset
パーティションの現在のコンシューマーオフセット。
TopicPartition
committedOffset
パーティションの最後にコミットされたオフセット。
TopicPartition
commitsSucceeded
成功したオフセットコミットの総数。
KafkaSourceReader
commitsFailed
失敗したコミット数
KafkaSourceReader
-
Kafka コンシューマーメトリック
基盤となる Kafka コンシューマーのメトリックは、KafkaSourceReader.KafkaConsumer メトリックグループに登録されます。たとえば、
records-consumed-totalメトリックは .operator.KafkaSourceReader.KafkaConsumer.records-consumed-total に登録されます。register.consumer.metricsプロパティを使用して、Kafka コンシューマーメトリックを登録するかどうかを指定できます。このオプションはデフォルトで有効になっています (true)。Kafka コンシューマーメトリックの詳細については、「Apache Kafka ドキュメント」をご参照ください。
-
-
-
Kafka シンクの構築
Flink Kafka シンクは、データストリームを 1 つ以上の Kafka トピックに書き込みます。
DataStream<String> stream = ... Properties kafkaProperties = new Properties(); kafkaProperties.setProperty("bootstrap.servers", "localhost:9092"); KafkaSink<String> sink = KafkaSink.<String>builder() .setKafkaProducerConfig(kafkaProperties) .setRecordSerializer( KafkaRecordSerializationSchema.builder() .setTopic("my-topic") .setValueSerializationSchema(new SimpleStringSchema()) .build()) .setDeliveryGuarantee(DeliveryGuarantee.AT_LEAST_ONCE) .build(); stream.sinkTo(sink);Kafka シンクを構築するには、次のプロパティを構成する必要があります。
パラメーター
説明
Kafka クライアントプロパティ
bootstrap.serversプロパティは必須です。これには、カンマ区切りの Kafka ブローカーのリストを指定します。レコードシリアライザー
入力データを Kafka の
ProducerRecordに変換するには、KafkaRecordSerializationSchemaを提供する必要があります。 Flink は、メッセージキーと値のシリアル化、トピックの選択、メッセージのパーティショニングなどの一般的なコンポーネントを提供するスキーマビルダーを提供します。 また、対応するインターフェイスを実装して、よりきめ細かな制御を行うことも可能です。 Kafka に書き込む ProducerRecord を生成するために、受信レコードごとに ProducerRecord<byte[], byte[]> serialize(T element, KafkaSinkContext context, Long timestamp) メソッドが呼び出されます。ProducerRecordは、各レコードを Kafka に書き込む方法を詳細にコントロールし、次の操作を可能にします。-
送信先トピックの設定。
-
メッセージのキーの設定。
-
送信先パーティションの指定。
配信保証
bootstrap.serversパラメーターは必須であり、カンマ区切りの Kafka ブローカーのリストを指定します。配信保証
Flink のチェックポイントが有効な場合、Flink Kafka シンクは 1 回限りのセマンティクスを提供できます。チェックポイントを有効にすることに加えて、DeliveryGuarantee パラメーターを使用して異なる配信保証を指定できます。DeliveryGuarantee パラメーターは次のオプションを提供します:
-
DeliveryGuarantee.NONE:(デフォルト) Flink は保証を提供しません。データが失われたり、重複したりする可能性があります。
-
DeliveryGuarantee.AT_LEAST_ONCE:データが失われないことを保証しますが、重複が発生する可能性があります。
-
DeliveryGuarantee.EXACTLY_ONCE:Kafka トランザクションを使用して 1 回限りのセマンティクスを提供します。
説明EXACTLY_ONCE セマンティクスを使用する場合は、「1 回限りのセマンティクスに関する考慮事項」をご参照ください。
-
Flink CDC
Kafka コネクタをソースまたはシンクとして使用して、Flink CDC の YAML ジョブを作成します。
制限事項
-
Kafka データソースから Flink CDC データをインジェストするには、Realtime Compute for Apache Flink (VVR) 11.1 以降を使用します。
-
JSON、Debezium JSON、および Canal JSON のみがサポートされています。
-
複数のパーティションに分散された単一テーブルからデータを読み取るのは、Realtime Compute for Apache Flink (VVR) 8.0.11 以降でのみサポートされています。
構文
source:
type: kafka
name: Kafka source
properties.bootstrap.servers: localhost:9092
topic: ${kafka.topic}
sink:
type: kafka
name: Kafka Sink
properties.bootstrap.servers: localhost:9092
パラメーター
-
一般
パラメーター
説明
必須
型
デフォルト
備考
type
ソースまたはシンクのタイプ。
はい
String
–
値は
kafkaにする必要があります。name
ソースまたはシンクの名前。
いいえ
String
–
なし
properties.bootstrap.servers
Kafka ブローカーアドレス。
はい
String
–
フォーマットは
host1:port1,host2:port2,host3:port3で、区切り文字はカンマ (,) です。properties.*
Kafka クライアントの構成プロパティ。
いいえ
String
–
プロパティキーは、公式の Apache Kafka ドキュメントのプロデューサー設定およびコンシューマー設定で定義されている有効なオプションである必要があります。
Realtime Compute for Apache Flink (VVR) は、残りのキーと値のペアを基盤となる Kafka クライアントに渡す前に、
properties.プレフィックスを削除します。たとえば、トピックの自動作成を無効にするには、'properties.allow.auto.create.topics' = 'false'と設定します。key.format
Kafka メッセージキーのシリアル化および逆シリアル化フォーマット。
いいえ
String
–
-
ソースについては、
jsonフォーマットのみがサポートされています。 -
シンクの場合、有効な値は次のとおりです:
-
csv
-
json
-
説明このオプションは、Realtime Compute for Apache Flink (VVR) 11.0.0 以降でのみサポートされます。
value.format
Kafka メッセージ値のシリアル化および逆シリアル化フォーマット。
いいえ
String
debezium-json
-
ソースの場合、有効な値は次のとおりです:
-
debezium-json
-
canal-json
-
json
-
-
シンクの場合、有効な値は次のとおりです:
-
debezium-json
-
canal-json
-
canal-protobuf
-
説明-
debezium-jsonおよびcanal-jsonフォーマットは、Realtime Compute for Apache Flink (VVR) のバージョン 8.0.10 以降を必要とします。 -
jsonフォーマットには、Realtime Compute for Apache Flink (VVR) のバージョン 11.0.0 以降が必要です。
-
-
ソースパラメーター
パラメーター
説明
必須
型
デフォルト
備考
topic
読み取るトピック。
いいえ
String
–
複数のトピックをサブスクライブするには、トピック名をセミコロン (;) で区切ります。例:
topic-1;topic-2。説明このパラメーター、または
topic-patternのいずれか一方を指定します。topic-pattern
サブスクライブするトピックの名前に一致する正規表現。
いいえ
String
–
例:
-
user_event_.*:user_event_をプレフィックスとするすべてのトピックに一致します。 -
prod\.logs\..*:prod.logs.をプレフィックスとするトピックに一致します (.文字はエスケープする必要があります)。
説明このパラメーター、または
topicのいずれか一方を指定します。properties.group.id
コンシューマーグループ ID。
いいえ
String
–
新しいコンシューマーグループ ID を指定する場合、初期の開始オフセットを定義するために、properties.auto.offset.reset パラメーターを
earliestまたはlatestに設定する必要があります。scan.startup.mode
Kafka コンシューマーの開始オフセット。
いいえ
String
group-offsets
有効な値:
-
earliest-offset:利用可能な最も古いオフセットから読み取りを開始します。
-
latest-offset:最新のオフセットから読み取りを開始します。
-
group-offsets (デフォルト値):指定された properties.group.id のコミット済みオフセットから読み取りを開始します。
-
timestamp:scan.startup.timestamp-millis で指定されたタイムスタンプから読み取りを開始します。
-
specific-offsets:scan.startup.specific-offsets で指定されたオフセットから読み取りを開始します。
説明このパラメーターは、ジョブがステートレスで起動する場合にのみ適用されます。ステートフルなジョブが起動すると、常にそのステートに保存されているオフセットから消費します。
scan.startup.specific-offsets
scan.startup.modeがspecific-offsetsに設定されている場合の、各パーティションの開始オフセット。いいえ
String
–
例:
partition:0,offset:42;partition:1,offset:300scan.startup.timestamp-millis
scan.startup.modeがtimestampに設定されている場合の、ミリ秒単位の開始タイムスタンプです。いいえ
Long
–
単位はミリ秒です。
scan.topic-partition-discovery.interval
トピック内の新しいパーティションを動的に検出する間隔。
いいえ
Duration
5 分
コネクタは定期的に新しいパーティションを検出し、読み取ります。
topic-patternを使用する場合、コネクタはパターンに一致する新しいトピックも検出します。検出を無効にするには、この値を 0 以下に設定します。scan.check.duplicated.group.id
properties.group.idで指定されたコンシューマーグループが重複しているかどうかを確認します。いいえ
Boolean
false
有効な値:
-
true:ジョブが開始される前に重複するコンシューマーグループをチェックします。重複が見つかった場合、ジョブは失敗します。
-
false:競合をチェックせずにジョブを開始します。
schema.inference.strategy
スキーマ解析戦略。
いいえ
String
continuous
有効な値:
-
continuous:各データレコードのスキーマを解析します。スキーマに互換性がない場合、システムはより広いスキーマを推論し、スキーマ変更イベントを生成します。
-
static:ジョブの開始時にスキーマ解析を 1 回だけ実行します。データはこの初期スキーマに基づいて解析され、スキーマ変更イベントは生成されません。
説明-
スキーマ解析の詳細については、「スキーマ解析と進化のポリシー」をご参照ください。
-
この構成オプションは、Ververica Runtime (VVR) 8.0.11 以降でのみサポートされます。
scan.max.pre.fetch.records
初期スキーマ推論のためにパーティションごとに消費される最大メッセージ数。
いいえ
Int
50
データ処理が開始される前に、システムはスキーマを初期化するために、各パーティションから指定された数の最新メッセージを事前にフェッチして消費します。
key.fields-prefix
名前の競合を避けるためのメッセージキーフィールド名のプレフィックス。
いいえ
String
–
例えば、このパラメーターが
key_に設定され、メッセージキーにaという名前のフィールドが含まれている場合、解析されたフィールド名はkey_aになります。説明key.fields-prefixの値は、value.fields-prefixの値のプレフィックスであってはなりません。value.fields-prefix
名前の競合を避けるためのメッセージ値フィールド名のプレフィックス。
いいえ
String
–
たとえば、このパラメーターが
value_に設定されていて、メッセージの値にbという名前のフィールドが含まれている場合、解析されたフィールド名はvalue_bになります。説明value.fields-prefixの値は、key.fields-prefixの値のプレフィックスにすることはできません。metadata.list
下流のシンクに渡されるメタデータ列。
いいえ
String
–
利用可能なメタデータ列には、
topic、partition、offset、timestamp、timestamp-type、headers、およびleader-epochが含まれます。列名はコンマで区切ります。scan.value.initial-schemas.ddls
特定のテーブルの初期スキーマを定義する DDL 文。
いいえ
String
–
複数の DDL 文はセミコロン (
;) で区切ります。たとえば、CREATE TABLE db1.t1 (id BIGINT, name VARCHAR(10)); CREATE TABLE db1.t2 (id BIGINT);を使用して、テーブル db1.t1 と db1.t2 の初期スキーマをそれぞれ指定します。DDL で定義されたテーブルスキーマは、ターゲットシンクテーブルと一致し、Flink SQL 構文に準拠している必要があります。
説明この構成オプションは、Ververica Runtime (VVR) 11.5 以降でのみサポートされます。
ingestion.ignore-errors
データ解析エラーを無視します。
いいえ
Boolean
false
説明この構成オプションは、Ververica Runtime (VVR) 11.5 以降でのみサポートされます。
ingestion.error-tolerance.max-count
ジョブが失敗するまでに許容される解析エラーの最大数。
ingestion.ignore-errorsがtrueの場合にのみ有効です。いいえ
Integer
-1
このパラメーターは、
ingestion.ignore-errorsがtrueに設定されている場合にのみ適用されます。値 -1 は無制限の許容範囲を示します。つまり、解析例外によってジョブが失敗することはありません。説明この構成オプションは、Ververica Runtime (VVR) 11.5 以降でのみサポートされます。
scan.duplicate-field.strategy
キーと値の部分から解析された重複するフィールド名をどのように処理するかを指定します。
いいえ
String
EXCEPTION
有効な値:
-
EXCEPTION:キーと値に重複するフィールドが存在する場合に例外をスローします。これは VVR 11.6 以前のデフォルトの動作です。
-
PREFER_KEY:フィールドが重複している場合、キーフィールドの値を使用します。
-
PREFER_VALUE:フィールドが重複している場合、値フィールドの値を使用します。
説明この構成オプションは、Ververica Runtime (VVR) 11.7 以降でのみサポートされます。
-
Debezium JSON フォーマットパラメーター
パラメーター
必須
型
デフォルト
説明
debezium-json.distributed-tables
いいえ
Boolean
false
単一の Debezium JSON テーブルのデータが複数のパーティションに分散している場合は、
trueに設定します。説明この構成オプションは、Ververica Runtime (VVR) 8.0.11 以降でのみサポートされます。
重要このパラメーターを変更するには、ステートレスでの起動が必要です。
debezium-json.schema-include
いいえ
Boolean
false
Debezium JSON メッセージにスキーマを含めます。これは、Debezium Kafka Connect 構成の
value.converter.schemas.enableプロパティに対応しています。有効な値:
-
true:Debezium JSON メッセージにはスキーマが含まれます。
-
false:Debezium JSON メッセージにはスキーマが含まれません。
debezium-json.ignore-parse-errors
いいえ
Boolean
false
有効な値:
-
true:解析例外を引き起こす行をスキップします。
-
false:エラーをスローし、ジョブは失敗します。
debezium-json.infer-schema.primitive-as-string
いいえ
Boolean
false
テーブルスキーマの解析時に、すべてのプリミティブ型を
Stringとして解析します。有効な値:
-
true: すべてのプリミティブ型を
Stringとして解析します。 -
false:デフォルトのルールに基づいて型を解析します。
debezium-json.infer-schema.string-type-inference
いいえ
Boolean
true
文字列フィールドを TIME、DATE、または TIMESTAMP として推論するかどうかを指定します。このパラメーターを
falseに設定した場合、コネクタはこの推論をスキップし、フィールドを STRING として保持します。説明このパラメーターは、Ververica Runtime (VVR) 11.8 以降でのみサポートされます。
-
-
Canal JSON フォーマットパラメーター
パラメーター
必須
型
デフォルト
説明
canal-json.distributed-tables
いいえ
Boolean
false
Canal JSON の単一テーブルのデータが複数のパーティションに分散している場合は、このオプションを有効にする必要があります。
説明この構成オプションは、Ververica Runtime (VVR) 8.0.11 以降でのみサポートされます。
重要このパラメーターを変更するには、ステートレスでの起動が必要です。
canal-json.database.include
いいえ
String
–
Canal レコードの
databaseメタデータフィールドによってチェンジログをフィルタリングするための、オプションの正規表現です。一致するデータベースのレコードのみが処理されます。この正規表現は、Java の Pattern クラスと互換です。canal-json.table.include
いいえ
String
–
Canal レコードの
tableメタデータフィールドを使用して変更ログをフィルターするためのオプションの正規表現です。一致するテーブルのレコードのみが処理されます。この正規表現は、Java の Pattern クラスと互換性があります。canal-json.ignore-parse-errors
いいえ
Boolean
false
有効な値:
-
true:解析例外が発生した場合、現在の行をスキップします。
-
false:エラーをスローし、ジョブは起動に失敗します。
canal-json.infer-schema.primitive-as-string
いいえ
Boolean
false
テーブルスキーマの解析時に、すべてのプリミティブ型を
Stringとして解析します。有効な値:
-
true: すべてのプリミティブ型を
Stringとして解析します。 -
false:デフォルトのルールに基づいて型を解析します。
canal-json.infer-schema.string-type-inference
いいえ
Boolean
true
文字列フィールドを TIME、DATE、または TIMESTAMP として推論するかどうかを指定します。このパラメーターを
falseに設定した場合、コネクタはこの推論をスキップし、フィールドを STRING のままにします。説明このパラメーターは、Ververica Runtime (VVR) 11.8 以降でのみサポートされます。
canal-json.infer-schema.strategy
いいえ
String
AUTO
テーブルスキーマの解析戦略。
有効な値:
-
AUTO: JSON データからスキーマを自動的に解析します。解析エラーを防ぐため、データに
sqlTypeフィールドが含まれていない場合に推奨されます。 -
SQL_TYPE: Canal JSON データ内の
sqlType配列からスキーマを解析します。データにsqlTypeフィールドが含まれている場合、より正確な型を取得するために、これを SQL_TYPE に設定することをお勧めします。 -
MYSQL_TYPE: Canal JSON データ内の
mysqlType配列からスキーマを解析します。
Kafka の Canal JSON データに sqlType フィールドが含まれており、より正確な型マッピングが必要な場合は、canal-json.infer-schema.strategy を SQL_TYPE に設定します。
sqlType型マッピングルールの詳細については、「Canal JSON のスキーマ解析」をご参照ください。説明-
この構成は、Ververica Runtime (VVR) 11.1 以降でのみサポートされます。
-
MYSQL_TYPE値は、Ververica Runtime (VVR) 11.3 以降でサポートされています。
canal-json.mysql.treat-mysql-timestamp-as-datetime-enabled
いいえ
Boolean
true
MySQL の
TIMESTAMP型を CDC のTIMESTAMP型にマッピングします。-
true: MySQL
TIMESTAMP型は CDCTIMESTAMP型にマップされます。 -
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.string-type-inference
いいえ
Boolean
true
文字列フィールドを TIME、DATE、または TIMESTAMP として推論するかどうかを指定します。このパラメーターを
falseに設定した場合、コネクタはこの推論をスキップし、フィールドを STRING として保持します。説明このパラメーターは、Ververica Runtime (VVR) 11.8 以降でのみサポートされます。
json.infer-schema.flatten-nested-columns.enable
いいえ
Boolean
false
JSON データのネストされた列を再帰的に展開します。有効な値:
-
true:ネストされた列を再帰的に展開します。
-
false: ネストされたカラムを
Stringとして扱います。
json.decode.parser-table-id.fields
いいえ
String
–
JSON 形式のデータを解析する際に、指定された JSON フィールドの値を使用して tableId を生成します。複数のフィールドの値は英語のカンマ
,で連結されます。たとえば、JSON データが{"col0":"a", "col1","b", "col2","c"}の場合、生成される結果は次のようになります:構成
tableId
col0
a
col0,col1
a.b
col0,col1,col2
a.b.c
json.infer-schema.fixed-types
いいえ
String
–
JSON データを解析するとき、特定のフィールドのデータの型を指定できます。カンマ
,を使用して複数のフィールドを区切ります。たとえば、id BIGINT, name VARCHAR(10)は、idフィールドが BIGINT 型であり、nameフィールドが VARCHAR(10) 型であることを指定します。説明-
この構成オプションは、Ververica Runtime (VVR) 11.5 以降でのみサポートされます。
-
Ververica Runtime (VVR) バージョン 11.5 でこの構成を使用する場合、構成
scan.max.pre.fetch.records: 0も追加する必要があります。
json.decode.empty-value-as-delete.enabled
いいえ
Boolean
false
Kafka の圧縮トピック内のトゥームストーンメッセージ (空の値を持つ) を DELETE イベントとして解析するかどうかを指定します。空の値が削除セマンティクスを表すシナリオ (圧縮トピックのミラーリングや CDC の削除シグナルなど) で使用されます。
説明この構成オプションは、Ververica Runtime (VVR) 11.7 以降でのみサポートされます。
-
-
-
シンクテーブルのパラメーター
パラメーター
説明
必須
型
デフォルト
備考
type
シンクのタイプ。
はい
String
–
値は
kafkaである必要があります。name
シンクの名前。
いいえ
String
–
なし
topic
Kafka トピック名。
いいえ
String
–
このパラメーターが指定されている場合、すべてのデータはこのトピックに書き込まれます。
説明このパラメーターが指定されていない場合、各レコードは TableID にちなんで名付けられたトピックに書き込まれます。TableID は、データベース名とテーブル名をピリオド (
.) で結合して構築されます。例:databaseName.tableName。partition.strategy
Kafka パーティションの書き込み戦略。
いいえ
String
all-to-zero
有効な値:
-
all-to-zero(デフォルト):すべてのデータをパーティション 0 に書き込みます。 -
hash-by-key:プライマリキーのハッシュ値に基づいてデータをパーティションに書き込みます。これにより、同じプライマリキーを持つレコードが同じパーティションに書き込まれ、順序が保持されます。
sink.tableId-to-topic.mapping
上流のテーブル名から下流の Kafka トピック名へのマッピング。
いいえ
String
–
マッピングはセミコロン (
;) で区切ります。各マッピング内で、上流のテーブル名と下流の Kafka トピック名をコロン (:) で区切ります。テーブル名には正規表現を使用できます。複数のテーブルを同じトピックにマッピングするには、テーブル名をカンマ (,) で区切ります。例:mydb.mytable1:topic1;mydb.mytable2:topic2。説明このパラメーターを使用すると、元のテーブル名情報を保持したまま、マッピングされたトピックを変更できます。
-
Canal JSON フォーマットパラメーター
パラメーター
必須
型
デフォルト
説明
canal-json.serialize.update.keep-changed-fields-only
いいえ
Boolean
false
Canal JSON フォーマットの UPDATE メッセージの
oldセクションに、変更されたフィールドの以前の値のみを含めるかどうかを指定します。説明このパラメーターは、Ververica Runtime (VVR) 11.8 以降でのみサポートされます。
-
Debezium JSON フォーマットパラメーター
パラメーター
必須
型
デフォルト
説明
debezium-json.include-schema.enabled
いいえ
Boolean
false
Debezium JSON データにスキーマ情報を含めます。
debezium-json.emit.full-table-id.enabled
いいえ
Boolean
false
完全な 3 部構成のテーブル ID を Debezium JSON メタデータフィールドに書き込みます。
このパラメーターが有効な場合、マッピングは次のようになります:
CDC テーブル ID の部分
Debezium JSON キー
名前空間
dbスキーマ
schemaテーブル
tableこのパラメーターが無効な場合、マッピングは次のようになります:
CDC テーブル ID の部分
Debezium JSON キー
名前空間
マッピングされていません
スキーマ
dbテーブル
table説明このパラメーターは、Ververica Runtime (VVR) 11.6 以降でのみサポートされます。
-
例
-
Kafka を Flink CDC ソースとして使用する:
source: type: kafka name: Kafka source properties.bootstrap.servers: ${kafka.bootstraps.server} topic: ${kafka.topic} value.format: ${value.format} scan.startup.mode: ${scan.startup.mode} sink: type: hologres name: Hologres sink endpoint: <yourEndpoint> dbname: <yourDbname> username: ${secret_values.ak_id} password: ${secret_values.ak_secret} sink.type-normalize-strategy: BROADEN -
Kafka を Flink CDC シンクとして使用する:
source: type: mysql name: MySQL Source hostname: ${secret_values.mysql.hostname} port: ${mysql.port} username: ${secret_values.mysql.username} password: ${secret_values.mysql.password} tables: ${mysql.source.table} server-id: 8601-8604 sink: type: kafka name: Kafka Sink properties.bootstrap.servers: ${kafka.bootstraps.server} route: - source-table: ${mysql.source.table} sink-table: ${kafka.topic}routeモジュールは、ソーステーブルの送信先 Kafka トピックを指定します。
デフォルトでは、ApsaraMQ for Kafka の自動トピック作成機能は無効になっています。詳細については、「自動トピック作成に関するよくある質問」をご参照ください。ApsaraMQ for Kafka にデータを書き込む前に、トピックを作成する必要があります。詳細については、「ステップ 3:リソースの作成」をご参照ください。
スキーマ解析と進化のポリシー
Kafka コネクタは、現在既知のすべてのテーブルのスキーマを維持します。
テーブルスキーマの初期化
テーブルスキーマには、列とデータ型、データベースとテーブル名、およびプライマリキーが含まれます。次のセクションでは、これらのそれぞれを初期化する方法について説明します。
-
列とデータ型の情報
Flink CDC ジョブはデータから列とデータ型を自動的に推論できますが、特定のテーブルに対して明示的に定義したい場合があります。型をどの程度制御する必要があるかに応じて、3 つのスキーマ初期化戦略があります:
-
完全自動スキーマ推論
Kafka からデータを読み取る前に、Kafka コネクタは各パーティションから最大 scan.max.pre.fetch.records 個のメッセージを消費しようとし、各メッセージのスキーマを解析し、これらのスキーマをマージしてテーブルスキーマを初期化します。その後、データが実際に消費される前に、この初期化されたスキーマに基づいてテーブル作成イベントが生成されます。
Debezium JSON および Canal JSON フォーマットの場合、テーブル情報は各メッセージ内に含まれています。scan.max.pre.fetch.records パラメーターに基づいて事前にフェッチされたメッセージには、複数のテーブルのデータが含まれている可能性があります。したがって、単一のテーブルに対して事前にフェッチされたレコードの数は決定できません。事前フェッチとスキーマの初期化は、メッセージが消費されて処理される前に、各パーティションに対して 1 回だけ実行されます。後で新しいテーブルのデータが表示された場合、そのテーブルの最初のレコードから解析されたスキーマが初期スキーマとして使用され、スキーマは再度事前フェッチまたは初期化されません。
単一テーブルのデータを複数のパーティションに分散させることは、Ververica Runtime (VVR) 8.0.11 以降でのみサポートされており、debezium-json.distributed-tables または canal-json.distributed-tables 構成オプションを true に設定する必要があります。
-
初期テーブルスキーマの指定
場合によっては、初期テーブルスキーマを明示的に定義する必要があります。たとえば、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.infer-schema.fixed-types パラメーターを使用して、この情報を含むフィールドを指定できます。これらのフィールドは、データベース名とテーブル名にマッピングされます。以下は構成例です:
source: type: kafka name: Kafka Source properties.bootstrap.servers: host:9092 topic: test-topic value.format: json scan.startup.mode: earliest-offset # col1 フィールドの値をデータベース名として、col2 フィールドの値をテーブル名として使用 json.decode.parser-table-id.fields: col1,col2この構成では、コネクタは各レコードを、データベース名が
col1フィールドの値、テーブル名がcol2フィールドの値であるテーブルに送信します。
-
-
プライマリキー情報
-
Canal JSON フォーマットの場合、JSON データの
pkNamesフィールドがテーブルのプライマリキーを定義します。 -
Debezium JSON および JSON フォーマットの場合、データにはプライマリキー情報が含まれていません。
transformルールを使用して、テーブルにプライマリキーを手動で追加できます:transform: - source-table: \.*.\.* projection: \* primary-keys: key1, key2
-
スキーマ解析とスキーマ進化
テーブルスキーマが初期化された後、schema.inference.strategy が static に設定されている場合、Kafka コネクタは初期テーブルスキーマに基づいて各メッセージのメッセージ値を解析し、スキーマ変更イベントを生成しません。schema.inference.strategy が continuous に設定されている場合、Kafka コネクタは各 Kafka メッセージのメッセージ値を解析し、その物理列を識別し、結果のスキーマを現在維持されているスキーマと比較します。スキーマが一致しない場合、コネクタはそれらをマージしようとし、対応するテーブルスキーマ変更イベントを生成します。マージルールは次のとおりです:
-
解析された物理列に現在のスキーマに存在しないフィールドが含まれている場合、これらのフィールドはスキーマに追加され、それらを null 許容列として追加するイベントが生成されます。
-
解析された物理列が、現在のスキーマに存在するフィールドを含まない場合、それらのフィールドは保持され、その値には
NULLが設定されます。列削除イベントは生成されません。 -
同じ名前の列は次のように処理されます:
-
列のデータ型は同じだが精度が異なる場合、精度の大きい方の型が使用され、列の型変更イベントが生成されます。
-
列のデータ型が異なる場合、システムは以下の型階層ツリーで最小の共通親型を見つけます。システムはその後、この共通親型を列に使用し、列の型変更イベントを生成します。

-
-
サポートされているスキーマ進化ポリシー:
-
列の追加:コネクタは新しい列をスキーマの末尾に追加し、そのデータを同期します。新しい列は null 許容として設定されます。
-
列の削除:列削除イベントは生成されません。代わりに、その列の後続のデータには
NULLが設定されます。 -
列の名前変更:コネクタはこれを、古い列を削除して新しい列を追加する処理として扱います。新しい列はスキーマの末尾に追加され、元の列の値には
NULLが入力されます。 -
列の型の変更:
-
カラムタイプの変更をサポートするダウンストリーム sink が、その変更を処理するように設定されている場合、Flink CDC ジョブはその変更 (たとえば、
INTからBIGINTへ) に対応できます。 この機能は、特定の sink でサポートされているカラムタイプ変更ルールに依存します。 サポートされているルールについては、ご使用の sink のドキュメントを参照してください。 -
Hologres のように列の型の変更をサポートしない下流のシンクの場合、型の拡張を使用できます。この機能は、ジョブの開始時に下流のシンクに広いデータ型を持つテーブルを作成します。列の型が変更された場合、新しい型が下流のシンクで定義された広い型に収まる限り、システムはその変更を許容できます。
-
-
-
サポートされていないスキーマ変更:
-
プライマリキーやインデックスなどの制約の変更。
-
列を
NOT NULLからNULLABLEに変更すること。
-
-
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 Source
properties.bootstrap.servers: host:9092
topic: test-topic
value.format: json
scan.startup.mode: earliest-offset
# Enable Dirty Data Tolerance
ingestion.ignore-errors: true
# Tolerate up to 1000 dirty data records
ingestion.error-tolerance.max-count: 1000
この構成では、ジョブは 1,000 件以下のダーティレコードを検出する限り、実行を継続します。その数がしきい値を超えると、ジョブは失敗するため、データを調査できます。
ダーティデータによってジョブが決して失敗しないようにするには、以下の構成を使用します。
source:
type: kafka
name: Kafka Source
properties.bootstrap.servers: host:9092
topic: test-topic
value.format: json
scan.startup.mode: earliest-offset
# Enable Dirty Data Tolerance
ingestion.ignore-errors: true
# Tolerate all dirty data records
ingestion.error-tolerance.max-count: -1
ダーティデータの許容範囲を設定することでジョブは実行し続けますが、問題のあるレコードを検査したい場合もあるでしょう。また、ダーティデータを分析して Kafka プロデューサーを改善することもできます。「ダーティデータのコレクション」で説明されているように、TaskManager のログでジョブのダーティデータを確認できます。以下に例を示します。
source:
type: kafka
name: Kafka Source
properties.bootstrap.servers: host:9092
topic: test-topic
value.format: json
scan.startup.mode: earliest-offset
# Enable Dirty Data Tolerance
ingestion.ignore-errors: true
# Tolerate all dirty data records
ingestion.error-tolerance.max-count: -1
pipeline:
dirty-data.collector:
# Write dirty data to the TaskManager log file
type: logger
テーブル名とトピックのマッピング
Kafka が Flink CDC の sink として機能する場合、メッセージフォーマット (Debezium JSON や Canal JSON など) には元のテーブル名が埋め込まれます。下流のコンシューマーは通常、トピック名ではなく、この埋め込まれた名前をテーブル識別子として使用するため、テーブル名とトピック間のマッピングを正しく設定することが重要です。
MySQL データベースから 2 つのテーブル、mydb.mytable1 と mydb.mytable2 を同期する必要があるとします。次のマッピング戦略を利用できます:
1. マッピング戦略なし
マッピング戦略がない場合、各テーブルのデータは「<データベース名>.<テーブル名>」というフォーマットで命名されたトピックに書き込まれます。したがって、mydb.mytable1 のデータは mydb.mytable1 という名前のトピックに、mydb.mytable2 のデータは mydb.mytable2 という名前のトピックに書き込まれます。以下に構成例を示します:
source:
type: mysql
name: MySQL Source
hostname: ${secret_values.mysql.hostname}
port: ${mysql.port}
username: ${secret_values.mysql.username}
password: ${secret_values.mysql.password}
tables: mydb.mytable1,mydb.mytable2
server-id: 8601-8604
sink:
type: kafka
name: Kafka Sink
properties.bootstrap.servers: ${kafka.bootstraps.server}
2. ルートルールによるマッピング (非推奨)
デフォルトの「<データベース名>.<テーブル名>」フォーマットを使用する代わりに、特定のトピックにデータを書き込みたい場合があります。その場合、ルートルールを設定できます。以下に構成例を示します:
source:
type: mysql
name: MySQL Source
hostname: ${secret_values.mysql.hostname}
port: ${mysql.port}
username: ${secret_values.mysql.username}
password: ${secret_values.mysql.password}
tables: mydb.mytable1,mydb.mytable2
server-id: 8601-8604
sink:
type: kafka
name: Kafka Sink
properties.bootstrap.servers: ${kafka.bootstraps.server}
route:
- source-table: mydb.mytable1,mydb.mytable2
sink-table: mytable
この場合、mydb.mytable1 と mydb.mytable2 からのすべてのデータは、mytable という名前の単一のトピックに書き込まれます。
ただし、送信先トピックを変更するルートルールは、Kafka メッセージ (Debezium JSON または Canal JSON フォーマット) 内のテーブル名も変更してしまいます。すべての Kafka メッセージ内のテーブル名が mytable となり、このトピックからメッセージを消費するシステムで予期しない動作を引き起こす可能性があります。
3. sink.tableId-to-topic.mapping によるマッピング (推奨)
元のソーステーブル名を保持したままテーブル名をトピックにマッピングするには、`sink.tableId-to-topic.mapping` パラメーターを使用します。以下に構成例を示します:
source:
type: mysql
name: MySQL Source
hostname: ${secret_values.mysql.hostname}
port: ${mysql.port}
username: ${secret_values.mysql.username}
password: ${secret_values.mysql.password}
tables: mydb.mytable1,mydb.mytable2
server-id: 8601-8604
sink.tableId-to-topic.mapping: mydb.mytable1,mydb.mytable2:mytable
sink:
type: kafka
name: Kafka Sink
properties.bootstrap.servers: ${kafka.bootstraps.server}
または、以下の構成を使用することもできます:
source:
type: mysql
name: MySQL Source
hostname: ${secret_values.mysql.hostname}
port: ${mysql.port}
username: ${secret_values.mysql.username}
password: ${secret_values.mysql.password}
tables: mydb.mytable1,mydb.mytable2
server-id: 8601-8604
sink.tableId-to-topic.mapping: mydb.mytable1:mytable;mydb.mytable2:mytable
sink:
type: kafka
name: Kafka Sink
properties.bootstrap.servers: ${kafka.bootstraps.server}
この場合、mydb.mytable1 と mydb.mytable2 からのすべてのデータは mytable トピックに書き込まれ、Kafka メッセージ (Debezium JSON または Canal JSON フォーマット) 内のテーブル名は mydb.mytable1 または mydb.mytable2 として保持されます。これにより、下流のシステムは各レコードの元のソーステーブルを識別し続けることができます。
設定例
以下の例では、一般的なユースケースの設定を示します。
単一トピックからの読み取り
以下の例では、customers トピックを読み取り、データを Alibaba Cloud データレイク に書き込みます。
source:
type: kafka
topic: customers
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: json
# オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
schema.inference.strategy: continuous
sink:
type: paimon
name: Paimon Sink
catalog.properties.metastore: rest
catalog.properties.uri: dlf_uri
catalog.properties.warehouse: your_warehouse
catalog.properties.token.provider: dlf
# オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
commit.user: your_job_name
# オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
table.properties.deletion-vectors.enabled: true
JSON フォーマットの場合、生成されるテーブル名はデフォルトでトピック名と同じになります。
複数トピックからの読み取り
以下の例では、名前が正規表現に一致するトピックを読み取り、データを StarRocks に書き込みます。
source:
type: kafka
topic-pattern: user_event_.*
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: json
# オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
schema.inference.strategy: continuous
sink:
type: starrocks
jdbc-url: jdbc:mysql://<yourFeHostname>:9030
load-url: <yourFeHostname>:8030
username: <yourUsername>
password: ${secret_values.starrocks_password}
# オプション: データ量が少ないジョブの場合、フラッシュ間隔を短くして、データが長時間書き込まれないままになるのを防ぎます。デフォルトは 300000 ミリ秒 (5 分) です。
sink.buffer-flush.interval-ms: 5000
# オプション: アップストリームの文字セットが utf8mb4 の場合、テキストの切り捨てを防ぐためにこのパラメーターを 4 に設定します。デフォルトは 3 です。
unicode-char.max-bytes: 4
# オプション: 自動作成されるテーブルのバケット数を指定します。StarRocks バージョン 2.5.7 より前では、このパラメーターを明示的に設定する必要があります。それ以降のバージョンでは値を推論できます。
table.create.num-buckets: 8
# オプション: クラスター構成に基づいて、自動作成されるテーブルのレプリカ数を指定します。
table.create.properties.replication_num: 3
# オプション: StarRocks 3.2 以降では、この機能を有効にしてスキーマ変更を高速化します。
table.create.properties.fast_schema_evolution: true
# 注: 変換によってプライマリキーが変更された場合は、sink.ignore.update-before も false に設定する必要があります。
# そうしないと、古いプライマリキーを使用する行がダウンストリームシステムに残ってしまいます。
JSON フォーマットの場合、生成されるテーブル名はデフォルトでトピック名と同じになります。
キーの読み取りとフィールド競合の防止
キーと値でフィールド名が重複することによって発生するエラーは、以下のいずれかの方法で防ぐことができます。
-
フィールドにプレフィックスを追加して競合を防ぎます。
source: type: kafka topic: ${kafka.topic} properties.bootstrap.servers: localhost:9092 properties.group.id: ${kafka.group.id} key.format: json value.format: json # キーのフィールド名に key_ プレフィックスを追加します。 key.fields-prefix: key_ # 値のフィールド名に value_ プレフィックスを追加します。 value.fields-prefix: value_ # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。 schema.inference.strategy: continuous sink: type: paimon name: Paimon Sink catalog.properties.metastore: rest catalog.properties.uri: dlf_uri catalog.properties.warehouse: your_warehouse catalog.properties.token.provider: dlf # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。 commit.user: your_job_name # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。 table.properties.deletion-vectors.enabled: true -
競合解決ポリシーを設定します。詳細については、「scan.duplicate-field.strategy」をご参照ください。以下の設定では、キーのフィールドを優先し、値の中の同じ名前のフィールドは無視します。
source: type: kafka topic: ${kafka.topic} properties.bootstrap.servers: localhost:9092 properties.group.id: ${kafka.group.id} key.format: json value.format: json # キーのフィールドを優先し、値の中の同じ名前のフィールドは無視します。 scan.duplicate-field.strategy: PREFER_KEY # オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。 schema.inference.strategy: continuous sink: type: paimon name: Paimon Sink catalog.properties.metastore: rest catalog.properties.uri: dlf_uri catalog.properties.warehouse: your_warehouse catalog.properties.token.provider: dlf # オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。 commit.user: your_job_name # オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。 table.properties.deletion-vectors.enabled: true
メタデータ列の追加
以下の例では、customers トピックを読み取り、topic と partition のメタデータ列を追加します。
source:
type: kafka
topic: customers
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: json
# オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
schema.inference.strategy: continuous
metadata.list: topic,partition
sink:
type: paimon
name: Paimon Sink
catalog.properties.metastore: rest
catalog.properties.uri: dlf_uri
catalog.properties.warehouse: your_warehouse
catalog.properties.token.provider: dlf
# オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
commit.user: your_job_name
# オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
table.properties.deletion-vectors.enabled: true
解析エラーの処理
解析エラーが発生するとジョブは失敗します。ジョブが解析エラーを許容するように設定できます。この機能は、一般的に ダーティデータ収集 と組み合わせて使用されます。
以下の例では、すべての解析エラーを無視します。
source:
type: kafka
topic: customers
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: json
# オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
schema.inference.strategy: continuous
# 解析エラーを無視します。この機能を有効にすると、デフォルトですべての解析エラーが無視されます。
ingestion.ignore-errors: true
sink:
type: paimon
name: Paimon Sink
catalog.properties.metastore: rest
catalog.properties.uri: dlf_uri
catalog.properties.warehouse: your_warehouse
catalog.properties.token.provider: dlf
# オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
commit.user: your_job_name
# オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
table.properties.deletion-vectors.enabled: true
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
dirty-data.collector:
name: Logger Dirty Data Collector
type: logger
以下の例では、30 回の解析エラーが発生した後にジョブを失敗させます。
source:
type: kafka
topic: customers
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: json
# オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
schema.inference.strategy: continuous
# 解析エラーを無視します。
ingestion.ignore-errors: true
# 30 回の解析エラーが発生した後にジョブを失敗させます。
ingestion.error-tolerance.max-count: 30
sink:
type: paimon
name: Paimon Sink
catalog.properties.metastore: rest
catalog.properties.uri: dlf_uri
catalog.properties.warehouse: your_warehouse
catalog.properties.token.provider: dlf
# オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
commit.user: your_job_name
# オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
table.properties.deletion-vectors.enabled: true
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
dirty-data.collector:
name: Logger Dirty Data Collector
type: logger
JSON データの読み取り
以下のセクションでは、JSON フォーマットのデータを読み取る一般的な方法について説明します。
テーブル ID の解析方法の指定
デフォルトでは、JSON データのテーブル ID はトピック名です。データ内のフィールド値をテーブル ID として使用できます。以下の例では、db フィールドと tbl フィールドをテーブル ID として使用します。
source:
type: kafka
topic: customers
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: json
# オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
schema.inference.strategy: continuous
# db フィールドと tbl フィールドをテーブル ID として使用します。
value.json.decode.parser-table-id.fields: db,tbl
sink:
type: paimon
name: Paimon Sink
catalog.properties.metastore: rest
catalog.properties.uri: dlf_uri
catalog.properties.warehouse: your_warehouse
catalog.properties.token.provider: dlf
# オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
commit.user: your_job_name
# オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
table.properties.deletion-vectors.enabled: true
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
dirty-data.collector:
name: Logger Dirty Data Collector
type: logger
フィールドタイプの指定
フィールドタイプはフィールド値から推論されますが、推論されたタイプが期待するタイプではない場合があります。選択したフィールドに固定タイプを指定し、それらのフィールドに対する後続の型推論と進化をスキップできます。
以下の例では、4 つのフィールドのタイプを固定します。
source:
type: kafka
topic: customers
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: json
# db フィールドと tbl フィールドをテーブル ID として使用します。
value.json.decode.parser-table-id.fields: db,tbl
# 選択したフィールドに固定タイプを指定します。
value.json.infer-schema.fixed-types: 'db STRING, tbl STRING, id BIGINT, amount DECIMAL(18, 2)'
# 宣言されていないフィールドは引き続き動的に推論します。
schema.inference.strategy: continuous
sink:
type: paimon
name: Paimon Sink
catalog.properties.metastore: rest
catalog.properties.uri: dlf_uri
catalog.properties.warehouse: your_warehouse
catalog.properties.token.provider: dlf
# オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
commit.user: your_job_name
# オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
table.properties.deletion-vectors.enabled: true
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
dirty-data.collector:
name: Logger Dirty Data Collector
type: logger
Canal JSON データの読み取り
以下のセクションでは、Canal JSON フォーマットのデータを読み取る一般的な方法について説明します。
型推論ポリシーの設定
デフォルトでは、コネクタは Canal JSON データを読み取る際に、フィールド値からスキーマタイプを推論します。
source:
type: kafka
topic: customers
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: canal-json
# オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
schema.inference.strategy: continuous
sink:
type: paimon
name: Paimon Sink
catalog.properties.metastore: rest
catalog.properties.uri: dlf_uri
catalog.properties.warehouse: your_warehouse
catalog.properties.token.provider: dlf
# オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
commit.user: your_job_name
# オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
table.properties.deletion-vectors.enabled: true
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
dirty-data.collector:
name: Logger Dirty Data Collector
type: logger
Canal JSON データに記録されている SQL 型や MySQL 型などのスキーマ情報からスキーマを推論することもできます。以下の例では、MySQL 型を使用してスキーマを推論します。
source:
type: kafka
topic: customers
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: canal-json
# オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
schema.inference.strategy: continuous
# MySQL 型情報からスキーマを推論します。このパラメーターを SQL_TYPE に設定して、代わりに SQL 型情報を使用することもできます。
value.canal-json.infer-schema.strategy: MYSQL_TYPE
sink:
type: paimon
name: Paimon Sink
catalog.properties.metastore: rest
catalog.properties.uri: dlf_uri
catalog.properties.warehouse: your_warehouse
catalog.properties.token.provider: dlf
# オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
commit.user: your_job_name
# オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
table.properties.deletion-vectors.enabled: true
# ダーティデータコレクターを有効にして、解析できないレコードを出力します。
pipeline:
dirty-data.collector:
name: Logger Dirty Data Collector
type: logger
Debezium JSON データの読み取り
以下の例では、customers トピックを読み取り、データを Alibaba Cloud データレイク に書き込みます。
source:
type: kafka
topic: customers
properties.bootstrap.servers: localhost:9092
properties.group.id: ${kafka.group.id}
value.format: debezium-json
# オプション: 各レコードのスキーマを動的に推論し、スキーマの変更を検出します。
schema.inference.strategy: continuous
sink:
type: paimon
name: Paimon Sink
catalog.properties.metastore: rest
catalog.properties.uri: dlf_uri
catalog.properties.warehouse: your_warehouse
catalog.properties.token.provider: dlf
# オプション: コミットユーザーを指定します。競合を防ぐために、ジョブごとに異なるコミットユーザーを使用することを推奨します。
commit.user: your_job_name
# オプション: 削除ベクターを有効にして、読み取りパフォーマンスを向上させます。
table.properties.deletion-vectors.enabled: true
生の MySQL binlog の Kafka への同期
Flink CDC データインジェストは、生の MySQL binlog データを Canal JSON フォーマットで同期できます。以下のジョブは、複数のテーブルから order_dw_tables トピックに binlog を同期します。
source:
type: mysql
hostname: #{hostname}
port: 3306
username: #{username}
password: #{password}
tables: order_dw.\.*
server-id: 28601-28604
# オプション: 増分フェーズで作成されたテーブルからデータを同期します。
scan.binlog.newly-added-table.enabled: true
# オプション: テーブルと列のコメントを同期します。
include-comments.enabled: true
# オプション: TaskManager のメモリ不足エラーの可能性を防ぐために、まず非有界チャンクを処理します。
scan.incremental.snapshot.unbounded-chunk-first.enabled: true
# オプション: 解析フィルターを有効にして読み取りを高速化します。
scan.only.deserialize.captured.tables.changelog.enabled: true
# mysqlType、sqlType、sql、isDdl、およびその他のメタデータを Canal JSON データに追加します。
include-binlog-meta.enable: true
sink:
type: kafka
properties.bootstrap.servers: localhost:9092
topic: order_dw_tables
# Kafka の値に Canal JSON チェンジログフォーマットを使用します。
value.format: canal-json
# 日付と時刻データのシリアル化に使用するフォーマットを指定します。
value.canal-json.timestamp-format.standard: SQL
# binlog の順序を維持するために、すべてのデータをパーティション 0 に書き込みます。
partition.strategy: all-to-zero
Exactly-once セマンティクス
-
コンシューマーの分離レベルの設定
Kafka データを消費するすべてのアプリケーションでは、
isolation.levelプロパティを設定する必要があります。-
read_committed:コミット済みのデータのみを読み取ります。 -
read_uncommitted(デフォルト):コミットされていないデータも読み取ることができます。
EXACTLY_ONCE は
read_committedに依存します。そうでない場合、コンシューマーがコミットされていないデータを読み取り、一貫性が損なわれる可能性があります。 -
-
トランザクションタイムアウトとデータ損失
チェックポイントから回復する際、Realtime Compute for Apache Flink は、そのチェックポイントが開始される前にコミットされたトランザクションのみを考慮します。ジョブの障害発生から再起動までの時間が Kafka のトランザクションタイムアウトを超えると、Kafka は開いているトランザクションを自動的に中止し、データ損失が発生する可能性があります。
-
Kafka ブローカーの
transaction.max.timeout.msのデフォルト値は 15 分です。 -
デフォルトでは、Flink Kafka Sink は
transaction.timeout.msパラメーターを 1 時間に設定します。 -
ブローカーの
transaction.max.timeout.msを、Flink での設定値以上に増やす必要があります。
-
-
プロデューサープールと同時チェックポイント
EXACTLY_ONCEモードでは、固定サイズの Kafka プロデューサープールが使用されます。各チェックポイントは、このプールから 1 つのプロデューサーを使用します。同時チェックポイントの数がプールサイズを超えると、ジョブは失敗します。同時チェックポイントの最大数に基づいて、プロデューサープールのサイズを設定してください。
-
並列度のスケールダウンに関する制約
最初のチェックポイントが完了する前にジョブが失敗した場合、再起動時に元のプロデューサープールの情報が失われます。そのため、最初のチェックポイントが完了するまでは、ジョブの並列度をスケールダウンしないでください。スケールダウンが必要な場合でも、新しい並列度は
FlinkKafkaProducer.SAFE_SCALE_DOWN_FACTOR未満にすることはできません。 -
トランザクションによる読み取りのブロック
read_committedモードでは、コミットも中止もされていないトランザクションがあると、トピック全体の読み取り操作がブロックされます。例:
-
トランザクション 1 がデータを書き込みます。
-
トランザクション 2 がさらにデータを書き込み、コミットされます。
-
トランザクション 1 が開いている限り、コミット済みのトランザクション 2 のデータはコンシューマーには表示されません。
これには、以下の影響があります。
-
通常の操作中、データが表示されるまでのレイテンシーは、おおよそチェックポイントの間隔と等しくなります。
-
ジョブが失敗した場合、そのジョブが書き込んでいたトピックは、ジョブが再起動するかトランザクションがタイムアウトするまで、コンシューマーに対してブロックされます。極端なケースでは、トランザクションのタイムアウト処理自体が読み取り操作に影響を与えることもあります。
-