【免费下载链接】mage-ai
🧙 Build, run, and manage data pipelines for integrating and transforming data.
本篇技术指南围绕 Mage 开源项目中 Doris 目标端(Destination)文档展开,系统讲解如何在 Mage 数据集成管道中将 Apache Doris 配置为数据写入端:包括全部连接参数、SSH 隧道直连两种模式、可选配置项、底层建表/写入实现,以及一个可直接套用的 JSON 配置模板。读完本文,你将能够独立完成 Mage → Doris 的整条数据落地链路配置,并理解 Mage 在写入 Doris 时自动执行的建 Schema、建表、补列与数据插入逻辑。
一、Doris 目标端在 Mage 中的定位
Mage 的数据集成(Data Integration)能力将「数据管道」抽象为 Source(源端)与 Destination(目标端)两级。Doris 目标端位于 mage_integrations/mage_integrations/destinations/doris/,负责把上游读取到的记录批量写入 Apache Doris 数据库。
Doris 对外提供 MySQL 兼容协议,因此该目标端在底层复用了大量 MySQL 语义:连接层使用 mysql.connector 建立连接,DDL/DML 语句的构造逻辑也建立在 MySQL 方言之上。你可以从以下几处源码得到印证:
- 目标端实现:destinations/doris/init.py,其中
class Doris(Destination)继承自 destinations/sql/base.py 中的通用 SQL Destination 基类; - 连接层实现:connections/doris/init.py,提供
direct与ssh_tunnel两种连接方式; - 单元测试:tests/destinations/doris/test_doris.py,可作为配置与行为预期的参考。
二、核心配置参数
在 Mage 中配置 Doris 目标端时,必须提供以下凭据与连接信息:
| Key | 说明 | 示例值 | 是否必填 |
|---|---|---|---|
database | 目标 Doris 数据库名称,数据将被写入该库 | demo | ✅ |
host | Doris 服务器的主机名或 IP 地址 | mage.abc.us-west-2.rds.amazonaws.com | ✅ |
port | Doris 监听端口(默认通常为 9030) | 9030 | ✅ |
username | 连接数据库的用户名,须具备对目标 schema 的读写权限 | root | ✅ |
password | 对应用户的密码 | abc123... | ✅ |
table | 目标数据表名,Mage 会按需创建或写入该表 | dim_users_v1 | ✅ |
connection_method | 连接 Doris 服务器的方式:direct 或 ssh_tunnel | direct / ssh_tunnel | ✅ |
ssh_host | (可选)中间跳板机(bastion server)主机 | 123.45.67.89 | ❌ |
ssh_port | (可选)跳板机端口,默认值 22 | 22 | ❌ |
ssh_username | (可选)连接跳板机使用的用户名 | username | ❌ |
ssh_password | (可选)跳板机认证密码,若使用密码认证则需设置 | password | ❌ |
ssh_pkey | (可选)用于连接跳板机的私钥路径或私钥文件内容,若使用私钥认证则需设置 | /path/to/private/key | ❌ |
conn_kwargs | (可选)额外的 MySQL 连接关键字参数,以字典格式传入 | {"ssl_ca": "CARoot.pem", "ssl_cert": "certificate.pem", "ssl_key": "key.pem"} | ❌ |
use_lowercase | (可选)是否将列名统一转为小写 | true / false | ❌ |
参数逐项说明
- database / host / port / username / password:五者共同构成连接 Doris 的凭证基础。
build_connection()在 destinations/doris/init.py 中将这些参数原样传给DorisConnection,其中port使用self.config.get('port')读取,缺省时由连接层回退(连接层默认端口逻辑见下文)。官方 UI 文档 docs/data-integrations/destinations/doris.mdx 将上述字段均标记为必填。 - table:Mage 写入数据的目标表。若表不存在,Mage 会在首个批次自动执行
CREATE TABLE;若已存在,则对比 schema 后执行ALTER TABLE ADD COLUMN补齐新列。 - connection_method:决定连接链路是直连还是经由 SSH 隧道。其枚举值定义在连接层源码中:
ConnectionMethod.DIRECT = "direct"、ConnectionMethod.SSH_TUNNEL = "ssh_tunnel"(见 connections/doris/init.py)。 - ssh_* 系列:仅当
connection_method为ssh_tunnel时生效,用于穿透防火墙或私有网络,安全访问内网中的 Doris。 - conn_kwargs:以字典形式透传给底层 MySQL Connector 的额外参数,典型场景是启用 SSL(
ssl_ca、ssl_cert、ssl_key)或设置其他高级连接选项。 - use_lowercase:控制写入时列名是否统一转为小写。注意它与下面的
lower_case功能重叠,建议保持一致,避免混淆。
三、可选配置
| Key | 说明 | 示例值 |
|---|---|---|
skip_schema_creation | 若为 true,Mage 将不会执行 CREATE SCHEMA 命令(适用于 schema 已存在的场景) | true |
lower_case | 若为 true,Mage 会将所有列名统一转为小写,默认值为 true | true |
二者的实现位置与区别
skip_schema_creation在基类 destinations/sql/base.py 中以self.config.get("skip_schema_creation") is True判定。当设置为true时,export_batch_data会跳过build_create_schema_commands生成的CREATE SCHEMA IF NOT EXISTS ...命令,仅记录日志Skipping CREATE SCHEMA command。lower_case是基类属性use_lowercase的真实数据来源:return self.config.get('lower_case', True)(见 destinations/sql/base.py)。也就是说,配置中的lower_case决定目标端实际是否执行小写化;而 README 表格中的use_lowercase同样会进入 Doris 自身的列名清理逻辑(见 destinations/doris/init.py)。两者作用重叠,官方文档建议保持取值一致。- 在 Doris 的目标端模板配置 templates/config.json 中,默认携带
"use_lowercase": true;单元测试的期望模板 tests/destinations/doris/test_doris.py 也验证了这一点。
四、连接机制:直连与 SSH 隧道
Doris 连接类位于 connections/doris/init.py,核心逻辑集中在 build_connection():
- direct(直连)模式:直接以配置的
host、port、database、username、password调用mysql.connector.connect(...)建立连接。 - ssh_tunnel(SSH 隧道)模式:先构建
SSHTunnelForwarder,将本地端口转发到 Doris 的远端(host, port),随后通过127.0.0.1与本机转发端口建立 MySQL 连接。跳板机认证支持两种方式:- 密码认证:
ssh_password; - 私钥认证:
ssh_pkey,既可以传私钥文件路径(内部用os.path.exists判断后直接使用),也可以传私钥文件内容(内部通过paramiko.RSAKey.from_private_key解析)。
- 密码认证:
实现细节如下:
# 来自 mage_integrations/mage_integrations/connections/doris/__init__.py
if self.connection_method == ConnectionMethod.SSH_TUNNEL:
ssh_setting = dict(ssh_username=self.ssh_username)
if self.ssh_pkey is not None:
if os.path.exists(self.ssh_pkey):
ssh_setting["ssh_pkey"] = self.ssh_pkey
else:
ssh_setting["ssh_pkey"] = paramiko.RSAKey.from_private_key(
io.StringIO(self.ssh_pkey),
)
else:
ssh_setting["ssh_password"] = self.ssh_password
self.ssh_tunnel = SSHTunnelForwarder(
(self.ssh_host, self.ssh_port),
remote_bind_address=(self.host, self.port),
local_bind_address=("", self.port),
**ssh_setting,
)
self.ssh_tunnel.start()
self.ssh_tunnel._check_is_started()
host = "127.0.0.1"
port = self.ssh_tunnel.local_bind_port
连接关闭时,close_connection() 会先关闭 MySQL 连接,再停止并清空 SSH 隧道,确保资源得到释放。
端口回退细节
连接类的构造函数以 self.port = port or 3306 做了回退(见 connections/doris/init.py),即未显式配置端口时默认尝试 3306。但 README 与模板配置均明确建议使用 Doris 的默认端口 9030(模板中默认值即 9030),实操时请务必显式配置,避免回退到 MySQL 默认端口导致连接失败。
五、底层写入实现:建库、建表、补列与插入
Doris 目标端继承通用 SQL Destination 的执行框架,整个导出流程由基类 export_batch_data 编排(destinations/sql/base.py):
- 为首批记录补入
_mage_created_at、_mage_updated_at两个内部时间戳列; - 首个批次时,若未设置
skip_schema_creation,执行CREATE SCHEMA IF NOT EXISTS {database_name}(Doris 目标端把 database 当作 schema 处理); - 检查目标表是否存在(通过查询
information_schema.tables实现,见 destinations/doris/init.py):- 表不存在 → 执行
CREATE TABLE; - 表已存在 → 对比
information_schema.columns与当前 stream 的 schema,找出新增列并执行ALTER TABLE ... ADD COLUMN(源码注释保留TODO: Support alter column types,即暂不支持修改已有列类型);
- 表不存在 → 执行
- 按每批 1000 条(
BATCH_SIZE)构造 INSERT 语句并分批执行提交。
类型映射规则
Doris 目标端在 destinations/doris/utils.py 中定义了 JSON schema 类型到 Doris/MySQL 列类型的映射:
| 源类型(COLUMN_TYPE) | 映射列类型 |
|---|---|
| boolean | CHAR(52) |
| integer | UNSIGNED(建表/补列语句中统一改写为 INTEGER) |
| number | DOUBLE |
| object | JSON |
| string(datetime 格式) | CHAR(52) |
| string(其他) | CHAR(255) |
建表语句同时处理主键与唯一约束:将 stream 的 key_properties 首个字段设置为 PRIMARY KEY,并依据 unique_constraints 生成唯一索引(见 destinations/doris/utils.py)。
插入与冲突处理
build_insert_commands(destinations/doris/init.py)生成 INSERT INTO ... VALUES ... 语句。当配置了 unique_constraints 与冲突方法时:
- 冲突方法为
update(UNIQUE_CONFLICT_METHOD_UPDATE)时,追加AS new与ON DUPLICATE KEY UPDATE col = new.col,实现 MySQL 语义的 upsert; - 其他冲突方法时,改为
INSERT IGNORE INTO ...,跳过重复键记录。
字符串转义上,目标端对 object 类型值执行 ' → ''、\ → \\ 的双重转义,避免写入非法字符。
测试验证
单元测试 tests/destinations/doris/test_doris.py 验证了 CREATE TABLE 语句的构造结果。测试中 schema 为 {"ID": {"type": ["null", "string"]}},配置 lower_case: False,最终生成的建表语句为:
CREATE TABLE test_db.test_table (ID CHAR(255))
该用例同时校验了连接层构造参数(connection_method 默认 direct、ssh_port 默认 22 等),可直接作为排查配置问题的参照。
六、完整配置示例
基于官方模板 templates/config.json,一个最小可用的 Doris 目标端配置如下:
{
"database": "demo",
"host": "mage.abc.us-west-2.rds.amazonaws.com",
"password": "abc123...",
"port": 9030,
"table": "dim_users_v1",
"username": "root",
"use_lowercase": true
}
若 Doris 位于内网、需经跳板机访问,则在上述基础上追加 SSH 隧道参数:
{
"database": "demo",
"host": "10.0.0.10",
"password": "abc123...",
"port": 9030,
"table": "dim_users_v1",
"username": "root",
"connection_method": "ssh_tunnel",
"ssh_host": "123.45.67.89",
"ssh_port": 22,
"ssh_username": "bastion_user",
"ssh_pkey": "/path/to/private/key.pem"
}
需要启用 SSL 时,通过 conn_kwargs 传递 MySQL 兼容的 SSL 参数:
{
"database": "demo",
"host": "mage.abc.us-west-2.rds.amazonaws.com",
"password": "abc123...",
"port": 9030,
"table": "dim_users_v1",
"username": "root",
"conn_kwargs": {
"ssl_ca": "CARoot.pem",
"ssl_cert": "certificate.pem",
"ssl_key": "key.pem"
}
}
若目标库已预先创建,可设置 "skip_schema_creation": true 跳过建库步骤。
七、常见问题与注意事项
- 如何通过 SSH 隧道连接 Doris? 将
connection_method设为ssh_tunnel,并提供ssh_host、ssh_username,再根据认证方式二选一提供ssh_password或ssh_pkey。 - 能否使用私钥认证? 可以。
ssh_pkey既支持私钥文件路径,也支持私钥内容字符串,代码会自动区分。推荐优先使用私钥而非密码。 - Doris 是否支持 SSL? 支持。通过
conn_kwargs传入ssl_ca、ssl_cert、ssl_key等 MySQL 兼容的 SSL 选项即可。 - 表已存在时会怎样? Mage 会先查询
information_schema.columns对比列集合,只为新增列执行ALTER TABLE ADD COLUMN,不会重建既有表;已存在的列类型差异暂不处理。 use_lowercase与lower_case有什么区别? 两者都控制列名小写化:lower_case是基类读取的全局开关(默认true),use_lowercase则用于 Doris 目标端自身的列名清理与 INSERT 语句构造。二者语义重叠,官方建议保持取值一致,避免行为不确定。- 权限要求:连接用户须具备对目标数据库/表的读写权限(包括建表、加列、插入等 DDL/DML 操作)。
- 端口注意:Doris 通常监听
9030;若漏配端口,连接层会回退到 MySQL 默认的3306,导致连接失败,请务必显式配置。
八、延伸阅读
如果你想进一步深入,可继续阅读以下仓库文件:
- Doris 目标端 README(本文主文档)
- Doris 目标端实现
- Doris 建表/补列/类型映射工具函数
- Doris 连接层(直连与 SSH 隧道)
- Doris 保留字列表(列名若命中保留字会被自动加
_前缀) - Doris 目标端单元测试
- 官方 UI 配置文档
- 通用 SQL Destination 基类
【免费下载链接】mage-ai
🧙 Build, run, and manage data pipelines for integrating and transforming data.
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



