Le connecteur SelectDB intègre Realtime Compute for Apache Flink à ApsaraDB for SelectDB, un entrepôt de données en temps réel entièrement géré et compatible avec Apache Doris sur Alibaba Cloud. Utilisez-le pour créer des pipelines en temps réel qui lisent, écrivent ou recherchent des données dans SelectDB, et pour exécuter une synchronisation complète de base de données dans des jobs d'ingestion de données basés sur YAML.
Fonctionnalités prises en charge :
| Catégorie | Détails |
|---|---|
| Types de table | Table source, table de destination, table de dimension, destination d'ingestion de données |
| Mode d'exécution | Flux et lot |
| Format de données | JSON et CSV |
| Type d'API | DataStream, SQL et jobs YAML d'ingestion de données |
| Prise en charge des mises à jour/suppressions | Oui |
| Métriques de surveillance | Aucune |
Principales fonctionnalités :
Synchronisation complète des données de la base de données
Sémantique exactement une fois (exactly-once) via un commit en deux phases (2PC) — aucun enregistrement dupliqué ou perdu
Compatible avec Apache Doris 1.0 et versions ultérieures
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Realtime Compute for Apache Flink avec Ververica Runtime (VVR) 8.0.10 ou version ultérieure
Une instance ApsaraDB for SelectDB. Consultez la rubrique Créer une instance.
Une liste d'autorisation d'adresses IP configurée sur l'instance. Consultez la rubrique Configurer une liste d'autorisation.
Configurer le connecteur
Le connecteur SelectDB est intégré à VVR 11.1 et aux versions ultérieures ; aucune installation manuelle n'est requise.
Pour les versions VVR 8.0.10 à 11.0, installez le connecteur manuellement :
Téléchargez le package JAR depuis Maven Central (versions Flink 1.15–1.17).
Importez le fichier JAR dans votre console de développement Realtime Compute for Apache Flink. Consultez la rubrique Gérer les connecteurs personnalisés.
Référencez le connecteur dans votre job SQL en utilisant
'connector' = 'doris'.
SQL
Syntaxe
Les trois types de table (source, destination et dimension) partagent la même syntaxe DDL. Spécifiez le rôle de la table via les paramètres que vous incluez.
Pour utiliser SelectDB comme table source, activez d'abord la connexion directe au cluster. Dans la console ApsaraDB for SelectDB, accédez à Instance Details > Network Information et cliquez sur Enable Direct Cluster Connection . Cette opération active le protocole Arrow Flight SQL pour des lectures parallèles à haut débit.
CREATE TABLE selectdb_source (
order_id BIGINT,
user_id BIGINT,
total_amount DECIMAL(10, 2),
order_status TINYINT,
create_time TIMESTAMP(3),
product_name STRING
) WITH (
'connector' = 'doris',
'fenodes' = 'selectdb-cn-*******.selectdbfe.rds.aliyuncs.com:8080',
'table.identifier' = 'shop_db.orders',
'username' = 'admin',
'password' = '****'
);
Paramètres
Général
| Paramètre | Obligatoire | Par défaut | Description |
|---|---|---|---|
connector |
Oui | — | Défini sur doris. |
fenodes |
Oui | — | Endpoint HTTP de l'instance SelectDB : <Adresse VPC ou Adresse publique>:<Port du protocole HTTP>. Obtenez ces deux valeurs depuis Instance Details > Network Information dans la console SelectDB. Exemple : selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080. |
jdbc-url |
Non | — | Chaîne de connexion Java Database Connectivity (JDBC) pour les recherches dans les tables de dimension et les requêtes de métadonnées : jdbc:mysql://<Adresse VPC ou Adresse publique>:<Port du protocole MySQL>. Exemple : jdbc:mysql://selectdb-cn-***.selectdbfe.rds.aliyuncs.com:9030. |
table.identifier |
Oui | — | Table cible au format <base_de_données>.<table>. Exemple : db.tbl. |
username |
Oui | — | Nom d'utilisateur de la base de données. Réinitialisez le mot de passe depuis le coin supérieur droit de la page Instance Details si nécessaire. |
password |
Oui | — | Mot de passe associé au nom d'utilisateur de la base de données. |
doris.request.retries |
Non | 3 |
Nombre de tentatives pour les requêtes ayant échoué. |
doris.request.connect.timeout |
Non | 30s |
Délai d'expiration de la connexion. |
doris.request.read.timeout |
Non | 30s |
Délai d'expiration de la lecture. |
Table source
| Paramètre | Obligatoire | Par défaut | Description |
|---|---|---|---|
doris.request.query.timeout |
Non | 21600s |
Délai d'expiration de la requête (6 heures par défaut). |
doris.request.tablet.size |
Non | 1 |
Nombre de tablettes par partition. Des valeurs plus faibles augmentent le parallélisme Flink, mais exercent une pression accrue sur la base de données. |
doris.batch.size |
Non | 4064 |
Nombre maximal de lignes lues depuis un nœud Backend (BE) par requête. Augmentez cette valeur pour réduire la surcharge de connexion et la latence réseau. |
doris.exec.mem.limit |
Non | 8192mb |
Limite de mémoire par requête en octets (8 Go par défaut). |
source.use-flight-sql |
Non | false |
Aucune configuration n'est requise : l'activation de l'option Direct Cluster Connection dans la console SelectDB active automatiquement Arrow Flight SQL. |
source.flight-sql-port |
Non | — | Port Arrow Flight SQL (arrow_flight_sql_port) du nœud Frontend (FE). |
Table de destination
Le mode d'écriture influe sur les garanties de livraison et le comportement de vidage. Choisissez en fonction de vos exigences de cohérence :
| Écriture en flux | Écriture par lots | |
|---|---|---|
| Condition de déclenchement | Suit les intervalles de point de contrôle Flink | Vidage périodique selon le volume de données ou un seuil temporel |
| Garantie de livraison | Exactement une fois (via 2PC) | Au moins une fois ; atteignez l'idempotence avec le modèle Unique |
| Latence | Limitée par l'intervalle de point de contrôle | Flexible, indépendante des points de contrôle |
| Tolérance aux pannes | Récupération complète de l'état Flink | S'appuie sur la déduplication du modèle Unique |
| Paramètre | Obligatoire | Par défaut | Description |
|---|---|---|---|
sink.label-prefix |
Non | — | Préfixe d'étiquette pour les importations Stream Load. Doit être globalement unique pour tous les jobs : la même étiquette ne peut être validée qu'une seule fois. Requis pour garantir la sémantique exactement une fois lors des redémarrages de job. |
sink.properties.* |
Non | — | Paramètres d'importation Stream Load transmis directement à l'API Stream Load de SelectDB. Voir les exemples ci-dessous. |
sink.enable-delete |
Non | true |
Propage les opérations DELETE. Nécessite que la suppression par lots soit activée sur la table Doris et fonctionne uniquement avec le modèle Unique. |
sink.enable-2pc |
Non | true |
Active le commit en deux phases (2PC) pour la sémantique exactement une fois. Consultez la documentation Explicit Transaction Operations. |
sink.buffer-size |
Non | 1 MB |
Taille du tampon de cache d'écriture en octets. Conservez la valeur par défaut. |
sink.buffer-count |
Non | 3 |
Nombre de tampons de cache d'écriture. Conservez la valeur par défaut. |
sink.max-retries |
Non | 3 |
Nombre maximal de tentatives après un échec de validation. |
sink.enable.batch-mode |
Non | false |
Bascule vers le mode d'écriture par lots. Le vidage est contrôlé par les trois paramètres sink.buffer-flush.* ci-dessous plutôt que par les points de contrôle. La sémantique exactement une fois n'est pas garantie ; utilisez le modèle Unique pour l'idempotence. |
sink.flush.queue-size |
Non | 2 |
Taille de la file d'attente du cache en mode lot. |
sink.buffer-flush.max-rows |
Non | 500000 |
Nombre maximal de lignes par vidage en mode lot. |
sink.buffer-flush.max-bytes |
Non | 100 MB |
Nombre maximal d'octets par vidage en mode lot. |
sink.buffer-flush.interval |
Non | 10s |
Intervalle de vidage en mode lot. |
sink.ignore.update-before |
Non | true |
Ignore les événements update-before provenant de Flink CDC. |
**Exemples pour sink.properties.* :**
Format CSV :
'sink.properties.column_separator' = ','
-- If values may contain commas, use a non-printable separator:
-- 'sink.properties.column_separator' = '\x01'
Format JSON :
'sink.properties.format' = 'json',
'sink.properties.read_json_by_line' = 'true'
-- Alternatively: 'sink.properties.strip_outer_array' = 'true'
Table de dimension
| Paramètre | Obligatoire | Par défaut | Description |
|---|---|---|---|
lookup.cache.max-rows |
Non | -1 |
Nombre maximal de lignes dans le cache de recherche. -1 désactive la mise en cache. |
lookup.cache.ttl |
Non | 10s |
Durée de vie (TTL) des entrées du cache. |
lookup.max-retries |
Non | 1 |
Tentatives après l'échec d'une requête de recherche. |
lookup.jdbc.async |
Non | false |
Active la recherche asynchrone. |
lookup.jdbc.read.batch.size |
Non | 128 |
Taille maximale du lot par requête en mode de recherche asynchrone. |
lookup.jdbc.read.batch.queue-size |
Non | 256 |
Taille de la file d'attente du tampon intermédiaire en mode de recherche asynchrone. |
lookup.jdbc.read.thread-size |
Non | 3 |
Nombre de threads de recherche JDBC par tâche en mode de recherche asynchrone. |
Exemples
Table source
CREATE TEMPORARY TABLE selectdb_source (
order_id BIGINT,
user_id BIGINT,
total_amount DECIMAL(10, 2),
order_status TINYINT,
create_time TIMESTAMP(3),
product_name STRING
) WITH (
'connector' = 'doris',
'fenodes' = 'selectdb-cn-*******.selectdbfe.rds.aliyuncs.com:8080',
'table.identifier' = 'shop_db.orders',
'username' = 'admin',
'password' = '****'
);
Table de destination
CREATE TEMPORARY TABLE selectdb_sink (
order_id BIGINT,
user_id BIGINT,
total_amount DECIMAL(10, 2),
order_status TINYINT,
create_time TIMESTAMP(3),
product_name STRING
) WITH (
'connector' = 'doris',
'fenodes' = 'selectdb-cn-*******.selectdbfe.rds.aliyuncs.com:8080',
'table.identifier' = 'shop_db.orders',
'username' = 'admin',
'password' = '****',
'sink.label-prefix' = 'flink_orders' -- Must be globally unique across jobs
);
Table de dimension
SelectDB agit comme une table de dimension de recherche jointe à une table de faits en flux.
-- Fact table from Kafka
CREATE TEMPORARY TABLE fact_table (
`id` BIGINT,
`name` STRING,
`city` STRING,
`process_time` AS proctime()
) WITH (
'connector' = 'kafka',
...
);
-- Dimension table from SelectDB
CREATE TEMPORARY TABLE dim_city (
`city` STRING,
`level` INT,
`province` STRING,
`country` STRING
) WITH (
'connector' = 'doris',
'fenodes' = 'selectdb-cn-*******.selectdbfe.rds.aliyuncs.com:8080',
'jdbc-url' = 'jdbc:mysql://selectdb-cn-***.selectdbfe.rds.aliyuncs.com:9030',
'table.identifier' = 'dim.dim_city',
'username' = 'admin',
'password' = '****'
);
-- Temporal join
SELECT a.id, a.name, a.city, c.province, c.country, c.level
FROM fact_table a
LEFT JOIN dim_city FOR SYSTEM_TIME AS OF a.process_time AS c
ON a.city = c.city;
Ingestion de données
Utilisez le connecteur SelectDB comme destination dans des jobs d'ingestion de données basés sur YAML pour la synchronisation complète de la base de données.
Syntaxe
source:
type: <source-type>
sink:
type: doris
name: Doris Sink
fenodes: selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080
username: root
password: ""
Paramètres
| Paramètre | Obligatoire | Par défaut | Description |
|---|---|---|---|
type |
Oui | — | Défini sur doris. |
name |
Non | — | Nom descriptif de la destination. |
fenodes |
Oui | — | Endpoint HTTP : <Adresse VPC ou Adresse publique>:<Port du protocole HTTP>. Obtenez ces deux valeurs depuis Instance Details > Network Information dans la console SelectDB. Exemple : selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080. |
jdbc-url |
Non | — | Chaîne de connexion JDBC. Exemple : jdbc:mysql://selectdb-cn-***.selectdbfe.rds.aliyuncs.com:9030. |
username |
Oui | — | Nom d'utilisateur de la base de données. |
password |
Oui | — | Mot de passe associé au nom d'utilisateur de la base de données. |
sink.enable.batch-mode |
Non | true |
Le mode lot est activé par défaut dans les jobs d'ingestion de données. Le vidage est contrôlé par les trois paramètres sink.buffer-flush.* . La sémantique exactement une fois n'est pas garantie ; utilisez le modèle Unique pour l'idempotence. |
sink.flush.queue-size |
Non | 2 |
Taille de la file d'attente du cache. |
sink.buffer-flush.max-rows |
Non | 500000 |
Nombre maximal de lignes par vidage. |
sink.buffer-flush.max-bytes |
Non | 100 MB |
Nombre maximal d'octets par vidage. |
sink.buffer-flush.interval |
Non | 10s |
Intervalle de vidage. Minimum : 1s. |
sink.properties.* |
Non | — | Paramètres d'importation Stream Load. |
**Exemples pour sink.properties.* :**
Format CSV :
sink.properties.column_separator: ','
# If values may contain commas, use a non-printable separator:
# sink.properties.column_separator: '\x01'
Format JSON :
sink.properties.format: 'json'
sink.properties.read_json_by_line: 'true'
Exemples
Les exemples suivants couvrent des scénarios courants d'ingestion de données. Remplacez les endpoints, noms d'utilisateur et mots de passe génériques par vos valeurs réelles.
La syntaxe ${secret_values.nom_variable} fait référence à une variable secrète créée dans votre espace de travail. Pour plus d'informations, consultez la rubrique Gérer les variables. Pour une description complète des paramètres source, consultez les rubriques Connecteur YAML MySQL et Connecteur CDC Postgres.
Le connecteur ne crée pas les bases de données de destination. Avant de commencer, créez les bases de données de destination utilisées dans les exemples suivants dans votre instance ApsaraDB for SelectDB. Les tables de destination sont créées automatiquement si elles n'existent pas.
Synchronisation d'une seule table
Synchronisez une seule table MySQL vers SelectDB. La table de destination est créée automatiquement si elle n'existe pas.
source:
type: mysql
name: MySQL Source
hostname: <yourHostname>
port: 3306
username: ${secret_values.mysql_username}
password: ${secret_values.mysql_password}
tables: test_db.test_source_table
server-id: 5401-5499
# (Optional) Synchronize the existing full data first, and then the incremental data.
scan.startup.mode: initial
sink:
type: doris
name: SelectDB Sink
fenodes: selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080
jdbc-url: jdbc:mysql://selectdb-cn-****.selectdbfe.rds.aliyuncs.com:9030
username: ${secret_values.selectdb_username}
password: ${secret_values.selectdb_password}
pipeline:
name: MySQL to SelectDB Pipeline
Synchronisation complète de la base de données
Synchronisez toutes les tables d'une base de données MySQL vers SelectDB. Les noms des bases de données et des tables en aval sont identiques à ceux en amont. Les tables de destination sont créées automatiquement si elles n'existent pas.
source:
type: mysql
name: MySQL Source
hostname: <yourHostname>
port: 3306
username: ${secret_values.mysql_username}
password: ${secret_values.mysql_password}
# Matches all tables in the test_db database.
tables: test_db.\.*
server-id: 5401-5499
scan.startup.mode: initial
# (Optional) Synchronize tables that are created during the incremental phase without restarting the job.
scan.binlog.newly-added-table.enabled: true
sink:
type: doris
name: SelectDB Sink
fenodes: selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080
jdbc-url: jdbc:mysql://selectdb-cn-****.selectdbfe.rds.aliyuncs.com:9030
username: ${secret_values.selectdb_username}
password: ${secret_values.selectdb_password}
# (Optional) The flush interval for batch writing. Lower this value for small workloads so that data is not held in the buffer for too long.
sink.buffer-flush.interval: 10s
pipeline:
name: MySQL to SelectDB Pipeline
Exclusion de tables de la synchronisation complète de la base de données
Ignorez les tables que vous ne souhaitez pas synchroniser, telles que les tables temporaires et les tables de journal. Sans module de routage, les données sont écrites dans la table de destination portant le même nom que la table source.
source:
type: mysql
name: MySQL Source
hostname: <yourHostname>
port: 3306
username: ${secret_values.mysql_username}
password: ${secret_values.mysql_password}
tables: test_db.\.*
# Tables that match this regular expression are not synchronized. Separate multiple regular expressions with commas (,).
tables.exclude: test_db.tmp_\.*, test_db.log_\.*
server-id: 5401-5499
scan.startup.mode: initial
sink:
type: doris
name: SelectDB Sink
fenodes: selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080
jdbc-url: jdbc:mysql://selectdb-cn-****.selectdbfe.rds.aliyuncs.com:9030
username: ${secret_values.selectdb_username}
password: ${secret_values.selectdb_password}
pipeline:
name: MySQL to SelectDB Pipeline
Synchronisation vers des bases de données et des tables spécifiques
Utilisez le module de routage pour renommer les destinations lorsque les noms des bases de données ou des tables en aval diffèrent de ceux en amont. L'exemple suivant synchronise les tables de test_db vers la base de données ods_db et ajoute le préfixe ods_ à chaque nom de table. Par exemple, test_db.orders est synchronisé vers ods_db.ods_orders.
source:
type: mysql
name: MySQL Source
hostname: <yourHostname>
port: 3306
username: ${secret_values.mysql_username}
password: ${secret_values.mysql_password}
tables: test_db.\.*
server-id: 5401-5499
scan.startup.mode: initial
sink:
type: doris
name: SelectDB Sink
fenodes: selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080
jdbc-url: jdbc:mysql://selectdb-cn-****.selectdbfe.rds.aliyuncs.com:9030
username: ${secret_values.selectdb_username}
password: ${secret_values.selectdb_password}
route:
# <> is a placeholder that is replaced with the matched source table name.
- source-table: test_db.\.*
sink-table: ods_db.ods_<>
replace-symbol: <>
pipeline:
name: MySQL to SelectDB Pipeline
Fusion de tables fragmentées
Fusionnez plusieurs tables fragmentées partageant le même schéma en une seule table SelectDB. L'exemple suivant utilise le module de transformation pour ajouter une colonne identifiant la base de données et la table sources, puis utilise cette colonne avec la clé primaire métier comme clé primaire composite afin de pouvoir retracer l'origine des données fusionnées.
source:
type: mysql
name: MySQL Source
hostname: <yourHostname>
port: 3306
username: ${secret_values.mysql_username}
password: ${secret_values.mysql_password}
# Matches all shards, such as order_db_1.orders_1 and order_db_2.orders_2.
tables: order_db_\d+.orders_\d+
server-id: 5401-5499
scan.startup.mode: initial
sink:
type: doris
name: SelectDB Sink
fenodes: selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080
jdbc-url: jdbc:mysql://selectdb-cn-****.selectdbfe.rds.aliyuncs.com:9030
username: ${secret_values.selectdb_username}
password: ${secret_values.selectdb_password}
# Set this parameter to false when the downstream primary key differs from the upstream one. Otherwise, the rows that correspond to the old primary key are not deleted.
sink.ignore.update-before: false
transform:
- source-table: order_db_\d+.orders_\d+
# Append the src_table column that identifies the source database and table.
projection: "*, __schema_name__ || '.' || __table_name__ AS src_table"
# The composite primary key must be the same as the key columns of the destination table.
primary-keys: order_id, src_table
description: Append the source identifier and set a composite primary key
route:
# Merge all shards into a single table.
- source-table: order_db_\d+.orders_\d+
sink-table: dw_db.merged_orders
pipeline:
name: MySQL sharding to SelectDB Pipeline
Filtrage des données et élagage des colonnes
Utilisez le module de transformation pour filtrer les données et élaguer les colonnes. La condition de filtre est évaluée sur les champs de la table source pour décider si un enregistrement est synchronisé, et la projection détermine quelles colonnes sont écrites dans la table en aval.
source:
type: mysql
name: MySQL Source
hostname: <yourHostname>
port: 3306
username: ${secret_values.mysql_username}
password: ${secret_values.mysql_password}
tables: test_db.test_source_table
server-id: 5401-5499
scan.startup.mode: initial
sink:
type: doris
name: SelectDB Sink
fenodes: selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080
jdbc-url: jdbc:mysql://selectdb-cn-****.selectdbfe.rds.aliyuncs.com:9030
username: ${secret_values.selectdb_username}
password: ${secret_values.selectdb_password}
transform:
- source-table: test_db.test_source_table
# Synchronize only the records whose order_status is PAID.
filter: "order_status = 'PAID'"
# Write only the following four columns.
projection: order_id, customer_id, total_amount, created_at
primary-keys: order_id
description: Filter by order status and prune columns
pipeline:
name: MySQL to SelectDB Pipeline
Synchronisation complète de la base de données PostgreSQL
Synchronisez toutes les tables d'un schéma PostgreSQL vers SelectDB. Avant de commencer, définissez wal_level sur logical sur l'instance PostgreSQL et assurez-vous que max_replication_slots et max_wal_senders disposent d'une marge suffisante. Pour plus d'informations, consultez la rubrique Configurer une base de données PostgreSQL.
source:
type: postgres
name: PostgreSQL Source
hostname: <yourHostname>
port: 5432
username: ${secret_values.pg_username}
password: ${secret_values.pg_password}
# PostgreSQL table names use the database.schema.table format.
tables: test_db.public.\.*
slot.name: <yourSlotName>
decoding.plugin.name: pgoutput
scan.startup.mode: initial
# (Optional) Use an existing publication instead of creating one when the job starts.
debezium.publication.autocreate.mode: disabled
debezium.publication.name: <yourPublicationName>
sink:
type: doris
name: SelectDB Sink
fenodes: selectdb-cn-****.selectdbfe.rds.aliyuncs.com:8080
jdbc-url: jdbc:mysql://selectdb-cn-****.selectdbfe.rds.aliyuncs.com:9030
username: ${secret_values.selectdb_username}
password: ${secret_values.selectdb_password}
pipeline:
name: PostgreSQL to SelectDB Pipeline
Mappage des types
De Flink vers SelectDB
| Type Flink CDC | Type SelectDB | Notes |
|---|---|---|
TINYINT |
TINYINT |
|
SMALLINT |
SMALLINT |
|
INT |
INT |
|
BIGINT |
BIGINT |
|
DECIMAL |
DECIMAL |
|
FLOAT |
FLOAT |
|
DOUBLE |
DOUBLE |
|
BOOLEAN |
BOOLEAN |
|
DATE |
DATE |
|
TIMESTAMP[(p)] |
DATETIME[(p)] |
|
TIMESTAMP_LTZ[(p)] |
DATETIME[(p)] |
|
CHAR(n) |
CHAR(n*3) |
SelectDB stocke les chaînes en UTF-8. Les caractères anglais occupent 1 octet ; les caractères chinois occupent 3 octets. La longueur maximale de CHAR est de 255 ; les valeurs plus longues sont automatiquement converties en VARCHAR. |
VARCHAR(n) |
VARCHAR(n*3) |
Le même multiplicateur UTF-8 s'applique. La longueur maximale de VARCHAR est de 65533 ; les valeurs plus longues sont automatiquement converties en STRING. |
BINARY(n) |
STRING |
|
VARBINARY(n) |
STRING |
|
STRING |
STRING |