Realtime Compute for Apache Flink で Kafka SQL コネクタをソーステーブルまたは結果テーブルとして使用します。
概要
Apache Kafka は、オープンソースの分散イベントストリーミングプラットフォームであり、パフォーマンス専有型のデータ処理、ストリーミング分析、Data Integration に広く使用されています。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です。したがって、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 の 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 が競合する可能性があります。あるジョブで書き込み操作が失敗すると、Apache Kafka パーティションの Log Start Offset (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) インスタンスのセキュリティグループは、通常 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 がクライアントにアドバタイズするアドレスを見つけます。# 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 |
生のメッセージキー。 |
ソーステーブルと結果テーブル 説明
このパラメーターは、VVR 11.4 以降でのみサポートされます。 |
|
__raw_value__ |
STRING NOT NULL METADATA VIRTUAL |
生のメッセージ値。 |
ソーステーブルと結果テーブル 説明
このパラメーターは、VVR 11.4 以降でのみサポートされます。 |
コネクタオプション
-
一般
オプション
説明
タイプ
必須
デフォルト
備考
connector
コネクタのタイプ。
String
はい
–
値は
kafkaである必要があります。properties.bootstrap.servers
Kafka ブローカーアドレスのリスト。
String
はい
–
フォーマット:
host1:port1,host2:port2,...。アドレスはカンマ (,) で区切ります。properties.*
Kafka クライアントの追加プロパティ。
String
いいえ
–
プロパティキーは、公式の Apache Kafka ドキュメントの Producer Configs および Consumer Configs で定義されている有効なオプションである必要があります。
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のいずれか一方のみを設定できます。両方が設定されている場合、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.で始まるトピックに一致します (.文字はエスケープする必要があります)。
説明このオプションまたは
topicのいずれかを指定できますが、両方は指定できません。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 のコミット済みオフセットから読み取りを開始します。 -
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 を使用する場合、コネクタはパターンに一致する新しいトピックも検出します。この機能を無効にするには、間隔を正でない値に設定します。
説明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 データを保持します。説明-
このオプションは、VVR 8.0.6 以降でのみサポートされます。
-
式中の括弧はサポートされていません。
-
論理演算は左から右に評価されます。
-
ヘッダー値は比較のために UTF-8 文字列に変換されます。
scan.check.duplicated.group.id
別のアクティブなコンシューマーがすでに
properties.group.idを使用しているかどうかを確認します。Boolean
いいえ
false
有効な値:
-
true:ジョブを開始する前に、システムは重複したコンシューマーグループをチェックします。見つかった場合、競合を防ぐためにジョブは失敗します。
-
false:競合をチェックせずにジョブを開始します。
説明このオプションは、VVR 6.0.4 以降でのみサポートされます。
-
-
シンクテーブル
オプション
説明
タイプ
必須
デフォルト
備考
topic
ターゲットトピック。
String
はい
–
–
sink.partitioner
並列シンクインスタンスからのレコードを Kafka パーティションにマッピングします。
String
いいえ
default
有効な値:
-
default:デフォルトの Kafka パーティショナーを使用します。 -
fixed:各並列シンクインスタンスは固定の Kafka パーティションに書き込みます。 -
round-robin:レコードはラウンドロビン方式でパーティションに分散されます。 -
カスタムパーティショナー:カスタムパーティショナーを使用するには、
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 パラメーターで設定します。次の例では、JAAS 設定で PLAIN を SASL メカニズムとして使用するように Kafka テーブルを設定します。
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 の O&M チームに連絡して、正しいセキュリティと認証の設定を入手してください。
-
エスケープ:ネイティブの Apache Flink とは異なり、Realtime Compute for Apache Flink SQL エディターはデフォルトで二重引用符 (") をエスケープします。したがって、
properties.sasl.jaas.configオプションのユーザー名とパスワードに使用される二重引用符をエスケープするためにバックスラッシュ (\) を追加する必要はありません。 -
KMS での認証情報のホスト:
properties.sasl.jaas.configのユーザー名とパスワードをsecret://kms.<secret-name>.<key>に設定して、プレーンテキストの代わりに KMS で管理された認証情報を参照できます。これは、Realtime Compute エンジン VVR 11.9 以降でサポートされています。設定手順については、「KMS 認証情報管理の統合」をご参照ください。
ソーステーブルの開始オフセット
起動モード
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 への 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') のような関数を使用してフィールドを解析するのを避けるために、Source 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 を参照できるため、全体的なパフォーマンスが向上します。
1回限りのセマンティクス
-
コンシューマーの分離レベルの設定
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 のデータはコンシューマーには見えません。
これには以下の影響があります:
-
通常運用中、データの可視性遅延は、おおよそチェックポイント間隔に等しくなります。
-
ジョブが失敗した場合、書き込み先のトピックは、ジョブが再起動するかトランザクションがタイムアウトするまで、コンシューマーに対してブロックされます。極端な場合、トランザクションのタイムアウトプロセス自体も読み取り操作に影響を与える可能性があります。
-