Use o Kafka SQL connector como tabela de origem ou tabela de destino no Realtime Compute for Apache Flink.
Visão geral
O Apache Kafka é uma plataforma de streaming de eventos distribuída e de código aberto, amplamente utilizada para processamento de dados de alto desempenho, análises de streaming e integração de dados. O Kafka connector para Realtime Compute for Apache Flink utiliza o cliente Apache Kafka de código aberto para oferecer alto throughput de dados, suporte à leitura e gravação em múltiplos formatos de dados, e semântica de exactly-once.
|
Categoria |
Descrição |
|
Tipos suportados |
SQL source, sink Flink CDC source, sink DataStream source, sink |
|
Modo de execução |
Streaming |
|
Formatos de dados |
|
|
Métricas |
|
|
Tipos de API |
SQL, DataStream, Flink CDC |
|
Atualização/exclusão no sink |
O connector suporta apenas a adição de dados a uma tabela de destino. Atualizações e exclusões não são suportadas. Nota
Para mais informações sobre como atualizar ou excluir dados em uma Sink Table, consulte Upsert Kafka. |
Pré-requisitos
Antes de começar, verifique se os pré-requisitos para o tipo de cluster Kafka estão atendidos:
-
Conectar a um cluster ApsaraMQ for Kafka
O cluster Kafka deve ser da versão 0.11 ou posterior.
Crie um cluster ApsaraMQ for Kafka. Para mais informações, consulte Step 3: Create resources.
O workspace do Flink e o cluster Kafka devem estar na mesma Virtual Private Cloud (VPC), e o bloco CIDR do workspace do Flink deve ser adicionado à lista de permissões do ApsaraMQ for Kafka. Para mais informações, consulte Configure whitelists.
ImportanteLimitações para gravação de dados no ApsaraMQ for Kafka:
O ApsaraMQ for Kafka não suporta o formato de compressão Zstandard (zstd) para gravações.
O ApsaraMQ for Kafka não suporta gravações idempotentes ou transacionais, o que impede o uso da semântica de exactly-once fornecida pelas Kafka sink tables. A partir do Ververica Runtime (VVR) 8.0.0, o Kafka connector utiliza o cliente Kafka 3.x, no qual a propriedade
properties.enable.idempotencetem como padrãotrue. Portanto, para evitar falhas de gravação ao usar o Ververica Runtime (VVR) 8.0.0 ou posterior para gravar no ApsaraMQ for Kafka, adicione a configuração properties.enable.idempotence=false à definição da sua sink table. Para uma comparação dos mecanismos de armazenamento e das limitações de recursos do ApsaraMQ for Kafka, consulte Comparison between storage engines.
-
Conectar a um cluster Apache Kafka autogerenciado
O cluster Apache Kafka autogerenciado deve ser da versão 0.11 ou posterior.
O workspace do Flink deve ter conectividade de rede com o cluster Apache Kafka autogerenciado. Para detalhes sobre como conectar a um cluster pela internet pública, consulte FAQ about network connectivity.
Somente as opções de configuração de cliente para o Apache Kafka versão 2.8 são suportadas. Para mais informações, consulte a documentação do Apache Kafka sobre Consumer Configs e Producer Configs.
Observações
Gravações transacionais não são recomendadas devido a limitações de design conhecidas no Apache Flink e no Apache Kafka. Ao definir sink.delivery-guarantee = 'exactly-once', o Kafka connector ativa as gravações transacionais, com os seguintes problemas conhecidos:
Cada checkpoint gera um novo Transaction ID. Caso o intervalo entre checkpoints seja muito curto, o grande volume de Transaction IDs gerados pode esgotar a memória do coordenador do cluster Kafka, comprometendo sua estabilidade.
Cada transação cria uma nova instância de Producer. Se muitas transações forem confirmadas simultaneamente, o TaskManager pode ficar sem memória, desestabilizando o job do Apache Flink.
Se múltiplos jobs do Apache Flink utilizarem o mesmo
sink.transactional-id-prefix, os Transaction IDs gerados poderão entrar em conflito. Quando uma operação de gravação falha em um job, isso pode impedir o avanço do Log Start Offset (LSO) de uma partição do Apache Kafka, afetando todos os consumidores daquela partição.
Caso necessite de semântica de exactly-once, use o Upsert Kafka connector para gravar em uma tabela de chave primária, garantindo idempotência. Se o uso de gravações transacionais for indispensável, consulte Exactly-once semantics usage notes.
Solucionar problemas de conectividade de rede
O erro Timed out waiting for a node assignment quando um job do Realtime Compute for Apache Flink falha ao iniciar geralmente indica um problema de conectividade de rede entre o Realtime Compute for Apache Flink e o cluster Kafka.
Um cliente Kafka se conecta aos brokers da seguinte forma:
O cliente utiliza os endereços especificados em
bootstrap.serverspara estabelecer a conexão inicial com o cluster Kafka.O cluster Kafka retorna os metadados de cada broker, incluindo seus endpoints.
O cliente então usa esses endpoints para se conectar aos brokers e ler ou gravar dados.
Mesmo que os endereços de bootstrap.servers estejam acessíveis, o cliente não conseguirá ler ou gravar dados se o Kafka retornar endpoints de broker incorretos. Esse problema ocorre com frequência em arquiteturas de rede que utilizam proxy, redirecionamento de porta ou linha dedicada.
Etapas de diagnóstico
ApsaraMQ for Kafka
-
Confirme o tipo de Endpoint
Default Endpoint (rede interna)
SASL Endpoint (rede interna com autenticação)
Public Endpoint (requer solicitação separada)
Use o recurso Network Probe no console de desenvolvimento do Realtime Compute for Apache Flink para descartar problemas de conectividade com o endereço
bootstrap.servers. -
Verifique os grupos de segurança e as listas de permissões
Adicione o bloco CIDR do workspace do Realtime Compute for Apache Flink à lista de permissões da sua instância Kafka. Para mais informações, consulte View VPC CIDR Block e Configure a whitelist.
-
Verifique a configuração SASL (se habilitada)
Ao usar um endpoint SASL_SSL, certifique-se de que os mecanismos JAAS, SSL e SASL estejam configurados corretamente no seu job do Realtime Compute for Apache Flink. Sem autenticação adequada, a conexão pode falhar durante a fase de handshake, o que também pode se manifestar como um timeout. Para mais informações, consulte Security and authentication.
Self-managed Kafka
-
Use o recurso Network Probe****
Esse recurso permite descartar problemas de conectividade com o endereço
bootstrap.serverse verificar se o endpoint interno ou público correto está sendo utilizado. -
Verifique os grupos de segurança e as listas de permissões
O grupo de segurança da instância do Elastic Compute Service (ECS) deve permitir tráfego de entrada na porta do endpoint Kafka, normalmente 9092 ou 9093.
Certifique-se de que qualquer firewall na instância ECS permita tráfego originado da VPC do seu workspace do Realtime Compute for Apache Flink. Para mais informações, consulte View VPC CIDR Block.
-
Verifique a configuração
Use a ferramenta zkCli.sh ou zookeeper-shell.sh para fazer login no cluster ZooKeeper utilizado pelo Kafka.
-
Execute um comando para obter os metadados do broker. Por exemplo, execute
get /brokers/ids/0. No campo endpoints da resposta, localize o endereço que o Kafka divulga aos clientes.# 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} -
Use o recurso Network Probe no console de desenvolvimento do Realtime Compute for Apache Flink para testar se esse endereço está acessível.
NotaSe o endereço não estiver acessível, entre em contato com os administradores do Kafka para verificar e corrigir as configurações
listenerseadvertised.listeners, garantindo que o endereço divulgado seja acessível a partir do Realtime Compute for Apache Flink.Para mais informações sobre conexões de clientes Kafka, consulte Troubleshoot Connectivity.
-
Verifique a configuração SASL (se habilitada)
Ao usar um endpoint SASL_SSL, certifique-se de que os mecanismos JAAS, SSL e SASL estejam configurados corretamente no seu job do Realtime Compute for Apache Flink. Sem autenticação adequada, a conexão pode falhar durante a fase de handshake, o que também pode se manifestar como um timeout. Para mais informações, consulte Security and authentication.
SQL
Use o Kafka connector como tabela de origem ou tabela de destino em jobs SQL.
Sintaxe
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'
)
Colunas de metadados
Defina colunas de metadados em uma tabela de origem ou de destino para acessar os metadados das mensagens Kafka. Por exemplo, ao assinar múltiplos tópicos, uma coluna de metadados pode identificar de qual tópico cada registro se origina.
CREATE TABLE kafka_source (
-- Read the message topic as the `record_topic` column
`record_topic` STRING NOT NULL METADATA FROM 'topic' VIRTUAL,
-- Read the timestamp from the ConsumerRecord as the `ts` column
`ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
-- Read the message offset as the `record_offset` column
`record_offset` BIGINT NOT NULL METADATA FROM 'offset' VIRTUAL,
...
) WITH (
'connector' = 'kafka',
...
);
CREATE TABLE kafka_sink (
-- Write the timestamp from the `ts` column as the ProducerRecord's timestamp to Kafka
`ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp' VIRTUAL,
...
) WITH (
'connector' = 'kafka',
...
);
A tabela a seguir lista as colunas de metadados suportadas pelas tabelas de origem e de destino do Kafka.
|
Chave |
Tipo |
Descrição |
Escopo |
|
topic |
STRING NOT NULL METADATA VIRTUAL |
Tópico da mensagem. |
Tabela de origem |
|
partition |
INT NOT NULL METADATA VIRTUAL |
ID da partição da mensagem. |
Tabela de origem |
|
headers |
MAP<STRING, BYTES> NOT NULL METADATA VIRTUAL |
Cabeçalhos da mensagem. |
Tabela de origem e tabela de destino |
|
leader-epoch |
INT NOT NULL METADATA VIRTUAL |
Leader-epoch da mensagem. |
Tabela de origem |
|
offset |
BIGINT NOT NULL METADATA VIRTUAL |
Offset da mensagem. |
Tabela de origem |
|
timestamp |
TIMESTAMP(3) WITH LOCAL TIME ZONE NOT NULL METADATA VIRTUAL |
Timestamp da mensagem. |
Tabela de origem e tabela de destino |
|
timestamp-type |
STRING NOT NULL METADATA VIRTUAL |
Tipo de timestamp da mensagem. Os valores válidos são:
|
Tabela de origem |
|
__raw_key__ |
STRING NOT NULL METADATA VIRTUAL |
Chave bruta da mensagem. |
Tabela de origem e tabela de destino Nota
Este parâmetro é suportado apenas no Ververica Runtime (VVR) 11.4 e versões posteriores. |
|
__raw_value__ |
STRING NOT NULL METADATA VIRTUAL |
Valor bruto da mensagem. |
Tabela de origem e tabela de destino Nota
Este parâmetro é suportado apenas no Ververica Runtime (VVR) 11.4 e versões posteriores. |
Opções do conector
-
General
Option
Description
Type
Required
Default
Remarks
connector
Tipo do conector.
String
Yes
–
O valor deve ser
kafka.properties.bootstrap.servers
Lista de endereços dos brokers Kafka.
String
Yes
–
Formato:
host1:port1,host2:port2,.... Separe os endereços com vírgulas (,).properties.*
Propriedades adicionais para o cliente Kafka.
String
No
–
As chaves de propriedade devem ser opções válidas definidas na documentação oficial do Apache Kafka para Producer Configs e Consumer Configs.
O Realtime Compute for Apache Flink remove o prefixo properties. e repassa os pares chave-valor restantes ao cliente Kafka subjacente. Por exemplo, defina
'properties.allow.auto.create.topics' = 'false'para desativar a criação automática de tópicos.O conector Kafka sobrescreve as opções a seguir, portanto não é possível configurá-las por este meio:
-
key.deserializer
-
value.deserializer
format
Formato para serialização e desserialização do valor de uma mensagem Kafka.
String
No
–
Formatos suportados:
-
csv
-
json
-
avro
-
debezium-json
-
canal-json
-
maxwell-json
-
avro-confluent
-
raw
NotaPara mais informações, consulte Opções de formato.
key.format
Formato para serialização e desserialização da chave de uma mensagem Kafka.
String
No
–
Formatos suportados:
-
csv
-
json
-
avro
-
debezium-json
-
canal-json
-
maxwell-json
-
avro-confluent
-
raw
NotaAo usar esta configuração, key.options é obrigatório.
key.fields
Campos do schema da tabela a serem usados como chave da mensagem Kafka.
String
No
–
Separe múltiplos nomes de campo com ponto e vírgula (;). Por exemplo,
'field1;field2'.key.fields-prefix
Prefixo personalizado para todos os campos de chave, evitando conflitos de nomes com os campos de valor.
String
No
–
Este prefixo distingue os campos de chave dos campos de valor. Ele é removido antes da serialização da chave ou após a desserialização.
NotaAo usar esta opção,
value.fields-includedeve ser definido comoEXCEPT_KEY.value.format
Formato para serialização e desserialização do valor de uma mensagem Kafka.
String
No
–
Esta configuração equivale a
format. Defina apenas uma das opções:formatouvalue.format. Se ambas forem configuradas,value.formattem precedência sobreformat.value.fields-include
Define se os campos de chave são incluídos no formato de valor.
String
No
ALL
Valores válidos:
-
ALL: O valor da mensagem Kafka inclui todas as colunas da tabela. -
EXCEPT_KEY: O valor da mensagem Kafka inclui todas as colunas da tabela, exceto as definidas emkey.fields.
-
-
Source table
Option
Description
Type
Required
Default
Remarks
topic
Tópico ou tópicos a serem lidos.
String
No
–
Para assinar múltiplos tópicos, separe os nomes com ponto e vírgula (;), por exemplo,
'topic-1;topic-2'.NotaEspecifique esta opção ou
topic-pattern, mas não ambas.topic-pattern
Expressão regular que corresponde aos tópicos a serem assinados. O consumidor assina todos os tópicos cujos nomes correspondam a este padrão.
String
No
–
Exemplos:
-
user_event_.*: Corresponde a todos os tópicos com o prefixouser_event_. -
prod\.logs\..*: Corresponde a tópicos com o prefixoprod.logs.(o caractere.deve ser escapado).
NotaEspecifique esta opção ou
topic, mas não ambas.properties.group.id
ID do grupo de consumidores da source Kafka.
String
No
KafkaSource-{Source-Table-Name}
Ao usar um ID de grupo de consumidores pela primeira vez, defina também properties.auto.offset.reset como
earliestoulatestpara estabelecer o offset inicial de leitura.scan.startup.mode
Offset de inicialização do consumidor Kafka.
String
No
group-offsets
Valores válidos:
-
earliest-offset: Inicia a leitura a partir do offset mais antigo disponível. -
latest-offset: Inicia a leitura a partir do offset mais recente. -
group-offsets: Inicia a leitura a partir dos offsets confirmados do properties.group.id especificado. -
timestamp: Inicia a leitura a partir do valor especificado em scan.startup.timestamp-millis. -
specific-offsets: Inicia a leitura a partir dos offsets definidos em scan.startup.specific-offsets.
NotaEsta opção aplica-se apenas quando um job é iniciado sem estado. Se um job retomar a partir de um checkpoint, a leitura começa pelos offsets armazenados no estado do checkpoint.
scan.startup.specific-offsets
Offset de início por partição quando
scan.startup.modeéspecific-offsets.String
No
–
Por exemplo,
partition:0,offset:42;partition:1,offset:300scan.startup.timestamp-millis
Timestamp de início em milissegundos quando
scan.startup.modeestá definido comotimestamp.Long
No
–
A unidade é milissegundos.
scan.topic-partition-discovery.interval
Intervalo de descoberta de partições.
Duration
No
5 minutes
O conector descobre e lê periodicamente novas partições. Ao usar topic-pattern, o conector também detecta novos tópicos que correspondam ao padrão. Defina o intervalo como um valor não positivo para desativar este recurso.
NotaNo Ververica Runtime (VVR) 6.0.x, a descoberta dinâmica de partições está desativada por padrão. A partir do VVR 8.0, este recurso é ativado por padrão com um intervalo de descoberta de 5 minutos.
scan.header-filter
Filtra mensagens com base nos cabeçalhos da mensagem Kafka.
String
No
–
A chave e o valor do cabeçalho são separados por dois-pontos (:). Múltiplas condições de cabeçalho são conectadas por operadores lógicos (& e |). O operador lógico NOT (!) também é suportado. Por exemplo,
depart:toy|depart:book&!env:testretém os dados Kafka se o cabeçalho contiverdepart=toyoudepart=booke não contiverenv=test.Nota-
Esta opção é suportada apenas no Ververica Runtime (VVR) 8.0.6 e versões posteriores.
-
Parênteses em expressões não são suportados.
-
As operações lógicas são avaliadas da esquerda para a direita.
-
Os valores dos cabeçalhos são convertidos para strings UTF-8 para comparação.
scan.check.duplicated.group.id
Verifica se outro consumidor ativo já está usando o
properties.group.id.Boolean
No
false
Valores válidos:
-
true: Antes de iniciar o job, o sistema verifica a existência de um grupo de consumidores duplicado. Se encontrado, o job falha para evitar conflitos.
-
false: Inicia o job sem verificar conflitos.
NotaEsta opção é suportada apenas no Ververica Runtime (VVR) 6.0.4 e versões posteriores.
-
-
Sink table
Option
Description
Type
Required
Default
Remarks
topic
Tópico de destino.
String
Yes
–
–
sink.partitioner
Mapeia registros de instâncias paralelas do sink para partições Kafka.
String
No
default
Valores válidos:
-
default: Usa o particionador padrão do Kafka. -
### **Confirmação de offsets do source**
A tabela source do Kafka confirma o offset do consumidor no cluster Kafka somente após um checkpoint bem-sucedido. Por isso, intervalos longos de checkpoint fazem com que o offset confirmado fique defasado. O progresso real de leitura fica armazenado no estado do checkpoint, que o sistema utiliza para recuperação de falhas. Os offsets confirmados servem apenas como monitor de progresso e não são usados na recuperação — portanto, falhas de confirmação não afetam a precisão dos dados.
### **Partitioner customizado para sink**
Se a estratégia de particionamento nativa do Kafka não atender às suas necessidades, implemente um partitioner customizado estendendo a classe [FlinkKafkaPartitioner](https://github.com/apache/flink-connector-kafka/blob/369e7be46a70fd50d68746498aed82105741e7d6/flink-connector-kafka/src/main/java/org/apache/flink/streaming/connectors/kafka/partitioner/FlinkKafkaPartitioner.java). Após o desenvolvimento, compile o código em um pacote JAR e faça o upload usando o recurso [Artifacts](t2740613.xdita#) no console do Realtime Compute. Com o pacote JAR carregado e referenciado, defina o parâmetro sink.partitioner na cláusula WITH com o nome completo e qualificado da sua classe de partitioner, por exemplo, `org.mycompany.MyPartitioner`.
### **Kafka, Upsert Kafka e Kafka JSON catalog**
O Kafka é uma plataforma de streaming de eventos append-only que não suporta atualizações nem exclusões de dados. Em SQL de streaming, uma tabela sink Kafka padrão não consegue lidar com dados de Change Data Capture (CDC) provenientes de upstream nem com a lógica de retração de operadores como aggregate e join. Quando for necessário gravar dados que contenham alterações ou retrações, utilize uma tabela sink [Upsert Kafka](t2306784.dita#concept_2306784).
Para simplificar a sincronização em lote de dados de Change Data Capture (CDC) de uma ou mais tabelas de banco de dados upstream para o Kafka, use um Kafka JSON catalog. Se os dados armazenados no Kafka estiverem em formato JSON, o Kafka JSON catalog permite pular a etapa de definição de schema e dos parâmetros WITH. Consulte [Manage Kafka JSON catalogs](t2212019.dita#task_2159375) para mais detalhes.
### **Exemplos**
#### **Exemplo 1: Leitura e escrita no Kafka**
Este exemplo lê dados de um tópico Kafka de source e os grava em um tópico de sink. Os dados estão no formato CSV.
```sql
CREATE TEMPORARY TABLE kafka_source (
id INT,
name STRING,
age INT
) WITH (
'connector' = 'kafka',
'topic' = 'source',
'properties.bootstrap.servers' = '
', 'properties.group.id' = ' ', 'format' = 'csv' ); CREATE TEMPORARY TABLE kafka_sink ( id INT, name STRING, age INT ) WITH ( 'connector' = 'kafka', 'topic' = 'sink', 'properties.bootstrap.servers' = ' ', 'properties.group.id' = ' ', 'format' = 'csv' ); INSERT INTO kafka_sink SELECT id, name, age FROM kafka_source; ``` #### **Exemplo 2: Sincronização de schema e dados de tabela** Use o conector Kafka para sincronizar mensagens de um tópico Kafka para o Hologres em tempo real. Para evitar mensagens duplicadas no Hologres durante um failover, utilize o offset e o ID de partição das mensagens Kafka como chave primária composta. ```sql 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' = ' ', 'topic' = 'kafka_evolution_demo', 'scan.startup.mode' = 'earliest-offset', 'format' = 'json', 'json.infer-schema.flatten-nested-columns.enable' = 'true' -- Optional. Flattens all nested columns. ); CREATE TABLE IF NOT EXISTS hologres.kafka.`sync_kafka` WITH ( 'connector' = 'hologres' ) AS TABLE vvp.`default`.kafkaTable; ``` #### **Exemplo 3: Sincronização de chaves e valores do Kafka** Se a chave de uma mensagem Kafka contiver informações relevantes, sincronize tanto a chave quanto o valor. ```sql CREATE TEMPORARY TABLE kafkaTable ( `key_id` INT NOT NULL, `val_name` VARCHAR(200) ) WITH ( 'connector' = 'kafka', 'properties.bootstrap.servers' = ' ', '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; ``` #### **Exemplo 4: Sincronização de dados com transformações** Ao sincronizar dados do Kafka para o Hologres, pode ser necessário aplicar transformações leves. ```sql 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' = 'NotaAs chaves de mensagens do Kafka não suportam Schema Evolution nem análise automática de tipos. Declare o schema manualmente.
', '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'); --Use COALESCE to handle null values. ``` #### **Exemplo 5: Análise de JSON aninhado** A seguir, um exemplo de mensagem JSON: ```json { "id": 101, "name": "VVP", "properties": { "owner": "Alibaba Cloud", "engine": "Flink" } } ``` Para evitar o uso de funções como `JSON_VALUE(payload, '$.properties.owner')` para analisar campos, defina a estrutura diretamente no DDL do Source: ```sql 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' ); ``` Com essa abordagem, o Flink analisa o JSON em campos estruturados durante a fase de leitura. As consultas SQL subsequentes podem referenciar diretamente `properties.owner` sem chamadas adicionais de funções, o que melhora o desempenho geral. ## Semântica exactly-once Configure o nível de isolamento do consumidor Todas as aplicações que consomem dados do Kafka devem definir a propriedade
isolation.level:read_committed: Lê apenas dados confirmados.read_uncommitted(Padrão): Permite a leitura de dados não confirmados.
O modo EXACTLY_ONCE depende de `read_committed`. Sem essa configuração, os consumidores podem enxergar dados não confirmados, comprometendo a consistência.
Timeout de transação e perda de dados Ao recuperar de um checkpoint, o Realtime Compute for Apache Flink considera apenas as transações confirmadas antes do início daquele checkpoint. Se o intervalo entre a falha do job e sua reinicialização exceder o timeout de transação do Kafka, o Kafka aborta automaticamente a transação aberta, podendo resultar em perda de dados. O valor padrão de
transaction.max.timeout.mspara um broker Kafka é de 15 minutos.Por padrão, o Flink Kafka Sink define o parâmetro
transaction.timeout.mscomo 1 hora.Aumente o valor de
transaction.max.timeout.msno broker para que seja maior ou igual à configuração definida no Flink.Pool de produtores e checkpoints concorrentes O modo
EXACTLY_ONCEutiliza um pool de produtores Kafka de tamanho fixo. Cada checkpoint consome um produtor desse pool. Se o número de checkpoints concorrentes exceder o tamanho do pool, o job falhará. Dimensione o pool de produtores com base no número máximo de checkpoints concorrentes.Restrições para redução de paralelismo Se um job falhar antes de o primeiro checkpoint ser concluído, as informações do pool de produtores original serão perdidas na reinicialização. Portanto, não reduza o paralelismo do job antes que o primeiro checkpoint seja concluído. Caso a redução seja inevitável, o novo paralelismo não deve ser inferior a
FlinkKafkaProducer.SAFE_SCALE_DOWN_FACTOR.Transações bloqueiam leituras No modo
read_committed, qualquer transação que não tenha sido confirmada ou abortada bloqueia as operações de leitura em todo o tópico. Por exemplo: A Transação 1 grava dados.A Transação 2 grava mais dados e é confirmada.
Enquanto a Transação 1 permanecer aberta, os dados da Transação 2 — já confirmada — ficam invisíveis para os consumidores.
Esse comportamento traz as seguintes implicações:
Em operação normal, a latência de visibilidade dos dados é aproximadamente igual ao intervalo de checkpoint.
Se um job falhar, qualquer tópico em que ele estivesse gravando ficará bloqueado para os consumidores até que o job seja reiniciado ou a transação expire. Em casos extremos, o próprio processo de expiração da transação também pode afetar as operações de leitura.
## FAQ
How do I retrieve JSON data from Kafka using Realtime Compute for Apache Flink?
Why does an Event Time-based Window produce no output for a ApsaraMQ for Kafka Source Table?
-