最近在帮客户做数据中台迁移时,遇到个典型场景:需要把几十个业务系统的HTTP接口数据实时同步到Doris数仓。刚开始用SeaTunnel配置时,发现看似简单的流程藏着不少"暗坑"。比如有个客户的生产环境接口返回的JSON里嵌套了五层数组,直接用默认配置会导致字段映射完全错乱。
HTTP接口同步最大的特点就是数据结构不可控。不像数据库有明确的schema,REST API返回的JSON可能包含:
更麻烦的是Doris这边的要求:
这就导致源端和目标的"数据类型鸿沟"。我见过最极端的案例是:接口返回的ID是字符串形式的数字(比如"123456"),而Doris表要求BIGINT类型。如果直接在schema里定义BIGINT,同步时会报类型转换错误。
先看一个经过实战检验的HTTP source配置模板:
json复制{
"plugin_name": "Http",
"url": "http://api.example.com/data",
"method": "GET",
"format": "json",
"json_field": {
"user_id": "$.data.items[*].user.id",
"order_amount": "$.data.items[*].amount",
"create_time": "$.data.items[*].timestamp"
},
"schema": {
"fields": {
"user_id": "STRING",
"order_amount": "DECIMAL(18,2)",
"create_time": "TIMESTAMP"
}
}
}
几个关键技巧:
[*]处理数组,比如$.data.items[*].user.id表示提取所有items元素下的user.idurl写成"http://api.example.com/data?page={{page}}&size=100",配合pageing配置遇到过最棘手的问题是字段数量不一致。某次同步时发现10万条数据丢了37条,排查发现是某些记录的address字段缺失。解决方案是在schema里配置默认值:
json复制"schema": {
"fields": {
"address": {
"type": "STRING",
"default_value": "N/A"
}
}
}
这是经过20+项目验证的Doris sink配置模板:
json复制{
"plugin_name": "Doris",
"fenodes": "doris-fe:8030",
"database": "finance",
"table": "transactions",
"username": "loader",
"password": "******",
"sink.enable-2pc": "true",
"save_mode_create_template": "CREATE TABLE IF NOT EXISTS `${database}`.`${table}` (
user_id LARGEINT,
order_amount DECIMAL(18,2),
create_time DATETIME
) ENGINE=OLAP
UNIQUE KEY(user_id, create_time)
DISTRIBUTED BY HASH(user_id)
PROPERTIES (
\"replication_num\" = \"3\",
\"storage_medium\" = \"SSD\",
\"storage_cooldown_time\" = \"7 days\"
)"
}
特别注意:
CAST(user_id AS LARGEINT)转换sink.enable-2pc保证精确一次语义,但需要Doris 1.2+版本save_mode_create_template里的字段顺序要和schema一致,否则会出现"Column count doesn't match"错误| 参数名 | 默认值 | 生产建议值 | 说明 |
|---|---|---|---|
| sink.buffer-size | 8192 | 32768 | 增大可提升吞吐量 |
| sink.buffer-count | 3 | 8 | 并行度设置 |
| sink.flush.interval-ms | 30000 | 10000 | 缩短间隔降低延迟 |
| sink.max-retries | 3 | 5 | 网络不稳定时增加重试次数 |
| sink.parallelism | 1 | 4 | 根据Doris FE节点数调整 |
在某个电商大促项目中,通过调整这些参数,同步性能从最初的5000条/秒提升到3.2万条/秒。关键是要监控Doris的BE节点CPU使用率,当达到70%时就该停止增加并行度。
HTTP接口常见的坑:
推荐在transform阶段统一处理:
json复制{
"plugin_name": "Sql",
"source_table_name": "temp_table",
"result_table_name": "processed_table",
"query": "SELECT
CAST(user_id AS BIGINT) AS user_id,
ROUND(CAST(amount_str AS DECIMAL(18,2)), 2) AS amount,
FROM_UNIXTIME(SUBSTR(ts_str,1,10)) AS create_time
FROM temp_table"
}
问题1:Stream Load返回"Label [xxxx] already used"
"sink.label-prefix": "load-$(date +%s)"问题2:数据类型不匹配报"errCode=2"
SELECT typeof(字段)检查实际类型DATE_FORMAT函数统一格式问题3:同步速度突然下降
streaming_load_rpc_max_alive_time_sec参数log4j2.xml里添加:xml复制<Logger name="org.apache.seatunnel.connectors.seatunnel.http" level="DEBUG"/>
<Logger name="org.apache.seatunnel.connectors.seatunnel.doris" level="TRACE"/>
json复制"sample_count": 100,
"sample_interval": 5000
"job.mode": "BATCH"时,先配置"sink.enable": false测试数据抽取最近帮某金融机构做迁移时,发现凌晨同步总会超时。最后发现是他们Doris集群的夜间合并任务导致。解决方案是调整Doris的cumulative_compaction_min_deltas参数,并在SeaTunnel配置里避开凌晨1-3点执行。