智驾数据闭环湖仓实战:StarRocks + Paimon 双路查询架构
发布时间:2026/9/14 21:46:54 作者:尧图编辑部 阅读量:1,286

上一篇我们把 79 张表的命名、分区、Bucket 设计讲完了有读者问了一个非常实际的工程问题「数据都在 Paimon 湖仓里但闭环大盘要毫秒级响应、训练平台点查难例库要随机圈选——查询引擎到底怎么查湖全部导进 StarRocks还是直接查外部表」这其实是湖仓架构落地时绕不开的选型难题全量导入内表查询快但数据冗余、同步链路复杂、一致性难保证全部外部表直查零冗余零同步但高频查询场景的性能撑不住业务平台的 SLA。我们的答案是——不做二选一按查询模式分层走「External Catalog ADS 内表物化」双路架构即席查询、明细下钻、跨域 JOIN 走外部表直查高频数据产品查询物化为 StarRocks 内表毫秒级直查。本文完整拆解这套架构的设计决策、建表原则、物化作业与权限边界。一、问题本质湖仓存得下但业务等不起先看智驾数据闭环的查询场景画像——同一个湖仓要同时服务五类平台查询模式差异极大平台典型查询查询模式延迟要求数据管理平台单条数据全链路状态追溯主键点查、低频秒级可接受训练平台难例库圈选、数据集版本对比高频点查 条件圈选毫秒级评测平台模型版本对比、Badcase 明细聚合分析、中频秒级可接受业务大屏闭环大盘、热力图、成本看板高频聚合查询毫秒级问题分析平台Badcase 回溯、触发事件下钻即席查询、跨表 JOIN秒级可接受如果只选一条路必然顾此失彼方案优点致命缺点全部外部表直查零数据冗余、零同步链路、永远查最新高频聚合查询性能撑不住大屏毫秒级 SLA全部导入内表查询性能拉满、毫秒级响应79 张表全量复制冗余成本高、一致性难保证 关键洞察选型的核心不是「湖快还是内表快」而是按查询模式分层——低频、灵活、探索式的查询走外部表高频、固定、面向产品的查询走内表。查询模式决定出口而不是数据层级决定出口。二、双路查询架构全景统一查询 · 双路出口整体架构遵循一个原则所有平台统一走 StarRocks 查询由 StarRocks 在内部做双路分流——路一External Catalog 直查ODS/DWD/DWS 层经paimon_catalog直查 Paimon数据已在湖仓统一管理无需搬运适合即席查询与全链路追溯路二ADS 内表直查ADS 层 10 张ads_*表由 StarRocks 离线加工并物化为内表承载毫秒级快速直查服务业务大屏与训练平台高频场景。这里必须澄清一个最容易搞混的问题——Paimon 侧也有 ads_* 表那它和 StarRocks 内表是什么关系Paimon 侧 ads_* 表 单一事实源StarRocks 内表 查询加速副本。一切加工逻辑以湖仓侧为准内表只服务毫秒级查询不回写、不作为事实源。这个主从关系决定了三件事血缘登记以 Paimon 侧表为节点对账校验以湖仓侧数据为基准物化失败兜底时降级查询读的是 Paimon 侧的 ads 表而不是别的来源。三、路一External Catalog 直查——一条 DDL 打通湖仓3.1 创建 Paimon CatalogExternal Catalog 的本质是把 Paimon 的元数据DLF和数据文件OSS注册进 StarRocks之后所有 Paimon 表都可以像本地表一样用 SQL 访问-- 创建 Paimon External Catalog阿里云 DLF OSS CREATE EXTERNAL CATALOG paimon_catalog PROPERTIES ( type paimon, -- 元数据DLF 目录 metastore dlf, dlf.region cn-hangzhou, -- 数据OSS 湖仓目录 paimon.catalog.warehouse oss://intelligent-driving-lakehouse/paimon/, -- 本地缓存100GBTTL 1 小时 cache.enabled true, cache.size 107374182400, cache.ttl 3600 );配置完成后SHOW TABLES FROM paimon_catalog.dwd即可看到湖仓侧全部 79 张表无需任何数据搬运。3.2 典型查询主键点查全链路状态数据管理平台最高频的场景是「一条数据现在走到哪一步了」。得益于上一篇讲的 data_id 主键设计这就是一次主键查询-- 单条数据全链路状态追溯dwd 层 27 张表以 data_id 串联 SELECT data_id, upload_status, preprocess_status, annotation_status, qc_status, delivery_status, total_production_hours FROM paimon_catalog.dwd.dwd_data_production_chain WHERE data_id COLLECT_BP_20240115143022_a3f8;3.3 让外部表查询跑得快两级裁剪外部表直查的性能密码藏在上一篇讲的物理设计里——分区裁剪 Bucket 裁剪裁剪手段触发条件效果分区裁剪WHERE 条件命中分区键dt / 业务字段只扫目标分区的文件扫描量降几个数量级Bucket 裁剪WHERE 条件命中分桶键如 data_id只扫单个 Bucket点查从秒级降到亚秒⚠️ 实践提醒物理设计是为查询模式服务的——上一篇的分区策略三规则、Bucket 五档本质都是在给这一章的两级裁剪铺路。设计阶段少想一步查询阶段就多花十倍。四、路二ADS 内表物化——10 张表的毫秒级直查4.1 物化范围10 张 ads_* 表Paimon 侧 ADS 层共 10 张表逐表物化为同名 StarRocks 内表。注意物化频率不是拍脑袋——按业务依赖强度分两档SR 内表中文名物化频率ads_closed_loop_dashboard闭环大盘指标表T1ads_production_bottleneck_analysis产线瓶颈分析表T1ads_badcase_root_cause_distributionBadcase 根因分布表T1ads_scene_library_summary场景库汇总表T1ads_hard_case_library难例库表训练平台高频依赖小时级ads_data_asset_catalog数据资产目录表T1ads_model_version_comparison模型版本对比表T1ads_ota_deployment_summaryOTA 部署汇总表T1ads_trigger_heatmap触发事件热力图表T1ads_storage_cost_dashboard存储成本看板表T14.2 建表原则两种模型选对物化才幂等StarRocks 内表不是把 Paimon DDL 抄一遍就行模型选择直接决定物化作业能不能重跑表特征模型选择物化方式带日期统计维度、整分区刷新看板/汇总类明细模型DUPLICATE按 stat_date 分区 INSERT OVERWRITE重跑幂等点查/圈选为主、持续更新难例库、资产目录主键模型PRIMARY KEY全表同步 主键去重幂等 UPSERT两个代表性建表示例分区分桶参照 Paimon 侧 bucket查询热点键参与分桶-- 示例1明细模型闭环大盘按 stat_date 分区增量覆盖 CREATE TABLE ads.ads_closed_loop_dashboard ( stat_date DATENOT NULL, project_code VARCHAR(64) NOT NULL, total_data_count BIGINT, avg_loop_hours DOUBLE, badcase_resolve_rate DOUBLE, update_time DATETIME ) ENGINE OLAP DUPLICATE KEY(stat_date, project_code) PARTITION BY RANGE(stat_date) () DISTRIBUTED BY HASH(project_code) BUCKETS 2 PROPERTIES ( dynamic_partition.enable true, -- 动态分区保留 365 天 dynamic_partition.time_unit DAY, dynamic_partition.start -365 ); -- 示例2主键模型难例库训练平台高频点查/圈选幂等 UPSERT CREATE TABLE ads.ads_hard_case_library ( data_id VARCHAR(128) NOT NULL, hard_case_type VARCHAR(64), difficulty_score DOUBLE, scene_type VARCHAR(64), is_used_in_training BOOLEAN, update_time DATETIME ) ENGINE OLAP PRIMARY KEY(data_id) DISTRIBUTED BY HASH(data_id) BUCKETS 8;4.3 物化作业两条 SQL 覆盖两种模式物化作业由 StarRocks 离线加工调度批处理把 Paimon 侧 ads_* 表同步至内表核心就两种写法-- ① 分区增量覆盖幂等看板类表按 stat_date 覆盖写入重跑不产生重复 INSERT OVERWRITE ads.ads_closed_loop_dashboard PARTITION(p20240115) SELECT stat_date, project_code, total_data_count, avg_loop_hours, ... FROM paimon_catalog.ads.ads_closed_loop_dashboard WHERE stat_date 2024-01-15; -- ② 主键模型幂等 UPSERT难例库类表全表同步主键去重 INSERT INTO ads.ads_hard_case_library SELECT * FROM paimon_catalog.ads.ads_hard_case_library;物化作业的四个工程要点决定了双路架构靠不靠谱设计点策略刷新频率看板/汇总类 T1 凌晨调度难例库等训练平台高频依赖表小时级调度分区增量覆盖按 stat_date 分区 INSERT OVERWRITE同一分区重跑结果幂等支持失败重跑与历史回刷对账校验T1 对账作业比对湖仓侧与内表行数及核心指标总数据量、Badcase 解决率差异超阈值告警并触发重刷失败回退物化失败或数据未就绪时统一查询网关以物化作业账号代理读 External Catalog 兜底业务账号无需直连SLA 优先于延迟五、查询路由与权限边界规则越简单越不容易出错5.1 路由规则一条就够了数据层查询出口适用场景延迟ADS 层StarRocks 内表ads 库闭环大盘、难例库、场景库等开箱即用数据产品毫秒级ODS / DWD / DWSExternal Catalog即席查询、全链路追溯、明细下钻、跨域 JOIN秒级裁剪后可亚秒凡命中 ads_* 表的查询一律路由 StarRocks 内表仅当物化作业失败降级或需回溯 ADS 加工逻辑时才允许查 paimon_catalog.ads兜底路径。5.2 权限设计用授权把路由规则固化下来路由规则不能只写在文档里——用 GRANT 语句把它固化业务账号想违反都没有入口-- 业务账号ODS/DWD/DWS 经 External Catalog 直查ADS 走内表 GRANT SELECT ON paimon_catalog.ods TOdata_platform%; GRANT SELECT ON paimon_catalog.dwd TOdata_platform%; GRANT SELECT ON paimon_catalog.dws TOdata_platform%; GRANT SELECT ON DATABASE ads TOdata_platform%; -- paimon_catalog.ads 仅授予物化作业账号与审计账号 -- 降级兜底由查询网关以 ads_materialize_job 代理读取 GRANT SELECT ON paimon_catalog.ads TOads_materialize_job%; GRANT SELECT ON paimon_catalog.ads TOaudit_account%; 设计意图业务账号直查paimon_catalog.ads会绕过物化加速、且权限边界失控。兜底查询由网关代理执行既保住可用性SLA 优先于延迟又不破坏权限模型。六、性能优化与运维四件套双路架构上线后日常运维主要抓四件事运维项配置要点解决的问题数据缓存scan_data_cache_size10GBTTL 3600s另开 Page 缓存 4GB热点数据免重复拉取重复查询加速资源组隔离按平台划分 Resource Group数据管理 cpu4/并发 20训练 cpu2/并发 10防止单平台大查询拖垮全局保障多租户公平慢查询监控query_time 10s 告警开启 Profile 分析执行计划及时发现缺分区条件、全表扫描类烂 SQL故障排查SHOW CATALOGS / SHOW TABLE STATUS / SHOW PARTITIONS 三连连接失败、元数据不新、分区缺失快速定位⚠️ 高频踩坑「数据不一致」几乎全部是缓存未刷新导致的——先清缓存、再检查 Paimon 表 Compaction 状态不要上来就怀疑同步链路。结语用三句话带走本篇查询模式决定出口——即席查走外部表高频产品查询走内表不做全量导入也不做一刀切单一事实源不动摇——Paimon 侧 ads_* 表是事实源与对账基准StarRocks 内表只是加速副本不回写幂等 对账 兜底——分区覆盖物化可重跑、T1 对账保一致、物化失败网关代理降级查湖仓双路架构才算工程上真正可靠。下篇预告系列二第 4 篇将深入Flink CDC 实时入湖——智驾多源数据接入架构设计拆解 CDC / Kafka / OSS 三通道如何统一入湖、断点续传与 Exactly-Once 语义如何保证。敬请期待。