平台底座 · 实时链路
架构总览
数据链路层级、组件端口与安全边界。dev 环境用轻量组件模拟生产的 Flink / Doris,调度则用真实 Airflow。
数据链路层级
接入 → Kafka → Flink → MySQL → Doris。本地 dev 用 ID-Mapping 服务 + MySQL 模拟 Flink / Doris;StreamPark / DolphinScheduler / Doris 为生产目标组件,调度由真实 Apache Airflow 承载。
┌─ L1 · 接入层(数据入口)
│ 小程序 / 企微 / 表单 / App / 批量导入 API
│ 统一封装为 UserEvent(tenant_id + channel + link_keys + properties)
▼
┌─ L2 · Kafka 消息层(事件总线)
│ tenant-{id}-events(大租户独立 Topic) · shared-tenant-events(微租户共享)
│ 按 tenant_id / channel_id 分区,保证同一用户事件有序
▼
┌─ L3 · Flink 实时计算层(StreamPark 管控)
│ Job-1 ID-Mapping(OneID 识别/merge) → Job-2 画像聚合 → Job-3 宽表打宽
│ 输出 enriched-events,并行写入下游存储
▼
┌─ L3+ · Redis 热层(旁路,< 5ms 点查)
│ Flink Job-1 同步写入 channel → one_id 映射,供实时识别/热点查询
▼
┌─ L4 · MySQL 业务冷层(持久化/审计)
│ one_id 发号器 · id_mapping 离线导入 · merge_log 合并审计 · 租户配置
▼
└─ L5 · Doris OLAP 层(画像/圈选)
id_mapping · user_profile · user_wide
大租户独立库 + BE Tag,小租户共享库 tenant_id 分区
── 查询层(只读)── SQL Engine + 数据 Agent ← 业务应用 / MA / BI
── 调度管控层(K8s)── StreamPark:Flink 启停扩缩 · DolphinScheduler:离线/批标签/运维
(dev 用 Apache Airflow 承载「可视化编排 Pipelines」的真实调度)前端技术栈:React 18 + Vite + TypeScript + TailwindCSS(TailAdmin 风格、Segment 信息架构)。数据链路:浏览器 /api/* →(dev: vite 代理 / 生产: nginx)→ SQL Engine :8002 → MySQL,毫秒级实时查询。
组件与端口
所有访问统一经 Nginx 网关 :8080;直连端口仅用于调试。
| 组件 | 端口 | 角色 |
|---|---|---|
| Nginx 网关 | 8080 | / 首页、/console/ CDP SPA、/api/* → sql-engine、Swagger 代理 |
| 控制台(前端) | 8080/console/ | 对标 Segment 的 React SPA(生产);dev 用 5173 |
| SQL Engine | 8002 | OLAP 查询层 + Agent(模板 SQL + DSL 圈人 + NL 圈人 + 只读 MCP) |
| ID-Mapping | 8001 | 实时合并服务 API(OneID 识别 / merge / 画像查询) |
| MySQL 8 | 3308 | 业务库:id_mapping / user_profile / user_groups / merge_log / object_* |
| Redis 7 | 6381 | OneID 热缓存 |
| Kafka / Kafka UI | 9094 / 8083 | 多租户事件总线 / Topic 可视化 |
| Airflow | 8088 | 「可视化编排」真实调度后端(admin/admin),经 REST API 触发 DAG |
| 智能助手 assistant | 8004 | 多智能体:路由 → 数据查询/分析/任务/通用 |

标注约定 · 真实 = 走 SQL Engine → MySQL 的实时查询,操作即落库;Mock = 纯前端演示数据(页面右上有「Mock 数据」角标),后端尚未接入(路线图)。
安全边界
LLM 绝不直出 SQL。 圈人 / 查询走
engine.py 模板 + 参数绑定,或 dsl.py 的 validate → echo → compile → estimate 路径——候选 DSL 必须先过校验层(字段 / 操作符 / 关系 / 跳数)才会被展示或执行。存储经 executor.py 解耦,可用 OLAP_BACKEND 在 MySQL / Doris 间切换。