All Products
Search
Document Center

Realtime Compute for Apache Flink:Kafka connector

Last Updated:Aug 25, 2026

Gunakan Kafka connector sebagai sumber, sink, atau tujuan Flink CDC di Realtime Compute for Apache Flink.

Ikhtisar

Apache Kafka adalah platform streaming event terdistribusi open-source yang banyak digunakan untuk pemrosesan data berkinerja tinggi, analitik streaming, dan integrasi data. Kafka connector untuk Realtime Compute for Apache Flink menggunakan client Apache Kafka open-source untuk menyediakan throughput data berkinerja tinggi, mendukung pembacaan dan penulisan berbagai format data, serta menawarkan semantik tepat-sekali.

Kategori

Deskripsi

Jenis yang didukung

Sumber SQL, sink

Sumber Flink CDC, sink

Sumber DataStream, sink

Mode eksekusi

Streaming

Format data

Format data yang didukung

  • CSV

  • JSON

  • Apache Avro

  • Confluent Avro

  • Debezium JSON

  • Canal JSON

  • Maxwell JSON

  • Raw

  • Protobuf

Catatan
  • Format Data Protobuf bawaan hanya didukung untuk Ververica Runtime (VVR) 8.0.9 dan versi setelahnya.

  • Setiap format data yang didukung memiliki parameter terkait yang dapat ditentukan dalam klausa WITH. Untuk informasi lebih lanjut, lihat Formats.

Metrik

Metrik

  • Tabel Sumber

    • numRecordsIn

    • numRecordsInPerSecond

    • numBytesIn

    • numBytesInPerSecond

    • currentEmitEventTimeLag

    • currentFetchEventTimeLag

    • sourceIdleTime

    • pendingRecords

  • Tabel Sink

    • numRecordsOut

    • numRecordsOutPerSecond

    • numBytesOut

    • numBytesOutPerSecond

    • currentSendTime

Catatan

Untuk informasi lebih lanjut tentang metrik, lihat Metrics.

Jenis API

SQL, DataStream, Flink CDC

Pembaruan/penghapusan sink

Connector ini hanya mendukung penambahan data ke tabel sink. Pembaruan dan penghapusan tidak didukung.

Catatan

Untuk informasi lebih lanjut tentang cara memperbarui atau menghapus data di Tabel Sink, lihat Upsert Kafka.

Prasyarat

Sebelum memulai, pastikan Anda memenuhi prasyarat berikut sesuai jenis kluster Kafka Anda:

  • Menghubungkan ke kluster ApsaraMQ for Kafka

    • Versi kluster Kafka minimal 0.11.

    • Anda telah membuat kluster ApsaraMQ for Kafka. Untuk informasi lebih lanjut, lihat Langkah 3: Buat sumber daya.

    • Ruang kerja Flink dan kluster Kafka berada dalam Virtual Private Cloud (VPC) yang sama, dan Anda telah menambahkan Blok CIDR ruang kerja Flink ke daftar putih ApsaraMQ for Kafka. Untuk informasi lebih lanjut, lihat Konfigurasi daftar putih.

    Penting

    Batasan penulisan data ke ApsaraMQ for Kafka:

    • ApsaraMQ for Kafka tidak mendukung format kompresi Zstandard (zstd) untuk penulisan.

    • ApsaraMQ for Kafka tidak mendukung penulisan idempoten atau transaksional, sehingga mencegah Anda menggunakan semantik tepat-sekali yang disediakan oleh tabel sink Kafka. Mulai Ververica Runtime (VVR) 8.0.0, Kafka connector menggunakan Kafka client 3.x, di mana properti properties.enable.idempotence secara default bernilai true. Oleh karena itu, untuk mencegah kegagalan penulisan saat menggunakan Ververica Runtime (VVR) 8.0.0 atau versi setelahnya untuk menulis ke ApsaraMQ for Kafka, Anda harus menambahkan konfigurasi properties.enable.idempotence=false ke definisi tabel sink Anda. Untuk perbandingan mesin penyimpanan dan batasan fitur ApsaraMQ for Kafka, lihat Perbandingan antar mesin penyimpanan.

  • Menghubungkan ke kluster Apache Kafka yang dikelola sendiri

    • Versi kluster Apache Kafka yang dikelola sendiri minimal 0.11.

    • Ruang kerja Flink memiliki konektivitas jaringan ke kluster Apache Kafka yang dikelola sendiri. Untuk detail cara menghubungkan ke kluster melalui internet publik, lihat FAQ tentang konektivitas jaringan.

    • Hanya opsi konfigurasi klien untuk Apache Kafka versi 2.8 yang didukung. Untuk informasi lebih lanjut, lihat dokumentasi Apache Kafka Consumer Configs dan Producer Configs.

Catatan

Penulisan transaksional tidak disarankan karena keterbatasan desain yang diketahui pada Apache Flink dan Apache Kafka. Saat Anda mengatur sink.delivery-guarantee = 'exactly-once', Kafka connector mengaktifkan penulisan transaksional, dengan masalah-masalah berikut:

  • Setiap checkpoint menghasilkan ID Transaksi baru. Jika interval checkpoint terlalu pendek, banjir ID Transaksi yang dihasilkan dapat menyebabkan koordinator kluster Kafka kehabisan memori, sehingga mengganggu stabilitas kluster.

  • Setiap transaksi membuat instance Producer baru. Jika terlalu banyak transaksi melakukan commit secara bersamaan, Pengelola Tugas (TaskManager) dapat kehabisan memori, sehingga mengganggu pekerjaan Apache Flink.

  • Jika beberapa pekerjaan Apache Flink menggunakan sink.transactional-id-prefix yang sama, ID Transaksi yang dihasilkan dapat bertabrakan. Ketika operasi penulisan gagal pada satu pekerjaan, hal ini dapat mencegah Log Start Offset (LSO) partisi Apache Kafka maju. Hal ini memengaruhi semua konsumen partisi tersebut.

Jika Anda memerlukan semantik tepat-sekali, gunakan connector Upsert Kafka untuk menulis ke tabel kunci primer, sehingga memastikan idempotensi. Jika Anda harus menggunakan penulisan transaksional, lihat Catatan penggunaan semantik tepat-sekali.

Pemecahan masalah konektivitas jaringan

Error Timed out waiting for a node assignment saat pekerjaan Realtime Compute for Apache Flink gagal dimulai biasanya menunjukkan adanya masalah konektivitas jaringan antara Realtime Compute for Apache Flink dan kluster Kafka.

Klien Kafka menghubungkan ke broker sebagai berikut:

  1. Klien menggunakan alamat yang ditentukan dalam bootstrap.servers untuk membuat koneksi awal ke kluster Kafka.

  2. Kluster Kafka mengembalikan metadata untuk setiap broker, termasuk titik akhirnya.

  3. Klien kemudian menggunakan titik akhir ini untuk menghubungkan ke broker guna membaca atau menulis data.

Meskipun alamat bootstrap.servers dapat dijangkau, klien tidak dapat membaca atau menulis data jika Kafka mengembalikan titik akhir broker yang salah. Masalah ini sering terjadi pada arsitektur jaringan yang menggunakan proxy, penerusan port, atau jalur sewa.

Langkah pemecahan masalah

ApsaraMQ for Kafka

  1. Konfirmasi jenis Titik Akhir

    • Titik Akhir Default (jaringan internal)

    • Titik Akhir SASL (jaringan internal dengan otentikasi)

    • Titik Akhir Publik (memerlukan aplikasi terpisah)

    Gunakan fitur Network Probe di Konsol pengembangan Realtime Compute for Apache Flink untuk mengesampingkan masalah konektivitas dengan alamat bootstrap.servers.

  2. Periksa grup keamanan dan daftar putih

    Tambahkan Blok CIDR ruang kerja Realtime Compute for Apache Flink ke daftar putih instans Kafka Anda. Untuk informasi lebih lanjut, lihat Lihat Blok CIDR VPC dan Konfigurasi daftar putih.

  3. Periksa konfigurasi SASL (jika diaktifkan)

    Jika Anda menggunakan titik akhir SASL_SSL, pastikan mekanisme JAAS, SSL, dan SASL dikonfigurasi dengan benar di pekerjaan Realtime Compute for Apache Flink Anda. Tanpa otentikasi yang tepat, koneksi dapat gagal selama fase handshake, yang juga dapat muncul sebagai timeout. Untuk informasi lebih lanjut, lihat Keamanan dan otentikasi.

Kafka yang dikelola sendiri

  1. Gunakan fitur Network Probe

    Fitur ini membantu Anda mengesampingkan masalah konektivitas dengan alamat bootstrap.servers dan memverifikasi bahwa titik akhir internal atau publik yang benar digunakan.

  2. Periksa grup keamanan dan daftar putih

    • Grup keamanan untuk instans Elastic Compute Service (ECS) harus mengizinkan lalu lintas masuk pada port titik akhir Kafka, biasanya 9092 atau 9093.

    • Pastikan firewall pada instans ECS mengizinkan lalu lintas dari VPC ruang kerja Realtime Compute for Apache Flink Anda. Untuk informasi lebih lanjut, lihat Lihat Blok CIDR VPC.

  3. Periksa konfigurasi

    1. Gunakan tool zkCli.sh atau zookeeper-shell.sh untuk login ke kluster ZooKeeper yang digunakan Kafka.

    2. Jalankan perintah untuk mendapatkan metadata broker. Misalnya, jalankan get /brokers/ids/0. Di field endpoints respons, temukan alamat yang diiklankan Kafka kepada klien.

      
      # bin/zookeeper-shell.sh localhost:2181
      Connecting to localhost:2181
      Welcome to ZooKeeper!
      JLine support is disabled
      
      WATCHER::
      
      WatchedEvent state:SyncConnected type:None path:null
      get /brokers/ids/0
      {"listener_security_protocol_map":{"PLAINTEXT":"PLAINTEXT"},"endpoints":["PLAINTEXT://116.62.xxx:9092"],"jmx_port":-1,"host":"116.62.xxx","timestamp":"1614840078030","port":9092,"version":4}
      
    3. Gunakan fitur Network Probe di Konsol pengembangan Realtime Compute for Apache Flink untuk menguji apakah alamat ini dapat diakses.

      Catatan
      • Jika alamat tidak dapat diakses, hubungi administrator Kafka Anda untuk memeriksa dan memperbaiki konfigurasi listeners dan advertised.listeners agar alamat yang diiklankan dapat diakses dari Realtime Compute for Apache Flink.

      • Untuk informasi lebih lanjut tentang koneksi klien Kafka, lihat Troubleshoot Connectivity.

  4. Periksa konfigurasi SASL (jika diaktifkan)

    Jika Anda menggunakan titik akhir SASL_SSL, pastikan mekanisme JAAS, SSL, dan SASL dikonfigurasi dengan benar di pekerjaan Realtime Compute for Apache Flink Anda. Tanpa otentikasi yang tepat, koneksi dapat gagal selama fase handshake, yang juga dapat muncul sebagai timeout. Untuk informasi lebih lanjut, lihat Keamanan dan otentikasi.

SQL

Gunakan Kafka connector sebagai tabel sumber atau tabel sink dalam pekerjaan SQL.

Sintaks

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'
)

Kolom metadata

Definisikan kolom metadata di tabel sumber atau sink untuk mengakses metadata pesan Kafka. Misalnya, saat Anda berlangganan ke beberapa topik, kolom metadata dapat mengidentifikasi topik asal setiap record.

CREATE TABLE kafka_source (
  -- Baca topik pesan sebagai kolom `record_topic`
  `record_topic` STRING NOT NULL METADATA FROM 'topic' VIRTUAL,
  -- Baca timestamp dari ConsumerRecord sebagai kolom `ts`
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
  -- Baca offset pesan sebagai kolom `record_offset`
  `record_offset` BIGINT NOT NULL METADATA FROM 'offset' VIRTUAL,
  ...
) WITH (
  'connector' = 'kafka',
  ...
);

CREATE TABLE kafka_sink (
  -- Tulis timestamp dari kolom `ts` sebagai timestamp ProducerRecord ke Kafka
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
  ...
) WITH (
  'connector' = 'kafka',
  ...
);

Tabel berikut mencantumkan kolom metadata yang didukung oleh tabel sumber dan sink Kafka.

Kunci

Type

Deskripsi

Ruang Lingkup

topic

STRING NOT NULL METADATA VIRTUAL

Topik pesan.

Tabel sumber

partition

INT NOT NULL METADATA VIRTUAL

ID partisi pesan.

Tabel sumber

headers

MAP<STRING, BYTES> NOT NULL METADATA VIRTUAL

Header pesan.

Tabel sumber dan tabel sink

leader-epoch

INT NOT NULL METADATA VIRTUAL

Pesan leader-epoch.

Tabel sumber

offset

BIGINT NOT NULL METADATA VIRTUAL

Offset pesan.

Tabel sumber

timestamp

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

Timestamp pesan.

Tabel sumber dan tabel sink

timestamp-type

STRING NOT NULL METADATA VIRTUAL

Jenis timestamp pesan. Nilai yang valid adalah:

  • NoTimestampType: Tidak ada timestamp yang ditentukan dalam pesan.

  • CreateTime: Waktu pesan dibuat.

  • LogAppendTime: Waktu pesan ditambahkan ke log broker Kafka.

Tabel sumber

__raw_key__

STRING NOT NULL METADATA VIRTUAL

Kunci pesan mentah.

Tabel sumber dan tabel sink

Catatan

Parameter ini hanya didukung di Ververica Runtime (VVR) 11.4 dan versi setelahnya.

__raw_value__

STRING NOT NULL METADATA VIRTUAL

Nilai pesan mentah.

Tabel sumber dan tabel sink

Catatan

Parameter ini hanya didukung di Ververica Runtime (VVR) 11.4 dan versi setelahnya.

Opsi konektor

  • Umum

    Opsi

    Deskripsi

    Tipe

    Wajib

    Default

    Keterangan

    connector

    Jenis connector.

    String

    Ya

    Nilainya harus kafka.

    properties.bootstrap.servers

    Daftar alamat broker Kafka.

    String

    Ya

    Format: host1:port1,host2:port2,.... Pisahkan alamat dengan koma (,).

    properties.*

    Properti tambahan untuk klien Kafka.

    String

    Tidak

    Kunci properti harus merupakan opsi valid yang ditentukan dalam dokumentasi resmi Apache Kafka untuk Producer Configs dan Consumer Configs.

    Realtime Compute for Apache Flink menghapus prefiks properties. dan meneruskan pasangan kunci-nilai yang tersisa ke klien Kafka yang mendasari. Misalnya, Anda dapat mengatur 'properties.allow.auto.create.topics' = 'false' untuk menonaktifkan pembuatan topik otomatis.

    Kafka connector menimpa opsi-opsi ini, sehingga Anda tidak dapat mengonfigurasinya dengan cara ini:

    • key.deserializer

    • value.deserializer

    format

    Format untuk serialisasi dan deserialisasi nilai pesan Kafka.

    String

    Tidak

    Format yang didukung:

    • csv

    • json

    • avro

    • debezium-json

    • canal-json

    • maxwell-json

    • avro-confluent

    • raw

    Catatan

    Untuk informasi lebih lanjut, lihat Opsi format.

    key.format

    Format untuk serialisasi dan deserialisasi kunci pesan Kafka.

    String

    Tidak

    Format yang didukung:

    • csv

    • json

    • avro

    • debezium-json

    • canal-json

    • maxwell-json

    • avro-confluent

    • raw

    Catatan

    Saat Anda menggunakan konfigurasi ini, key.options wajib diisi.

    key.fields

    Field dari skema tabel yang akan digunakan sebagai kunci pesan Kafka.

    String

    Tidak

    Pisahkan beberapa nama field dengan titik koma (;). Misalnya, 'field1;field2'.

    key.fields-prefix

    Awalan kustom untuk semua field kunci guna mencegah konflik nama dengan field nilai.

    String

    Tidak

    Awalan ini digunakan untuk membedakan antara field kunci dan field nilai. Awalan ini dihapus sebelum serialisasi kunci atau setelah deserialisasi.

    Catatan

    Jika Anda menggunakan opsi ini, value.fields-include harus diatur ke EXCEPT_KEY.

    value.format

    Format untuk serialisasi dan deserialisasi nilai pesan Kafka.

    String

    Tidak

    Konfigurasi ini setara dengan format. Anda hanya dapat mengatur salah satu dari format atau value.format. Jika keduanya dikonfigurasi, value.format menggantikan format.

    value.fields-include

    Menentukan apakah field kunci disertakan dalam format nilai.

    String

    Tidak

    ALL

    Nilai yang valid:

    • ALL: Nilai pesan Kafka mencakup semua kolom tabel.

    • EXCEPT_KEY: Nilai pesan Kafka mencakup semua kolom tabel kecuali yang ditentukan dalam key.fields.

  • Tabel sumber

    Opsi

    Deskripsi

    Tipe

    Wajib

    Default

    Keterangan

    topic

    Topik atau topik-topik yang akan dibaca.

    String

    Tidak

    Untuk berlangganan ke beberapa topik, pisahkan nama-namanya dengan titik koma (;), misalnya, 'topic-1;topic-2'.

    Catatan

    Anda dapat menentukan salah satu opsi ini atau topic-pattern, tetapi tidak keduanya.

    topic-pattern

    Ekspresi reguler yang cocok dengan topik yang akan dilanggan. Konsumen berlangganan ke semua topik yang namanya cocok dengan pola ini.

    String

    Tidak

    Contoh:

    • user_event_.*: Cocok dengan semua topik yang diawali dengan user_event_.

    • prod\.logs\..*: Cocok dengan topik yang diawali dengan prod.logs. (karakter . harus di-escape).

    Catatan

    Anda dapat menentukan salah satu opsi ini atau topic, tetapi tidak keduanya.

    properties.group.id

    ID kelompok konsumen sumber Kafka.

    String

    Tidak

    KafkaSource-{Nama-Tabel-Sumber}

    Jika Anda menggunakan ID kelompok konsumen untuk pertama kalinya, Anda juga harus mengatur properties.auto.offset.reset ke earliest atau latest untuk menentukan offset startup awal.

    scan.startup.mode

    Offset startup konsumen Kafka.

    String

    Tidak

    group-offsets

    Nilai yang valid:

    • earliest-offset: Mulai membaca dari offset paling awal yang tersedia.

    • latest-offset: Mulai membaca dari offset terbaru.

    • group-offsets: Mulai membaca dari offset yang telah di-commit dari properties.group.id yang ditentukan.

    • timestamp: Mulai membaca dari scan.startup.timestamp-millis yang ditentukan.

    • specific-offsets: Mulai membaca dari offset yang ditentukan dalam scan.startup.specific-offsets.

    Catatan

    Opsi ini hanya berlaku saat pekerjaan dimulai tanpa state. Jika pekerjaan dilanjutkan dari checkpoint, pekerjaan membaca dari offset yang disimpan dalam state checkpoint.

    scan.startup.specific-offsets

    Offset awal per-partisi saat scan.startup.mode adalah specific-offsets.

    String

    Tidak

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

    scan.startup.timestamp-millis

    Timestamp awal dalam milidetik saat scan.startup.mode diatur ke timestamp.

    Long

    Tidak

    Unitnya adalah milidetik.

    scan.topic-partition-discovery.interval

    Interval penemuan partisi.

    Duration

    Tidak

    5 menit

    Connector secara berkala menemukan dan membaca dari partisi baru. Saat Anda menggunakan topic-pattern, connector juga menemukan topik baru yang cocok dengan pola tersebut. Atur interval ke nilai non-positif untuk menonaktifkan fitur ini.

    Catatan

    Di Ververica Runtime (VVR) 6.0.x, penemuan partisi dinamis dinonaktifkan secara default. Mulai dari VVR 8.0, fitur ini diaktifkan secara default dengan interval penemuan 5 menit.

    scan.header-filter

    Memfilter pesan berdasarkan header pesan Kafka.

    String

    Tidak

    Kunci header dan nilainya dipisahkan oleh titik dua (:). Beberapa kondisi header dihubungkan menggunakan operator logika (& dan |). Operator logika NOT (!) juga didukung. Misalnya, depart:toy|depart:book&!env:test menyimpan data Kafka jika header berisi depart=toy atau depart=book dan tidak berisi env=test.

    Catatan
    • Opsi ini hanya didukung di Ververica Runtime (VVR) 8.0.6 dan versi setelahnya.

    • Tanda kurung dalam ekspresi tidak didukung.

    • Operasi logika dievaluasi dari kiri ke kanan.

    • Nilai header dikonversi ke string UTF-8 untuk perbandingan.

    scan.check.duplicated.group.id

    Memeriksa apakah sudah ada konsumen aktif lain yang menggunakan properties.group.id.

    Boolean

    Tidak

    false

    Nilai yang valid:

    • true: Sebelum memulai pekerjaan, sistem memeriksa duplikasi kelompok konsumen. Jika ditemukan, pekerjaan gagal untuk mencegah konflik.

    • false: Memulai pekerjaan tanpa memeriksa konflik.

    Catatan

    Opsi ini hanya didukung di Ververica Runtime (VVR) 6.0.4 dan versi setelahnya.

  • Tabel sink

    Opsi

    Deskripsi

    Tipe

    Wajib

    Default

    Keterangan

    topic

    Topik tujuan.

    String

    Ya

    sink.partitioner

    Memetakan record dari instance sink paralel ke partisi Kafka.

    String

    Tidak

    default

    Nilai yang valid:

    • default: Menggunakan partitioner Kafka default.

    • fixed: Setiap instance sink paralel menulis ke partisi Kafka tetap.

    • round-robin: Record didistribusikan ke partisi secara round-robin.

    • Partitioner kustom: Untuk menggunakan partitioner kustom, berikan nama kelas lengkap dari subclass FlinkKafkaPartitioner, misalnya, org.mycompany.MyPartitioner.

    sink.delivery-guarantee

    Jaminan pengiriman sink.

    String

    Tidak

    at-least-once

    Nilai yang valid:

    • none: Tidak memberikan jaminan. Record dapat hilang atau diduplikasi.

    • at-least-once: Menjamin tidak ada record yang hilang, tetapi mungkin terduplikasi.

    • exactly-once: Menggunakan transaksi Kafka untuk memberikan semantik tepat-sekali, memastikan record tidak hilang maupun terduplikasi.

    Catatan

    Saat menggunakan semantik exactly-once, Anda juga harus menentukan sink.transactional-id-prefix.

    sink.transactional-id-prefix

    Awalan ID transaksi. Diperlukan saat sink.delivery-guarantee adalah exactly-once.

    String

    Ya, jika sink.delivery-guarantee adalah exactly-once

    Hanya diperlukan saat sink.delivery-guarantee diatur ke exactly-once.

    sink.parallelism

    Paralelisme operator sink.

    Integer

    Tidak

    Secara default, framework menentukan paralelisme berdasarkan operator hulu.

Keamanan dan otentikasi

Jika kluster Kafka memerlukan koneksi aman atau otentikasi, tambahkan prefiks konfigurasi keamanan dan otentikasi terkait dengan properties. dan atur di parameter WITH. Contoh berikut mengonfigurasi tabel Kafka untuk menggunakan PLAIN sebagai mekanisme SASL dengan konfigurasi 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";'
)

Contoh berikut menunjukkan cara menggunakan SASL_SSL sebagai protokol keamanan dan SCRAM-SHA-256 sebagai mekanisme SASL.

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',
  /* Konfigurasi SSL */
  /* Path ke truststore untuk sertifikat CA server. */
  /* File yang diunggah menggunakan Artifacts disimpan di direktori /flink/usrlib/. */
  'properties.ssl.truststore.location' = '/flink/usrlib/kafka.client.truststore.jks',
  'properties.ssl.truststore.password' = 'test1234',
  /* Jika otentikasi klien diperlukan, Anda juga harus mengonfigurasi path ke keystore (kunci privat). */
  'properties.ssl.keystore.location' = '/flink/usrlib/kafka.client.keystore.jks',
  'properties.ssl.keystore.password' = 'test1234',
  /* Algoritma yang digunakan untuk memverifikasi hostname server. String kosong menonaktifkan verifikasi hostname. */
  'properties.ssl.endpoint.identification.algorithm' = '',
  /* Konfigurasi SASL */
  /* Atur mekanisme SASL ke SCRAM-SHA-256. */
  'properties.sasl.mechanism' = 'SCRAM-SHA-256',
  /* Konfigurasi JAAS. */
  'properties.sasl.jaas.config' = 'org.apache.flink.kafka.shaded.org.apache.kafka.common.security.scram.ScramLoginModule required username="username" password="password";'
)

Anda dapat menggunakan fitur Artifacts di konsol Realtime Compute for Apache Flink untuk mengunggah sertifikat CA dan kunci privat yang disebutkan dalam contoh. File yang diunggah disimpan di direktori /flink/usrlib. Untuk menggunakan file sertifikat CA bernama my-truststore.jks, Anda dapat mengatur properti 'properties.ssl.truststore.location' di klausa WITH dengan salah satu dari dua cara berikut:

  • Atur 'properties.ssl.truststore.location' = '/flink/usrlib/my-truststore.jks'. Metode ini menghindari pengunduhan file secara dinamis dari Object Storage Service (OSS) saat runtime, tetapi tidak mendukung Mode Debug.

  • Jika versi mesin Realtime Compute adalah VVR 11.5 atau versi setelahnya, Anda dapat mengonfigurasi properties.ssl.truststore.location dan properties.ssl.keystore.location ke path OSS absolut. Format path file adalah oss://flink-fullymanaged-<ID Ruang Kerja>/artifacts/namespaces/<Nama Namespace>/<nama file>. Metode ini mengunduh file OSS secara dinamis selama runtime Flink dan mendukung Mode Debug.

Catatan
  • Verifikasi konfigurasi Anda: Contoh dalam topik ini menunjukkan konfigurasi umum. Sebelum mengonfigurasi Kafka connector, hubungi tim O&M Kafka Anda untuk mendapatkan pengaturan keamanan dan otentikasi yang benar.

  • Escape karakter: Berbeda dengan Apache Flink asli, editor SQL Realtime Compute for Apache Flink secara default melakukan escape tanda kutip ganda (") . Oleh karena itu, Anda tidak perlu menambahkan backslash (\) untuk melakukan escape tanda kutip ganda yang digunakan untuk username dan password dalam opsi properties.sasl.jaas.config.

Offset awal tabel sumber

Mode startup

Anda dapat mengonfigurasi opsi scan.startup.mode untuk menentukan offset dari mana tabel sumber Kafka mulai membaca data. Nilai yang valid meliputi:

  • earliest-offset: Mulai membaca dari offset paling awal.

  • latest-offset: Mulai membaca dari offset terbaru.

  • group-offsets: Mulai membaca dari offset yang telah di-commit untuk kelompok konsumen yang ditentukan dalam properties.group.id.

  • timestamp: Mulai membaca dari pesan pertama dengan timestamp lebih besar dari atau sama dengan nilai yang ditentukan dalam scan.startup.timestamp-millis.

  • specific-offsets: Mulai membaca dari offset partisi tertentu yang ditentukan dalam scan.startup.specific-offsets.

Catatan
  • Jika Anda tidak menentukan mode startup, default-nya adalah 'group-offsets'.

  • Opsi scan.startup.mode hanya berlaku untuk pekerjaan tanpa status. Saat pekerjaan berstatus dimulai, pekerjaan selalu mengonsumsi dari offset yang disimpan dalam statenya.

Contoh:

CREATE TEMPORARY TABLE kafka_source (
  ...
) WITH (
  'connector' = 'kafka',
  ...
  -- Mengonsumsi dari offset paling awal.
  'scan.startup.mode' = 'earliest-offset',
  -- Mengonsumsi dari offset terbaru.
  'scan.startup.mode' = 'latest-offset',
  -- Mengonsumsi dari offset yang telah di-commit kelompok konsumen "my-group".
  'properties.group.id' = 'my-group',
  'scan.startup.mode' = 'group-offsets',
  'properties.auto.offset.reset' = 'earliest', -- Jika "my-group" digunakan pertama kali, konsumsi dimulai dari offset paling awal.
  'properties.auto.offset.reset' = 'latest', -- Jika "my-group" digunakan pertama kali, konsumsi dimulai dari offset terbaru.
  -- Mengonsumsi dari timestamp tertentu dalam milidetik: 1655395200000.
  'scan.startup.mode' = 'timestamp',
  'scan.startup.timestamp-millis' = '1655395200000',
  -- Mengonsumsi dari offset tertentu.
  'scan.startup.mode' = 'specific-offsets',
  'scan.startup.specific-offsets' = 'partition:0,offset:42;partition:1,offset:300'
);

Prioritas offset awal

Offset awal tabel sumber ditentukan oleh aturan berikut, berdasarkan prioritas:

Prioritas (tertinggi ke terendah)

Offset yang disimpan dalam checkpoint atau titik simpan.

Waktu mulai yang dipilih di konsol Realtime Compute for Apache Flink saat startup pekerjaan.

Offset awal yang ditentukan oleh scan.startup.mode di klausa WITH.

Jika scan.startup.mode tidak ditentukan, group-offsets digunakan untuk memulai konsumsi dari offset kelompok konsumen yang sesuai.

Jika offset yang ditentukan oleh langkah-langkah ini tidak valid, misalnya karena telah kedaluwarsa atau terjadi masalah di kluster Kafka, sistem mereset offset sesuai kebijakan yang ditentukan dalam properties.auto.offset.reset. Jika opsi ini tidak dikonfigurasi, sistem melemparkan exception yang memerlukan intervensi pengguna.

Skenario umum melibatkan memulai konsumsi dengan ID kelompok konsumen baru. Tabel sumber pertama kali menanyakan kluster Kafka untuk offset yang telah di-commit kelompok tersebut. Karena ID kelompok baru, tidak ditemukan offset yang valid. Akibatnya, sistem mereset offset sesuai kebijakan yang ditentukan dalam properties.auto.offset.reset. Oleh karena itu, saat mengonsumsi dengan ID kelompok baru, Anda harus mengonfigurasi opsi properties.auto.offset.reset.

Menyimpan offset sumber

Tabel sumber Kafka hanya melakukan commit offset konsumennya ke kluster Kafka setelah checkpoint berhasil, sehingga interval checkpoint yang panjang menyebabkan offset yang di-commit tertinggal. Tabel sumber menyimpan progres bacaan aktual dalam state checkpoint, yang digunakan sistem untuk pemulihan kesalahan. Offset yang di-commit hanya berfungsi sebagai monitor progres dan tidak digunakan untuk pemulihan, sehingga kegagalan commit tidak memengaruhi akurasi data.

Pemartisi sink kustom

Jika strategi partisi bawaan Kafka tidak memenuhi kebutuhan Anda, Anda dapat mengimplementasikan partitioner kustom dengan memperluas kelas FlinkKafkaPartitioner. Setelah pengembangan selesai, kompilasi kode Anda menjadi paket JAR dan unggah menggunakan fitur Artifacts di konsol Realtime Compute. Setelah paket JAR diunggah dan dirujuk, atur parameter sink.partitioner di klausa WITH ke nama kelas lengkap partitioner Anda, misalnya, org.mycompany.MyPartitioner.

Kafka, Upsert Kafka, dan katalog JSON Kafka

Kafka adalah platform streaming event yang hanya menambahkan data dan tidak mendukung pembaruan atau penghapusan data. Di SQL streaming, tabel sink Kafka standar tidak dapat menangani data Change Data Capture (CDC) hulu atau logika retraction dari operator seperti agregat dan join. Jika Anda perlu menulis data yang berisi perubahan atau retraction, gunakan tabel sink Upsert Kafka.

Untuk menyederhanakan sinkronisasi batch data Change Data Capture (CDC) dari satu atau beberapa tabel database hulu ke Kafka, Anda dapat menggunakan katalog JSON Kafka. Jika data yang disimpan di Kafka dalam format JSON, katalog JSON Kafka memungkinkan Anda melewati langkah mendefinisikan skema dan parameter WITH. Untuk detailnya, lihat Kelola katalog JSON Kafka.

Contoh

Contoh 1: Membaca dari dan menulis ke Kafka

Contoh ini membaca data dari topik sumber Kafka dan menulisnya ke topik sink. Data dalam format 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;

Contoh 2: Menyinkronkan skema dan data tabel

Anda dapat menggunakan Kafka connector untuk menyinkronkan pesan dari topik Kafka ke Hologres secara real time. Untuk mencegah pesan duplikat di Hologres selama failover, Anda dapat menggunakan offset dan ID partisi pesan Kafka sebagai kunci primer komposit.

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'
    -- Opsional. Meratakan semua kolom bersarang.
);

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

Contoh 3: Menyinkronkan kunci dan nilai Kafka

Jika kunci pesan Kafka berisi informasi relevan, Anda dapat menyinkronkan kunci dan nilai tersebut.

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;
Catatan

Kunci pesan Kafka tidak mendukung Evolusi Skema atau penguraian tipe otomatis. Anda harus mendeklarasikan skema secara manual.

Contoh 4: Menyinkronkan data dan melakukan komputasi

Saat menyinkronkan data dari Kafka ke Hologres, Anda mungkin memerlukan transformasi ringan.

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');
--Gunakan COALESCE untuk menangani nilai null.

Contoh 5: Mengurai JSON bersarang

Berikut adalah contoh pesan JSON:

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

Untuk menghindari penggunaan fungsi seperti JSON_VALUE(payload, '$.properties.owner') untuk mengurai field, Anda dapat langsung mendefinisikan struktur dalam DDL Sumber:

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'
);

Dengan pendekatan ini, Flink mengurai JSON menjadi field terstruktur selama fase pembacaan. Kueri SQL selanjutnya dapat langsung mereferensikan properties.owner tanpa panggilan fungsi tambahan, yang meningkatkan kinerja keseluruhan.

DataStream API

Penting

Untuk membaca atau menulis data dengan API DataStream, gunakan DataStream Connector yang sesuai untuk menghubungkan ke Realtime Compute for Apache Flink. Untuk informasi lebih lanjut tentang cara menyiapkan DataStream Connector, lihat Integrasikan konektor DataStream.

  • Membuat sumber Kafka

    Kafka Source menyediakan kelas builder untuk membuat instance Kafka Source. Kode contoh berikut membangun Kafka Source yang mengonsumsi data dari Offset paling awal dari topik input-topic. Kelompok Konsumen adalah my-group, dan Nilai Pesan Kafka dideserialisasi sebagai string.

    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");

    Untuk membangun Kafka Source, Anda harus menentukan properti berikut.

    Parameter

    Deskripsi

    BootstrapServers

    Daftar alamat broker Kafka. Atur properti ini dengan memanggil metode setBootstrapServers(String).

    GroupId

    ID Kelompok Konsumen. Atur properti ini dengan memanggil metode setGroupId(String).

    Topik atau Partisi

    Topik atau partisi untuk berlangganan. Kafka Source mendukung tiga metode berikut untuk berlangganan ke topik atau partisi:

    • Berlangganan ke semua partisi topik dalam daftar.

      KafkaSource.builder().setTopics("topic-a","topic-b")
    • Pola topik: Berlangganan ke semua partisi topik yang namanya cocok dengan ekspresi reguler yang ditentukan.

      KafkaSource.builder().setTopicPattern("topic.*")
    • Daftar partisi, tempat Anda dapat berlangganan ke partisi tertentu.

      final HashSet<TopicPartition> partitionSet = new HashSet<>(Arrays.asList(
              new TopicPartition("topic-a", 0),    // Partisi 0 dari topik "topic-a"
              new TopicPartition("topic-b", 5)));  // Partisi 5 dari topik "topic-b"
      KafkaSource.builder().setPartitions(partitionSet)

    Deserializer

    Deserializer yang digunakan untuk mengurai pesan Kafka.

    Tentukan deserializer menggunakan metode setDeserializer(KafkaRecordDeserializationSchema). KafkaRecordDeserializationSchema mendefinisikan cara mengurai ConsumerRecord Kafka. Jika Anda hanya perlu mengurai Nilai Pesan Kafka, Anda dapat menggunakan salah satu metode berikut:

    • Gunakan metode setValueOnlyDeserializer(DeserializationSchema) dari kelas builder. DeserializationSchema mendefinisikan cara mengurai data biner Nilai Pesan Kafka.

    • Gunakan kelas yang mengimplementasikan antarmuka Deserializer Kafka. Misalnya, Anda dapat menggunakan StringDeserializer untuk mengurai Nilai Pesan Kafka menjadi string.

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

    Untuk mengurai ConsumerRecord lengkap, Anda harus mengimplementasikan antarmuka KafkaRecordDeserializationSchema.

    POM

    Kafka DataStream Connector tersedia di repositori pusat Maven.

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

    Saat menggunakan DataStream Connector Kafka, pertimbangkan properti berikut:

    • Offset awal

      Kafka Source menentukan offset awal-nya menggunakan initializer offset (OffsetsInitializer). Initializer bawaan meliputi:

      Offset Initializer

      Kode

      Memulai konsumsi dari Offset paling awal.

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

      Memulai konsumsi dari Offset terbaru.

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

      Memulai konsumsi data yang timestamp-nya lebih besar dari atau sama dengan waktu yang ditentukan. Unitnya adalah milidetik.

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

      Memulai konsumsi dari Offset yang telah di-commit Kelompok Konsumen. Jika tidak ada Offset yang telah di-commit, menggunakan strategi reset yang ditentukan (misalnya, Offset paling awal).

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

      Konsumsi dimulai dari offset yang di-commit oleh kelompok konsumen, dan tidak ada kebijakan reset offset yang ditentukan.

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

      Catatan
      • Jika initializer bawaan tidak memenuhi kebutuhan Anda, Anda dapat mengimplementasikan initializer offset kustom.

      • Jika Anda tidak menentukan initializer offset, default-nya adalah OffsetsInitializer.earliest().

    • Mode streaming dan mode batch

      Kafka Source mendukung mode streaming dan Mode Batch. Secara default, beroperasi dalam mode streaming, di mana Pekerjaan berjalan tanpa batas hingga gagal atau dibatalkan. Untuk mengonfigurasi Kafka Source agar berjalan dalam Mode Batch, Anda dapat menggunakan setBounded(OffsetsInitializer) untuk menentukan offset berhenti. Kafka Source berhenti ketika semua partisi mencapai offset berhenti yang ditentukan.

      Catatan

      Kafka Source dalam mode streaming biasanya tidak memiliki offset berhenti. Namun, untuk tujuan pengujian, Anda dapat menggunakan setUnbounded(OffsetsInitializer) untuk menentukan offset berhenti bahkan dalam mode streaming. Perhatikan nama metode yang berbeda untuk menentukan offset berhenti: setUnbounded untuk mode streaming dan setBounded untuk Mode Batch.

    • Penemuan partisi dinamis

      Untuk menangani penskalaan Topik atau pembuatan topik baru tanpa me-restart Pekerjaan Flink, Anda dapat mengaktifkan Penemuan partisi dinamis saat berlangganan ke topik berdasarkan pola. Fitur ini dinonaktifkan secara default dan harus diaktifkan secara eksplisit:

      KafkaSource.builder()
          .setProperty("partition.discovery.interval.ms", "10000") // Temukan partisi baru setiap 10 detik.
      Penting

      Fitur penemuan partisi dinamis bergantung pada mekanisme pembaruan metadata kluster Kafka. Jika kluster Kafka tidak memperbarui informasi partisi secara tepat waktu, partisi baru mungkin tidak ditemukan. Pastikan konfigurasi partition.discovery.interval.ms kluster Kafka sesuai dengan skenario aktual Anda.

    • Waktu event dan watermark

      Secara default, Kafka Source menggunakan timestamp dari Pesan Kafka sebagai Waktu Event. Anda dapat mendefinisikan strategi Watermark kustom untuk mengekstrak Waktu Event dari isi Pesan dan mengirimkan Watermark ke hulu.

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

      Untuk mempelajari lebih lanjut tentang strategi Watermark kustom, lihat Generating Watermarks.

      Catatan

      Jika subtugas sumber menganggur—misalnya, ketika Partisi Kafka tidak memiliki data baru atau Paralelisme sumber lebih tinggi daripada jumlah partisi Kafka—Watermark untuk subtugas tersebut tidak akan maju, sehingga dapat menghambat komputasi jendela di hilir.

      Untuk mengatasi masalah ini, pertimbangkan solusi berikut:

      • Konfigurasi timeout idle sumber: Aktifkan properti table.exec.source.idle-timeout untuk menandai sumber idle sebagai sementara idle. Hal ini memungkinkan Watermark di hulu maju.

      • Atur Paralelisme yang sesuai: Pastikan Paralelisme sumber tidak lebih besar daripada jumlah partisi Kafka.

    • Offset commit

      Saat checkpoint diaktifkan, Kafka Source melakukan commit Offset konsumen saat ini ke Kafka ketika Checkpoint selesai. Hal ini memastikan state Checkpoint Flink konsisten dengan Offset yang di-commit di broker Kafka. Jika checkpoint dinonaktifkan, Kafka Source mengandalkan mekanisme commit periodik otomatis internal konsumen Kafka. Fitur ini dikontrol oleh properti konsumen Kafka enable.auto.commit dan auto.commit.interval.ms.

      Catatan

      Kafka Source tidak mengandalkan offset yang di-commit untuk toleransi kesalahan dan pemulihan. Commit offset hanya untuk memantau progres konsumen Kafka dan Kelompok Konsumen.

    • Properti lainnya

      Selain properti yang disebutkan, Anda dapat menggunakan setProperties(Properties) dan setProperty(String, String) untuk mengatur properti apa pun untuk Kafka Source dan konsumen Kafka yang mendasarinya. Kafka Source menyediakan properti spesifik berikut.

      Parameter

      Deskripsi

      client.id.prefix

      Awalan ID klien untuk konsumen Kafka.

      partition.discovery.interval.ms

      Interval penemuan partisi dalam milidetik. Nilai -1 menonaktifkan penemuan partisi dinamis.

      Catatan

      Di Mode Batch, properti ini secara otomatis diatur ke -1.

      register.consumer.metrics

      Mendaftarkan metrik konsumen Kafka di Flink.

      Konfigurasi Konsumen Kafka Lainnya

      Untuk daftar lengkap konfigurasi konsumen Kafka, lihat dokumentasi resmi Apache Kafka.

      Penting

      Untuk memastikan operasi yang benar, DataStream Connector Kafka menimpa properti yang dikonfigurasi secara manual berikut:

      • key.deserializer selalu ditimpa ke org.apache.kafka.common.serialization.ByteArrayDeserializer.

      • value.deserializer selalu ditimpa ke org.apache.kafka.common.serialization.ByteArrayDeserializer.

      • auto.offset.reset.strategy ditimpa oleh strategi yang disediakan oleh OffsetsInitializer.

      Contoh berikut menunjukkan cara mengonfigurasi konsumen Kafka untuk menggunakan mekanisme SASL PLAIN dan menyediakan konfigurasi JAAS.

      KafkaSource.builder()
          .setProperty("sasl.mechanism", "PLAIN")
          .setProperty("sasl.jaas.config", "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"username\" password=\"password\";")
    • Pemantauan

      Kafka Source mengekspos metrik melalui sistem metrik Flink untuk pemantauan dan diagnostik.

      • Ruang lingkup metrik

        Semua metrik untuk pembaca sumber Kafka didaftarkan di bawah grup metrik KafkaSourceReader, yang merupakan subgrup dari grup metrik operator. Metrik yang terkait dengan partisi topik tertentu didaftarkan di subgrup KafkaSourceReader.topic.<topic_name>.partition.<partition_id>.

        Misalnya, metrik Offset Konsumen saat ini (currentOffset) untuk Partisi 1 topik "my-topic" tersedia di .operator.KafkaSourceReader.topic.my-topic.partition.1.currentOffset. Jumlah commit yang berhasil (commitsSucceeded) tersedia di .operator.KafkaSourceReader.commitsSucceeded.

      • Daftar metrik

        Metrik

        Deskripsi

        Ruang Lingkup

        currentOffset

        Offset konsumen saat ini dari partisi.

        TopicPartition

        committedOffset

        Offset terakhir yang di-commit untuk partisi.

        TopicPartition

        commitsSucceeded

        Jumlah total commit offset yang berhasil.

        KafkaSourceReader

        commitsFailed

        Jumlah commit yang gagal

        KafkaSourceReader

      • Metrik konsumen Kafka

        Metrik konsumen Kafka yang mendasari didaftarkan di grup metrik KafkaSourceReader.KafkaConsumer. Misalnya, metrik records-consumed-total didaftarkan di .operator.KafkaSourceReader.KafkaConsumer.records-consumed-total.

        Anda dapat menggunakan properti register.consumer.metrics untuk menentukan apakah akan mendaftarkan metrik konsumen Kafka. Opsi ini diaktifkan secara default (true). Untuk informasi lebih lanjut tentang metrik konsumen Kafka, lihat dokumentasi Apache Kafka.

  • Membuat sink Kafka

    Sink Kafka Flink menulis aliran data ke satu atau beberapa topik 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);

    Untuk membangun Kafka Sink, Anda harus mengonfigurasi properti berikut.

    Parameter

    Deskripsi

    Properti klien Kafka

    Properti bootstrap.servers wajib diisi. Properti ini menentukan daftar broker Kafka yang dipisahkan koma.

    Serializer rekaman

    Anda harus menyediakan KafkaRecordSerializationSchema untuk mengonversi data input menjadi ProducerRecord Kafka. Flink menyediakan builder skema yang menawarkan komponen umum, seperti serialisasi untuk kunci dan nilai pesan, pemilihan topik, dan partisi pesan. Anda juga dapat mengimplementasikan antarmuka yang sesuai untuk kontrol lebih rinci. Metode ProducerRecord<byte[], byte[]> serialize(T element, KafkaSinkContext context, Long timestamp) dipanggil untuk setiap record yang masuk untuk menghasilkan ProducerRecord yang akan ditulis ke Kafka.

    ProducerRecord memberikan kontrol rinci tentang cara setiap record ditulis ke Kafka, memungkinkan Anda untuk:

    • Menetapkan Topik tujuan.

    • Atur Message Key.

    • Tentukan Partition tujuan.

    Jaminan pengiriman

    Parameter bootstrap.servers wajib diisi dan menentukan daftar broker Kafka yang dipisahkan koma.

    Jaminan pengiriman

    Saat checkpoint Flink diaktifkan, Flink Kafka Sink dapat memberikan semantik tepat-sekali. Selain mengaktifkan checkpoint, Anda dapat menggunakan parameter DeliveryGuarantee untuk menentukan jaminan pengiriman yang berbeda. Parameter DeliveryGuarantee menyediakan opsi berikut:

    • DeliveryGuarantee.NONE: (Default) Flink tidak memberikan jaminan. Data dapat hilang atau terduplikasi.

    • DeliveryGuarantee.AT_LEAST_ONCE: Menjamin tidak ada data yang hilang, tetapi duplikasi mungkin terjadi.

    • DeliveryGuarantee.EXACTLY_ONCE: Menggunakan transaksi Kafka untuk memberikan semantik tepat-sekali.

      Catatan

      Saat menggunakan semantik EXACTLY_ONCE, lihat Pertimbangan untuk semantik tepat-sekali.

Flink CDC

Gunakan Kafka connector sebagai sumber atau sink untuk membuat pekerjaan YAML untuk Flink CDC.

Batasan

  • Gunakan Realtime Compute for Apache Flink (VVR) 11.1 atau versi setelahnya untuk mengingesti data Flink CDC dari sumber data Kafka.

  • Hanya JSON, Debezium JSON, dan Canal JSON yang didukung.

  • Hanya Realtime Compute for Apache Flink (VVR) 8.0.11 dan versi setelahnya yang mendukung pembacaan data dari tabel tunggal yang didistribusikan di beberapa Partisi.

Sintaks

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

Parameter

  • Umum

    Parameter

    Deskripsi

    Wajib

    Tipe

    Default

    Keterangan

    type

    Jenis sumber atau sink.

    Ya

    String

    Nilainya harus kafka.

    name

    Nama sumber atau sink.

    Tidak

    String

    Tidak ada

    properties.bootstrap.servers

    Alamat broker Kafka.

    Ya

    String

    Formatnya adalah host1:port1,host2:port2,host3:port3, dipisahkan koma (,).

    properties.*

    Properti konfigurasi untuk klien Kafka.

    Tidak

    String

    Kunci properti harus merupakan opsi valid sebagaimana ditentukan dalam dokumentasi resmi Apache Kafka untuk Producer Configs dan Consumer Configs.

    Realtime Compute for Apache Flink (VVR) menghapus prefiks properties. sebelum meneruskan pasangan kunci-nilai yang tersisa ke klien Kafka yang mendasari. Misalnya, atur 'properties.allow.auto.create.topics' = 'false' untuk menonaktifkan pembuatan topik otomatis.

    key.format

    Format serialisasi dan deserialisasi kunci pesan Kafka.

    Tidak

    String

    • Untuk sumber, hanya format json yang didukung.

    • Untuk sink, nilai yang valid adalah:

      • csv

      • json

    Catatan

    Opsi ini hanya didukung di Realtime Compute for Apache Flink (VVR) 11.0.0 dan versi setelahnya.

    value.format

    Format serialisasi dan deserialisasi nilai pesan Kafka.

    Tidak

    String

    debezium-json

    • Untuk sumber, nilai yang valid adalah:

      • debezium-json 

      • canal-json

      • json

    • Untuk sink, nilai yang valid adalah:

      • debezium-json 

      • canal-json

      • canal-protobuf

    Catatan
    • Format debezium-json dan canal-json memerlukan Realtime Compute for Apache Flink (VVR) versi 8.0.10 atau versi setelahnya.

    • Format json memerlukan Realtime Compute for Apache Flink (VVR) versi 11.0.0 atau versi setelahnya.

  • Parameter sumber

    Parameter

    Deskripsi

    Wajib

    Tipe

    Default

    Keterangan

    topic

    Topik atau topik-topik yang akan dibaca.

    Tidak

    String

    Untuk berlangganan ke beberapa topik, pisahkan nama-namanya dengan titik koma (;), misalnya, topic-1;topic-2.

    Catatan

    Tentukan salah satu parameter ini atau topic-pattern, tetapi tidak keduanya.

    topic-pattern

    Ekspresi reguler yang cocok dengan nama topik yang akan dilanggan.

    Tidak

    String

    Contoh:

    • user_event_.*: Cocok dengan semua topik yang diawali dengan user_event_.

    • prod\.logs\..*: Cocok dengan topik yang diawali dengan prod.logs. (karakter . harus di-escape).

    Catatan

    Tentukan salah satu parameter ini atau topic, tetapi tidak keduanya.

    properties.group.id

    ID kelompok konsumen.

    Tidak

    String

    Saat menentukan ID kelompok konsumen baru, Anda harus mengatur parameter properties.auto.offset.reset ke earliest atau latest untuk menentukan offset awal.

    scan.startup.mode

    Offset awal konsumen Kafka.

    Tidak

    String

    group-offsets

    Nilai yang valid:

    • earliest-offset: Mulai membaca dari offset paling awal yang tersedia.

    • latest-offset: Mulai membaca dari offset terbaru.

    • group-offsets (Nilai default): Mulai membaca dari offset yang telah di-commit untuk properties.group.id yang ditentukan.

    • timestamp: Mulai membaca dari timestamp yang ditentukan oleh scan.startup.timestamp-millis.

    • specific-offsets: Mulai membaca dari offset yang ditentukan oleh scan.startup.specific-offsets.

    Catatan

    Parameter ini hanya berlaku saat pekerjaan dimulai dengan startup tanpa status. Saat pekerjaan berstatus dimulai, pekerjaan selalu mengonsumsi dari offset yang disimpan dalam statenya.

    scan.startup.specific-offsets

    Offset awal per-partisi saat scan.startup.mode diatur ke specific-offsets.

    Tidak

    String

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

    scan.startup.timestamp-millis

    Timestamp awal dalam milidetik saat scan.startup.mode diatur ke timestamp.

    Tidak

    Long

    Satuannya adalah milidetik.

    scan.topic-partition-discovery.interval

    Interval untuk menemukan partisi baru secara dinamis dalam topik.

    Tidak

    Duration

    5 menit

    Connector secara berkala menemukan dan membaca dari partisi baru. Saat menggunakan topic-pattern, connector juga menemukan topik baru yang cocok dengan pola tersebut. Untuk menonaktifkan penemuan, atur nilai ini ke 0 atau kurang.

    scan.check.duplicated.group.id

    Memeriksa apakah kelompok konsumen yang ditentukan oleh properties.group.id merupakan duplikat.

    Tidak

    Boolean

    false

    Nilai yang valid:

    • true: Memeriksa duplikasi kelompok konsumen sebelum pekerjaan dimulai. Jika ditemukan duplikat, pekerjaan gagal.

    • false: Memulai pekerjaan tanpa memeriksa konflik.

    schema.inference.strategy

    Strategi penguraian skema.

    Tidak

    String

    continuous

    Nilai yang valid:

    • continuous: Mengurai skema setiap record data. Jika skema tidak kompatibel, sistem melakukan inferensi skema yang lebih luas dan menghasilkan event perubahan skema.

    • static: Melakukan penguraian skema hanya sekali saat pekerjaan dimulai. Data kemudian diurai berdasarkan skema awal ini, dan tidak ada event perubahan skema yang dihasilkan.

    Catatan

    scan.max.pre.fetch.records

    Pesan maksimum yang dikonsumsi per partisi untuk inferensi skema awal.

    Tidak

    Int

    50

    Sebelum pemrosesan data dimulai, sistem melakukan pre-fetch dan mengonsumsi jumlah pesan terbaru yang ditentukan dari setiap partisi untuk menginisialisasi skema.

    key.fields-prefix

    Awalan untuk nama field kunci pesan guna menghindari konflik nama.

    Tidak

    String

    Misalnya, jika parameter ini diatur ke key_, dan kunci pesan berisi field bernama a, nama field yang diurai menjadi key_a.

    Catatan

    Nilai key.fields-prefix tidak boleh menjadi awalan dari nilai value.fields-prefix.

    value.fields-prefix

    Awalan untuk nama field nilai pesan guna menghindari konflik nama.

    Tidak

    String

    Misalnya, jika parameter ini diatur ke value_, dan nilai pesan berisi field bernama b, nama field yang diurai menjadi value_b.

    Catatan

    Nilai value.fields-prefix tidak boleh menjadi awalan dari nilai key.fields-prefix.

    metadata.list

    Kolom metadata yang diteruskan ke sink hilir.

    Tidak

    String

    Kolom metadata yang tersedia meliputi topic, partition, offset, timestamp, timestamp-type, headers, dan leader-epoch. Pisahkan nama kolom dengan koma.

    scan.value.initial-schemas.ddls

    Pernyataan DDL yang mendefinisikan skema awal untuk tabel tertentu.

    Tidak

    String

    Gunakan titik koma (;) untuk memisahkan beberapa pernyataan DDL. Misalnya, gunakan CREATE TABLE db1.t1 (id BIGINT, name VARCHAR(10)); CREATE TABLE db1.t2 (id BIGINT); untuk menentukan skema awal untuk tabel db1.t1 dan db1.t2, masing-masing.

    Skema tabel yang ditentukan dalam DDL harus konsisten dengan tabel sink target dan mematuhi sintaks SQL Flink.

    Catatan

    Opsi konfigurasi ini hanya didukung di Ververica Runtime (VVR) 11.5 dan versi setelahnya.

    ingestion.ignore-errors

    Mengabaikan error penguraian data.

    Tidak

    Boolean

    false

    Catatan

    Opsi konfigurasi ini hanya didukung di Ververica Runtime (VVR) 11.5 dan versi setelahnya.

    ingestion.error-tolerance.max-count

    Jumlah maksimum error penguraian yang dapat ditoleransi sebelum pekerjaan gagal. Hanya berlaku saat ingestion.ignore-errors adalah true.

    Tidak

    Integer

    -1

    Parameter ini hanya berlaku saat ingestion.ignore-errors diatur ke true. Nilai -1 menunjukkan toleransi tak terbatas, artinya exception penguraian tidak akan menyebabkan pekerjaan gagal.

    Catatan

    Opsi konfigurasi ini hanya didukung di Ververica Runtime (VVR) 11.5 dan versi setelahnya.

    scan.duplicate-field.strategy

    Menentukan cara menangani nama field duplikat yang diurai dari bagian kunci dan nilai.

    Tidak

    String

    EXCEPTION

    Nilai yang valid:

    • EXCEPTION: Melemparkan exception saat field duplikat ada di kunci dan nilai. Ini adalah perilaku default di VVR 11.6 dan versi sebelumnya.

    • PREFER_KEY: Menggunakan nilai dari field kunci saat field diduplikasi.

    • PREFER_VALUE: Menggunakan nilai dari field nilai saat field diduplikasi.

    Catatan

    Opsi konfigurasi ini hanya didukung di Ververica Runtime (VVR) 11.7 dan versi setelahnya.

    • Parameter format Debezium JSON

      Parameter

      Wajib

      Tipe

      Default

      Deskripsi

      debezium-json.distributed-tables

      Tidak

      Boolean

      false

      Atur ke true jika data untuk tabel Debezium JSON tunggal didistribusikan di beberapa partisi.

      Catatan

      Opsi konfigurasi ini hanya didukung di Ververica Runtime (VVR) 8.0.11 dan versi setelahnya.

      Penting

      Memodifikasi parameter ini memerlukan startup tanpa status.

      debezium-json.schema-include

      Tidak

      Boolean

      false

      Menyertakan skema dalam pesan Debezium JSON. Ini sesuai dengan properti value.converter.schemas.enable dalam konfigurasi Debezium Kafka Connect.

      Nilai yang valid:

      • true: Pesan Debezium JSON berisi skema.

      • false: Pesan Debezium JSON tidak berisi skema.

      debezium-json.ignore-parse-errors

      Tidak

      Boolean

      false

      Nilai yang valid:

      • true: Melewatkan baris yang menyebabkan exception penguraian.

      • false: Melemparkan error dan pekerjaan gagal.

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

      Tidak

      Boolean

      false

      Mengurai semua tipe primitif sebagai String saat mengurai skema tabel.

      Nilai yang valid:

      • true: Mengurai semua tipe primitif sebagai String.

      • false: Mengurai tipe berdasarkan aturan default.

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

      Tidak

      Boolean

      true

      Menentukan apakah akan melakukan inferensi field string sebagai TIME, DATE, atau TIMESTAMP. Jika Anda mengatur parameter ini ke false, connector melewatkan inferensi ini dan menyimpan field sebagai STRING.

      Catatan

      Parameter ini hanya didukung di Ververica Runtime (VVR) 11.8 dan versi setelahnya.

    • Parameter format Canal JSON

      Parameter

      Wajib

      Tipe

      Default

      Deskripsi

      canal-json.distributed-tables

      Tidak

      Boolean

      false

      Jika data untuk tabel tunggal dalam Canal JSON didistribusikan di beberapa partisi, Anda harus mengaktifkan opsi ini.

      Catatan

      Opsi konfigurasi ini hanya didukung di Ververica Runtime (VVR) 8.0.11 dan versi setelahnya.

      Penting

      Memodifikasi parameter ini memerlukan startup tanpa status.

      canal-json.database.include

      Tidak

      String

      Ekspresi reguler opsional untuk memfilter changelog berdasarkan field metadata database dalam record Canal. Hanya record dari database yang cocok yang diproses. Ekspresi reguler kompatibel dengan kelas Pattern Java.

      canal-json.table.include

      Tidak

      String

      Ekspresi reguler opsional untuk memfilter changelog berdasarkan field metadata table dalam record Canal. Hanya record dari tabel yang cocok yang diproses. Ekspresi reguler kompatibel dengan kelas Pattern Java.

      canal-json.ignore-parse-errors

      Tidak

      Boolean

      false

      Nilai yang valid:

      • true: Melewatkan baris saat ini jika terjadi exception penguraian.

      • false: Melemparkan error dan pekerjaan gagal dimulai.

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

      Tidak

      Boolean

      false

      Mengurai semua tipe primitif sebagai String saat mengurai skema tabel.

      Nilai yang valid:

      • true: Mengurai semua tipe primitif sebagai String.

      • false: Mengurai tipe berdasarkan aturan default.

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

      Tidak

      Boolean

      true

      Menentukan apakah akan melakukan inferensi field string sebagai TIME, DATE, atau TIMESTAMP. Jika Anda mengatur parameter ini ke false, connector melewatkan inferensi ini dan menyimpan field sebagai STRING.

      Catatan

      Parameter ini hanya didukung di Ververica Runtime (VVR) 11.8 dan versi setelahnya.

      canal-json.infer-schema.strategy

      Tidak

      String

      AUTO

      Strategi penguraian skema tabel.

      Nilai yang valid:

      • AUTO: Secara otomatis mengurai skema dari data JSON. Direkomendasikan jika data tidak berisi field sqlType, untuk mencegah kegagalan penguraian.

      • SQL_TYPE: Mengurai skema dari array sqlType dalam data Canal JSON. Kami merekomendasikan mengatur ini ke SQL_TYPE untuk mendapatkan tipe yang lebih tepat jika data berisi field sqlType.

      • MYSQL_TYPE: Mengurai skema dari array mysqlType dalam data Canal JSON.

      Jika data Canal JSON di Kafka berisi field sqlType dan Anda memerlukan pemetaan tipe yang lebih tepat, atur canal-json.infer-schema.strategy ke SQL_TYPE.

      Untuk informasi lebih lanjut tentang aturan pemetaan tipe sqlType, lihat Penguraian Skema Canal JSON.

      Catatan
      • Konfigurasi ini hanya didukung di Ververica Runtime (VVR) 11.1 dan versi setelahnya.

      • Nilai MYSQL_TYPE didukung di Ververica Runtime (VVR) 11.3 dan versi setelahnya.

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

      Tidak

      Boolean

      true

      Memetakan tipe MySQL TIMESTAMP ke tipe CDC TIMESTAMP.

      • true: Tipe MySQL TIMESTAMP dipetakan ke tipe CDC TIMESTAMP.

      • false: Tipe MySQL TIMESTAMP dipetakan ke tipe CDC TIMESTAMP_LTZ.

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

      Tidak

      Boolean

      true

      Saat menggunakan strategi penguraian MYSQL_TYPE, mengontrol apakah memetakan tipe MySQL TINYINT(1) ke tipe CDC BOOLEAN.

      • true: Tipe MySQL TINYINT(1) dipetakan ke tipe CDC BOOLEAN.

      • false: Tipe MySQL TINYINT(1) dipetakan ke tipe CDC TINYINT(1).

      Opsi ini hanya berlaku saat canal-json.infer-schema.strategy diatur ke MYSQL_TYPE.

    • Parameter format JSON

      Parameter

      Wajib

      Tipe

      Default

      Deskripsi

      json.timestamp-format.standard

      Tidak

      String

      SQL

      Format timestamp untuk data input dan output.

      • SQL: Mengurai timestamp input dalam format yyyy-MM-dd HH:mm:ss.s{precision}, seperti 2020-12-30 12:13:14.123.

      • ISO-8601: Mengurai timestamp input dalam format yyyy-MM-ddTHH:mm:ss.s{precision}, seperti 2020-12-30T12:13:14.123.

      json.ignore-parse-errors

      Tidak

      Boolean

      false

      Nilai yang valid:

      • true: Melewatkan baris saat ini jika terjadi exception penguraian.

      • false: Melemparkan error dan pekerjaan gagal dimulai.

      json.infer-schema.primitive-as-string

      Tidak

      Boolean

      false

      Mengurai semua tipe primitif sebagai String saat mengurai skema tabel.

      Nilai yang valid:

      • true: Mengurai semua tipe primitif sebagai String.

      • false: Mengurai tipe berdasarkan aturan default.

      json.infer-schema.string-type-inference

      Tidak

      Boolean

      true

      Menentukan apakah akan melakukan inferensi field string sebagai TIME, DATE, atau TIMESTAMP. Jika Anda mengatur parameter ini ke false, connector melewatkan inferensi ini dan menyimpan field sebagai STRING.

      Catatan

      Parameter ini hanya didukung di Ververica Runtime (VVR) 11.8 dan versi setelahnya.

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

      Tidak

      Boolean

      false

      Secara rekursif memperluas kolom bersarang dalam data JSON. Nilai yang valid:

      • true: Secara rekursif memperluas kolom bersarang.

      • false: Memperlakukan kolom bersarang sebagai String.

      json.decode.parser-table-id.fields

      Tidak

      String

      Menggunakan nilai field JSON tertentu untuk menghasilkan tableId saat mengurai data dalam format JSON. Nilai beberapa field digabungkan dengan koma Inggris ,. Misalnya, jika data JSON adalah {"col0":"a", "col1","b", "col2","c"}, hasil yang dihasilkan adalah sebagai berikut:

      Konfigurasi

      tableId

      col0

      a

      col0,col1

      a.b

      col0,col1,col2

      a.b.c

      json.infer-schema.fixed-types

      Tidak

      String

      Saat mengurai data JSON, Anda dapat menentukan tipe data untuk field tertentu. Gunakan koma , untuk memisahkan beberapa field. Misalnya, id BIGINT, name VARCHAR(10) menentukan bahwa field id bertipe BIGINT dan field name bertipe VARCHAR(10).

      Catatan
      • Opsi konfigurasi ini hanya didukung di Ververica Runtime (VVR) 11.5 dan versi setelahnya.

      • Saat menggunakan konfigurasi ini dengan Ververica Runtime (VVR) versi 11.5, Anda juga harus menambahkan konfigurasi scan.max.pre.fetch.records: 0.

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

      Tidak

      Boolean

      false

      Menentukan apakah akan mengurai pesan tombstone (dengan nilai kosong) di topik Kafka yang dikompaksi sebagai event DELETE. Digunakan untuk skenario di mana nilai kosong merepresentasikan semantik penghapusan, seperti pencermatan topik yang dikompaksi atau sinyal penghapusan CDC.

      Catatan

      Opsi konfigurasi ini hanya didukung di Ververica Runtime (VVR) 11.7 dan versi setelahnya.

  • Parameter tabel sink

    Parameter

    Deskripsi

    Wajib

    Tipe

    Default

    Keterangan

    type

    Jenis sink.

    Ya

    String

    Nilainya harus kafka.

    name

    Nama sink.

    Tidak

    String

    Tidak ada

    topic

    Nama topik Kafka.

    Tidak

    String

    Jika parameter ini ditentukan, semua data ditulis ke topik ini.

    Catatan

    Jika tidak ditentukan, setiap record ditulis ke topik yang dinamai sesuai TableID-nya. TableID dibentuk dengan menggabungkan nama database dan tabel menggunakan titik (.), contohnya: databaseName.tableName.

    partition.strategy

    Strategi penulisan partisi Kafka.

    Tidak

    String

    all-to-zero

    Nilai yang valid:

    • all-to-zero (default): Menulis semua data ke Partisi 0.

    • hash-by-key: Menulis data ke partisi berdasarkan nilai hash kunci primer, sehingga record dengan kunci primer yang sama selalu ditulis ke partisi yang sama untuk menjaga urutan.

    sink.tableId-to-topic.mapping

    Pemetaan nama tabel hulu ke nama topik Kafka hilir.

    Tidak

    String

    Pisahkan setiap Pemetaan dengan titik koma (;). Dalam setiap Pemetaan, pisahkan nama tabel upstream dan nama topik Kafka downstream menggunakan titik dua (:). Anda dapat menggunakan ekspresi reguler untuk nama tabel. Untuk memetakan beberapa tabel ke satu topik yang sama, pisahkan nama tabel tersebut dengan koma (,). Contohnya: mydb.mytable1:topic1;mydb.mytable2:topic2.

    Catatan

    Parameter ini memungkinkan Anda mengubah topik tujuan sambil tetap mempertahankan informasi nama tabel asli.

    • Parameter format Canal JSON

      Parameter

      Wajib

      Tipe

      Default

      Deskripsi

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

      Tidak

      Boolean

      false

      Menentukan apakah bagian old dalam pesan UPDATE dengan format Canal JSON hanya mencakup nilai sebelumnya dari field yang berubah.

      Catatan

      Parameter ini hanya didukung di Ververica Runtime (VVR) 11.8 dan versi yang lebih baru.

    • Parameter format Debezium JSON

      Parameter

      Wajib

      Tipe

      Default

      Deskripsi

      debezium-json.include-schema.enabled

      Tidak

      Boolean

      false

      Menyertakan informasi skema dalam data Debezium JSON.

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

      Tidak

      Boolean

      false

      Menulis ID tabel tiga bagian lengkap ke field metadata Debezium JSON.

      Jika parameter ini diaktifkan, pemetaannya adalah sebagai berikut:

      Bagian ID Tabel CDC

      Debezium JSON Key

      Namespace

      db

      Skema

      schema

      Tabel

      table

      Jika parameter ini dinonaktifkan, pemetaannya adalah sebagai berikut:

      Bagian ID Tabel CDC

      Debezium JSON Key

      Namespace

      Tidak dipetakan

      Skema

      db

      Tabel

      table

      Catatan

      Parameter ini hanya didukung di Ververica Runtime (VVR) 11.6 dan versi setelahnya.

Contoh

  • Gunakan Kafka sebagai sumber 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
  • Gunakan Kafka sebagai sink 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}

    Modul route menentukan Topik Kafka tujuan untuk Tabel Sumber.

Catatan

Secara default, fitur pembuatan topik otomatis dinonaktifkan untuk ApsaraMQ for Kafka. Untuk informasi lebih lanjut, lihat FAQ tentang pembuatan topik otomatis. Anda harus membuat topik sebelum menulis data ke ApsaraMQ for Kafka. Untuk informasi lebih lanjut, lihat Langkah 3: Buat sumber daya.

Kebijakan untuk penguraian dan evolusi skema

Kafka connector mempertahankan skema semua tabel yang saat ini diketahui.

Inisialisasi skema tabel

Skema tabel mencakup kolom dan tipe data, nama database dan tabel, serta kunci primer. Bagian berikut menjelaskan cara menginisialisasi masing-masing komponen tersebut.

  • Informasi kolom dan tipe data

Pekerjaan Flink CDC dapat secara otomatis melakukan inferensi kolom dan tipe data dari data, tetapi Anda mungkin ingin mendefinisikannya secara eksplisit untuk tabel tertentu. Ada tiga strategi inisialisasi skema, tergantung pada seberapa banyak kontrol yang Anda butuhkan atas tipe-tipe tersebut:

  1. Inferensi skema sepenuhnya otomatis

Sebelum membaca data dari Kafka, Kafka connector mencoba mengonsumsi hingga scan.max.pre.fetch.records pesan dari setiap partisi, mengurai skema setiap pesan, dan menggabungkan skema-skema tersebut untuk menginisialisasi skema tabel. Event pembuatan tabel kemudian dihasilkan berdasarkan skema yang diinisialisasi ini sebelum data benar-benar dikonsumsi.

Catatan

Untuk format Debezium JSON dan Canal JSON, informasi tabel terdapat dalam setiap pesan. Pesan yang diambil sebelumnya berdasarkan parameter scan.max.pre.fetch.records mungkin berisi data dari beberapa tabel. Oleh karena itu, jumlah record yang diambil sebelumnya untuk tabel tunggal tidak dapat ditentukan. Pengambilan sebelumnya dan inisialisasi skema hanya dilakukan sekali untuk setiap partisi sebelum pesannya dikonsumsi dan diproses. Jika data untuk tabel baru muncul nanti, skema yang diurai dari record pertama tabel tersebut digunakan sebagai skema awalnya, dan skema tersebut tidak diambil atau diinisialisasi ulang.

Penting

Distribusi data dari tabel tunggal di beberapa partisi hanya didukung di Ververica Runtime (VVR) 8.0.11 dan versi setelahnya, dan mengharuskan Anda mengatur opsi konfigurasi debezium-json.distributed-tables atau canal-json.distributed-tables ke true.

  1. Menentukan skema tabel awal

Dalam beberapa kasus, Anda mungkin perlu mendefinisikan skema tabel awal secara eksplisit—misalnya, saat menulis data dari Kafka ke tabel hilir yang sudah ada. Untuk melakukannya, tambahkan parameter scan.value.initial-schemas.ddls. Berikut contoh konfigurasinya:

source:
  type: kafka
  name: Kafka Source
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # Set the initial table schema
  scan.value.initial-schemas.ddls: CREATE TABLE db1.t1 (id BIGINT, name VARCHAR(10)); CREATE TABLE db1.t2 (id BIGINT);

Pernyataan DDL harus sesuai dengan skema tabel target. Konfigurasi ini menentukan tipe awal kolom id sebagai BIGINT dan kolom name sebagai VARCHAR(10) untuk tabel db1.t1, dan tipe awal kolom id sebagai BIGINT untuk tabel db1.t2.

Pernyataan DDL menggunakan sintaks SQL Flink.

  1. Menetapkan tipe tetap untuk field tertentu

Anda mungkin ingin mengunci field tertentu ke tipe data tetap. Misalnya, field yang biasanya diinferensikan sebagai TIMESTAMP mungkin perlu dikeluarkan sebagai string. Dalam hal ini, Anda dapat menambahkan parameter json.infer-schema.fixed-types untuk menentukan skema tabel awal. Parameter ini hanya berlaku saat format pesan adalah JSON. Berikut adalah contoh konfigurasi:

source:
  type: kafka
  name: Kafka Source
  properties.bootstrap.servers: host:9092
  topic: test-topic
  value.format: json
  scan.startup.mode: earliest-offset
  # Set specific fields to a fixed type
  json.infer-schema.fixed-types: id BIGINT, name VARCHAR(10)
  scan.max.pre.fetch.records: 0

Konfigurasi ini menentukan bahwa semua field id bertipe BIGINT dan semua field name bertipe VARCHAR(10).

Tipe data konsisten dengan tipe SQL Flink.

  • Informasi database dan tabel

    • Untuk format Canal JSON dan Debezium JSON, connector mengurai informasi tabel, termasuk nama database dan tabel, dari setiap pesan.

    • Untuk format JSON, secara default, informasi tabel hanya berisi nama tabel, yaitu nama topik yang berisi data tersebut. Jika data Anda berisi informasi database dan tabel, Anda dapat menggunakan parameter json.infer-schema.fixed-types untuk menentukan field yang berisi informasi ini. Field-field ini kemudian dipetakan ke nama database dan tabel. Berikut adalah contoh konfigurasi:

      source:
        type: kafka
        name: Kafka Source
        properties.bootstrap.servers: host:9092
        topic: test-topic
        value.format: json
        scan.startup.mode: earliest-offset
        # Use the value of the col1 field as the database name and the value of the col2 field as the table name
        json.decode.parser-table-id.fields: col1,col2

      Dengan konfigurasi ini, connector mengirimkan setiap record ke tabel di mana nama database adalah nilai field col1 dan nama tabel adalah nilai field col2.

  • Informasi kunci primer

    • Untuk format Canal JSON, field pkNames dalam data JSON mendefinisikan kunci primer tabel.

    • Untuk format Debezium JSON dan JSON, data tidak berisi informasi kunci primer. Anda dapat menambahkan kunci primer ke tabel secara manual dengan menggunakan aturan transform:

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

Penguraian skema dan evolusi skema

Setelah skema tabel diinisialisasi, jika schema.inference.strategy diatur ke static, Kafka connector mengurai nilai pesan setiap pesan berdasarkan skema tabel awal dan tidak menghasilkan event perubahan skema. Jika schema.inference.strategy diatur ke continuous, Kafka connector mengurai nilai pesan setiap pesan Kafka, mengidentifikasi kolom fisiknya, dan membandingkan skema yang dihasilkan dengan skema yang saat ini dipertahankan. Jika skema tidak konsisten, connector mencoba menggabungkannya dan menghasilkan event perubahan skema tabel yang sesuai. Aturan penggabungan adalah sebagai berikut:

  • Jika kolom fisik yang diurai berisi field yang tidak ada dalam skema saat ini, field tersebut ditambahkan ke skema, dan event dihasilkan untuk menambahkannya sebagai kolom nullable.

  • Jika kolom fisik yang diurai tidak berisi field yang ada dalam skema saat ini, field tersebut dipertahankan dan nilainya diisi dengan NULL. Tidak ada event penghapusan kolom yang dihasilkan.

  • Kolom yang memiliki nama yang sama ditangani sebagai berikut:

    • Jika field memiliki tipe data yang sama tetapi presisi berbeda, tipe dengan presisi lebih besar digunakan, dan event perubahan tipe kolom dihasilkan.

    • Jika field memiliki tipe data berbeda, sistem menemukan tipe induk umum terkecil dalam pohon hierarki tipe di bawah ini. Sistem kemudian menggunakan tipe induk umum ini untuk kolom dan menghasilkan event perubahan tipe kolom.

      image

  • Kebijakan evolusi skema yang didukung:

    • Menambahkan kolom: Connector menambahkan kolom baru ke akhir skema dan menyinkronkan datanya. Kolom baru diatur sebagai nullable.

    • Menghapus kolom: Tidak ada event penghapusan kolom yang dihasilkan. Sebagai gantinya, data selanjutnya untuk kolom tersebut diisi dengan NULL.

    • Mengganti nama kolom: Connector memperlakukan ini sebagai penghapusan kolom lama dan penambahan kolom baru. Kolom baru ditambahkan ke akhir skema, dan nilai untuk kolom asli diisi dengan NULL.

    • Mengubah tipe kolom:

      • Untuk sink downstream yang mendukung perubahan tipe kolom, Pekerjaan Flink CDC dapat menangani perubahan tipe (misalnya, dari INT ke BIGINT) selama sink downstream dikonfigurasi untuk memproses perubahan tersebut. Kemampuan ini bergantung pada aturan perubahan tipe kolom yang didukung oleh sink tertentu. Lihat dokumentasi sink Anda untuk informasi selengkapnya mengenai aturan yang didukung.

      • Untuk sink downstream yang tidak mendukung perubahan tipe kolom, seperti Hologres, Anda dapat menggunakan Pelebaran Tipe. Fitur ini membuat tabel dengan tipe data yang lebih luas di sink downstream saat Pekerjaan dimulai. Ketika tipe kolom berubah, sistem dapat mentoleransi perubahan tersebut selama tipe baru sesuai dengan tipe yang lebih luas yang telah ditentukan di sink downstream.

  • Perubahan skema yang tidak didukung:

    • Perubahan pada constraint, seperti kunci primer atau indeks.

    • Mengubah kolom dari NOT NULL ke NULLABLE.

  • Penguraian skema Canal JSON

    Data Canal JSON mungkin berisi field sqlType opsional, yang mencatat informasi tipe yang tepat untuk kolom data. Untuk mendapatkan skema yang lebih akurat, Anda dapat mengatur canal-json.infer-schema.strategy ke SQL_TYPE untuk menggunakan tipe dari field sqlType. Pemetaan tipenya adalah sebagai berikut:

    JDBC type

    Type code

    CDC type

    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

    Other data types

Toleransi dan pengumpulan data kotor

Sumber data Kafka Anda mungkin berisi record yang rusak, yang biasa disebut data kotor. Untuk mencegah pekerjaan Anda gagal dan restart berulang kali, Anda dapat mengonfigurasinya untuk melewatkan record yang tidak valid ini. Misalnya:

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

Dengan konfigurasi ini, pekerjaan terus berjalan selama tidak menemui lebih dari 1.000 record kotor. Setelah jumlah tersebut terlampaui, pekerjaan gagal sehingga Anda dapat menyelidiki data Anda.

Untuk memastikan pekerjaan Anda tidak pernah gagal karena data kotor, gunakan konfigurasi berikut:

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

Meskipun toleransi data kotor membuat pekerjaan Anda tetap berjalan, Anda mungkin juga ingin memeriksa record yang bermasalah. Anda juga mungkin ingin menganalisis data kotor untuk meningkatkan produsen Kafka Anda. Seperti yang dijelaskan dalam Pengumpulan Data Kotor, Anda dapat melihat data kotor pekerjaan di log TaskManager. Misalnya:

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

Pemetaan nama tabel dan topik

Saat Kafka berfungsi sebagai sink Flink CDC, format paket (seperti Debezium JSON atau Canal JSON) menyematkan nama tabel asli. Konsumen hilir umumnya menggunakan nama yang disematkan tersebut sebagai pengidentifikasi tabel, bukan nama topik, sehingga penting untuk mengonfigurasi pemetaan antara nama tabel dan topik secara tepat.

Anggaplah Anda perlu menyinkronkan dua tabel dari database MySQL: mydb.mytable1 dan mydb.mytable2. Strategi pemetaan berikut tersedia:

1. Tanpa strategi pemetaan

Tanpa strategi pemetaan apa pun, data untuk setiap tabel ditulis ke topik yang dinamai dalam format <Nama Database>.<Nama Tabel>. Oleh karena itu, data dari mydb.mytable1 ditulis ke topik bernama mydb.mytable1, dan data dari mydb.mytable2 ditulis ke topik bernama mydb.mytable2. Berikut adalah contoh konfigurasi:

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. Pemetaan aturan rute (Tidak direkomendasikan)

Anda mungkin ingin menulis data ke topik tertentu daripada menggunakan format default <Nama Database>.<Nama Tabel>. Untuk melakukan ini, Anda dapat mengonfigurasi aturan rute. Berikut adalah contoh konfigurasi:

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

Dalam hal ini, semua data dari mydb.mytable1 dan mydb.mytable2 ditulis ke satu topik bernama mytable.

Namun, aturan rute yang mengubah topik tujuan juga mengubah nama tabel dalam pesan Kafka (dalam format Debezium JSON atau Canal JSON). Nama tabel dalam semua pesan Kafka menjadi mytable. Hal ini dapat menyebabkan perilaku tak terduga pada sistem yang mengonsumsi pesan dari topik ini.

3. Pemetaan dengan sink.tableId-to-topic.mapping (Direkomendasikan)

Untuk memetakan nama tabel ke topik sambil mempertahankan nama sumber tabel asli, gunakan parameter sink.tableId-to-topic.mapping. Berikut adalah contoh konfigurasi:

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}

Atau, Anda dapat menggunakan konfigurasi berikut:

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}

Dalam kasus ini, seluruh data dari mydb.mytable1 dan mydb.mytable2 ditulis ke topik mytable, sedangkan nama tabel dalam Paket Kafka (dalam format Debezium JSON atau Canal JSON) tetap dipertahankan sebagai mydb.mytable1 atau mydb.mytable2. Dengan demikian, sistem downstream tetap dapat mengidentifikasi tabel sumber asli setiap Catatan.

Contoh konfigurasi

Contoh berikut menunjukkan konfigurasi untuk kasus penggunaan umum.

Baca dari satu topik

Contoh berikut membaca topik customers dan menulis data ke data lake Alibaba Cloud:

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # Optional: Dynamically infer the schema of each record and detect schema changes.
  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
  # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
  commit.user: your_job_name
  # Optional: Enable deletion vectors to improve read performance.
  table.properties.deletion-vectors.enabled: true

Untuk format JSON, nama tabel yang dihasilkan sama dengan nama topik secara default.

Baca dari beberapa topik

Contoh berikut membaca topik yang namanya cocok dengan ekspresi reguler dan menulis data ke StarRocks:

source:
  type: kafka
  topic-pattern: user_event_.*
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # Optional: Dynamically infer the schema of each record and detect schema changes.
  schema.inference.strategy: continuous

sink:
  type: starrocks
  jdbc-url: jdbc:mysql://<yourFeHostname>:9030
  load-url: <yourFeHostname>:8030
  username: <yourUsername>
  password: ${secret_values.starrocks_password}
 
  # Optional: For jobs with low data volumes, use a shorter flush interval to prevent data from remaining unwritten for a long time. The default is 300000 milliseconds, or 5 minutes.
  sink.buffer-flush.interval-ms: 5000
  # Optional: If the upstream character set is utf8mb4, set this parameter to 4 to prevent text truncation. The default is 3.
  unicode-char.max-bytes: 4
  # Optional: Specify the number of buckets for automatically created tables. You must explicitly configure this parameter for StarRocks versions earlier than 2.5.7. Later versions can infer the value.
  table.create.num-buckets: 8
  # Optional: Specify the number of replicas for automatically created tables based on your cluster configuration.
  table.create.properties.replication_num: 3
  # Optional: For StarRocks 3.2 and later, enable this feature to accelerate schema changes.
  table.create.properties.fast_schema_evolution: true
  # Note: If a transform changes a primary key, you must also set sink.ignore.update-before to false.
  # Otherwise, the row that uses the old primary key remains in the downstream system.

Untuk format JSON, nama tabel yang dihasilkan sama dengan nama topik secara default.

Baca kunci dan cegah konflik field

Anda dapat menggunakan salah satu metode berikut untuk mencegah error yang disebabkan oleh nama field duplikat di kunci dan nilai:

  1. Tambahkan awalan ke field untuk mencegah konflik:

    source:
      type: kafka
      topic: ${kafka.topic}
      properties.bootstrap.servers: localhost:9092
      properties.group.id: ${kafka.group.id}
      key.format: json
      value.format: json
      # Add the key_ prefix to field names in the key.
      key.fields-prefix: key_
      # Add the value_ prefix to field names in the value.
      value.fields-prefix: value_
      # Optional: Dynamically infer the schema of each record and detect schema changes.
      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
      # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
      commit.user: your_job_name
      # Optional: Enable deletion vectors to improve read performance.
      table.properties.deletion-vectors.enabled: true
  2. Konfigurasikan kebijakan resolusi konflik. Untuk informasi lebih lanjut, lihat scan.duplicate-field.strategy. Konfigurasi berikut memprioritaskan field di kunci dan mengabaikan field dengan nama yang sama di nilai:

    source:
      type: kafka
      topic: ${kafka.topic}
      properties.bootstrap.servers: localhost:9092
      properties.group.id: ${kafka.group.id}
      key.format: json
      value.format: json
      # Prefer fields in the key and ignore fields with the same names in the value.
      scan.duplicate-field.strategy: PREFER_KEY
      # Optional: Dynamically infer the schema of each record and detect schema changes.
      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
      # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
      commit.user: your_job_name
      # Optional: Enable deletion vectors to improve read performance.
      table.properties.deletion-vectors.enabled: true

Tambahkan kolom metadata

Contoh berikut membaca topik customers dan menambahkan kolom metadata topic dan partition:

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # Optional: Dynamically infer the schema of each record and detect schema changes.
  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
  # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
  commit.user: your_job_name
  # Optional: Enable deletion vectors to improve read performance.
  table.properties.deletion-vectors.enabled: true

Tangani error penguraian

Error penguraian menyebabkan pekerjaan gagal. Anda dapat mengonfigurasi pekerjaan untuk mentoleransi error penguraian. Fitur ini biasanya digunakan bersama dengan pengumpulan data kotor.

Contoh berikut mengabaikan semua error penguraian:

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # Optional: Dynamically infer the schema of each record and detect schema changes.
  schema.inference.strategy: continuous
  # Ignore parsing errors. By default, all parsing errors are ignored when this feature is enabled.
  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
  # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
  commit.user: your_job_name
  # Optional: Enable deletion vectors to improve read performance.
  table.properties.deletion-vectors.enabled: true
  
# Enable a dirty data collector to print records that cannot be parsed.
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

Contoh berikut membuat pekerjaan gagal setelah 30 error penguraian:

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # Optional: Dynamically infer the schema of each record and detect schema changes.
  schema.inference.strategy: continuous
  # Ignore parsing errors.
  ingestion.ignore-errors: true
  # Fail the job after 30 parsing errors.
  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
  # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
  commit.user: your_job_name
  # Optional: Enable deletion vectors to improve read performance.
  table.properties.deletion-vectors.enabled: true
  
# Enable a dirty data collector to print records that cannot be parsed.
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

Baca data JSON

Bagian berikut menjelaskan cara umum untuk membaca data dalam format JSON.

Tentukan cara penguraian ID tabel

Secara default, ID tabel data JSON adalah nama topik. Anda dapat menggunakan nilai field dalam data sebagai ID tabel. Contoh berikut menggunakan field db dan tbl sebagai ID tabel:

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # Optional: Dynamically infer the schema of each record and detect schema changes.
  schema.inference.strategy: continuous
  # Use the db and tbl fields as the table 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
  # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
  commit.user: your_job_name
  # Optional: Enable deletion vectors to improve read performance.
  table.properties.deletion-vectors.enabled: true
  
# Enable a dirty data collector to print records that cannot be parsed.
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

Tentukan tipe field

Tipe field diinferensikan dari nilai field, tetapi tipe yang diinferensikan mungkin bukan tipe yang Anda harapkan. Anda dapat menentukan tipe tetap untuk field yang dipilih dan melewatkan inferensi dan evolusi tipe selanjutnya untuk field tersebut.

Contoh berikut memperbaiki tipe empat field:

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: json
  # Use the db and tbl fields as the table ID.
  value.json.decode.parser-table-id.fields: db,tbl
  # Specify fixed types for selected fields.
  value.json.infer-schema.fixed-types: 'db STRING, tbl STRING, id BIGINT, amount DECIMAL(18, 2)'
  # Continue to dynamically infer fields that are not declared.
  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
  # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
  commit.user: your_job_name
  # Optional: Enable deletion vectors to improve read performance.
  table.properties.deletion-vectors.enabled: true
  
# Enable a dirty data collector to print records that cannot be parsed.
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

Baca data Canal JSON

Bagian berikut menjelaskan cara umum untuk membaca data dalam format Canal JSON.

Konfigurasikan kebijakan inferensi tipe

Secara default, connector melakukan inferensi tipe skema dari nilai field saat membaca data Canal JSON.

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: canal-json
  # Optional: Dynamically infer the schema of each record and detect schema changes.
  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
  # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
  commit.user: your_job_name
  # Optional: Enable deletion vectors to improve read performance.
  table.properties.deletion-vectors.enabled: true
  
# Enable a dirty data collector to print records that cannot be parsed.
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

Anda juga dapat melakukan inferensi skema dari informasi skema yang direkam dalam data Canal JSON, seperti tipe SQL atau tipe MySQL. Contoh berikut menggunakan tipe MySQL untuk melakukan inferensi skema:

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: canal-json
  # Optional: Dynamically infer the schema of each record and detect schema changes.
  schema.inference.strategy: continuous
  # Infer the schema from MySQL type information. You can set this parameter to SQL_TYPE to use SQL type information instead.
  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
  # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
  commit.user: your_job_name
  # Optional: Enable deletion vectors to improve read performance.
  table.properties.deletion-vectors.enabled: true
  
# Enable a dirty data collector to print records that cannot be parsed.
pipeline:
  dirty-data.collector:
    name: Logger Dirty Data Collector
    type: logger

Baca data Debezium JSON

Contoh berikut membaca topik customers dan menulis data ke data lake Alibaba Cloud:

source:
  type: kafka
  topic: customers
  properties.bootstrap.servers: localhost:9092
  properties.group.id: ${kafka.group.id}
  value.format: debezium-json
  # Optional: Dynamically infer the schema of each record and detect schema changes.
  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
  # Optional: Specify a commit user. We recommend that you use a different commit user for each job to prevent conflicts.
  commit.user: your_job_name
  # Optional: Enable deletion vectors to improve read performance.
  table.properties.deletion-vectors.enabled: true

Menyinkronkan binlog MySQL mentah ke Kafka

Ingesti data Flink CDC dapat menyinkronkan data binlog MySQL mentah dalam format Canal JSON. Pekerjaan berikut menyinkronkan binlog dari beberapa tabel ke topik order_dw_tables:

source:
  type: mysql
  hostname: #{hostname}
  port: 3306
  username: #{username}
  password: #{password}
  tables: order_dw.\.*
  server-id: 28601-28604
  # Optional: Synchronize data from tables that are created during the incremental phase.
  scan.binlog.newly-added-table.enabled: true
  # Optional: Synchronize table and column comments.
  include-comments.enabled: true
  # Optional: Process unbounded chunks first to prevent potential TaskManager out-of-memory errors.
  scan.incremental.snapshot.unbounded-chunk-first.enabled: true
  # Optional: Enable parsing filters to accelerate reads.
  scan.only.deserialize.captured.tables.changelog.enabled: true
  # Add mysqlType, sqlType, sql, isDdl, and other metadata to the Canal JSON data.
  include-binlog-meta.enable: true
  
sink:
  type: kafka
  properties.bootstrap.servers: localhost:9092
  topic: order_dw_tables
  # Use the Canal JSON changelog format for Kafka values.
  value.format: canal-json
  # Specify the format used to serialize date and time data.
  value.canal-json.timestamp-format.standard: SQL
  # Write all data to Partition 0 to preserve binlog order.
  partition.strategy: all-to-zero

Semantik tepat-sekali

  • Konfigurasikan tingkat isolasi konsumen

    Semua aplikasi yang mengonsumsi data Kafka harus mengatur properti isolation.level:

    • read_committed: Hanya membaca data yang telah di-commit.

    • read_uncommitted (Default): Dapat membaca data yang belum di-commit.

    EXACTLY_ONCE bergantung pada read_committed. Jika tidak, konsumen mungkin melihat data yang belum di-commit, sehingga mengganggu konsistensi.

  • Timeout transaksi dan kehilangan data

    Saat memulihkan dari checkpoint, Realtime Compute for Apache Flink hanya mempertimbangkan transaksi yang telah di-commit sebelum checkpoint tersebut dimulai. Jika durasi antara kegagalan pekerjaan dan restart-nya melebihi timeout transaksi Kafka, Kafka secara otomatis membatalkan transaksi yang terbuka, yang dapat mengakibatkan kehilangan data.

    • transaction.max.timeout.ms default untuk broker Kafka adalah 15 menit.

    • Secara default, Flink Kafka Sink mengatur parameter transaction.timeout.ms ke 1 jam.

    • Anda harus meningkatkan transaction.max.timeout.ms pada broker agar lebih besar dari atau sama dengan pengaturan di Flink.

  • Kolam produsen dan checkpoint konkuren

    Mode EXACTLY_ONCE menggunakan kolam produsen Kafka dengan ukuran tetap. Setiap checkpoint menggunakan satu produsen dari kolam ini. Jika jumlah checkpoint konkuren melebihi ukuran kolam, pekerjaan gagal.

    Konfigurasikan ukuran kolam produsen berdasarkan jumlah maksimum checkpoint konkuren.

  • Batasan penskalaan turun paralelisme

    Jika pekerjaan gagal sebelum checkpoint pertama selesai, informasi kolam produsen asli hilang saat restart. Oleh karena itu, jangan melakukan penskalaan turun paralelisme pekerjaan sebelum checkpoint pertama selesai. Jika penskalaan turun diperlukan, paralelisme baru tidak boleh kurang dari FlinkKafkaProducer.SAFE_SCALE_DOWN_FACTOR.

  • Transaksi memblokir pembacaan

    Dalam mode read_committed, transaksi apa pun yang belum di-commit atau dibatalkan memblokir operasi baca pada seluruh topik.

    Misalnya:

    • Transaksi 1 menulis data.

    • Transaksi 2 menulis lebih banyak data dan di-commit.

    • Selama Transaksi 1 tetap terbuka, data dari Transaksi 2 yang telah di-commit tidak terlihat oleh konsumen.

    Hal ini memiliki implikasi berikut:

    • Selama operasi normal, latensi visibilitas data kira-kira sama dengan interval checkpoint.

    • Jika pekerjaan gagal, topik apa pun yang sedang ditulisnya diblokir untuk konsumen sampai pekerjaan restart atau transaksi timeout. Dalam kasus ekstrem, proses timeout transaksi itu sendiri juga dapat memengaruhi operasi baca.

FAQ