Appearance
架构与数据流
为什么要换掉「一个数据库当数仓」
旧方案是用 SQL Server 直接做分层存储,本质上把存储、计算、服务压在一个引擎里。数据量小的时候没问题,量级一上来,三个环节会同时报警:
- 接入慢:Kettle 往 SQL Server 灌数,几千万行的文件就要跑很久,失败重跑成本高。
- 计算慢:复杂 SQL、窗口、关联都挤在一个实例里,和业务库争资源。
- 服务慢:BI 报表直连业务库或数仓库,看板一多就互相拖垮。
更关键的是主数据平台要的三件事——血缘、元数据、质量审计——单库方案给不了:表与表的关系散在 ETL 脚本里,字段含义靠人记,出了问题只能翻日志。
所以本方案不是"换一个更快的数据库",而是把数仓拆成各司其职的层:存储只负责持久化,计算按批/流分工,查询按交互式/临时分析分工,治理横切所有层。
设计原则
原则一:对象存储是唯一持久层
所有原始数据、中间数据、结果数据都以开放格式落在对象存储上,对外只暴露 S3 协议。Doris、Elasticsearch、Kafka 里的数据都是可重建的副本或中间态。
这条原则带来三个直接好处:
- 计算引擎可以随便换,数据不用搬。
- 存储与计算独立扩容:存储不够加存储节点,算力不够加计算节点。
- 备份与归档只盯一个地方。
原则二:开放表格式 + 开放目录
Iceberg 规定"数据怎么组织成表",REST Catalog 规定"表在哪、谁能用"。两者都是开放规范,实现可以替换:
- 换目录实现(Polaris → Nessie)只改引擎连接串;
- 换对象存储(Ceph RGW → SeaweedFS)只改 endpoint 与凭证;
- 上层 SQL、BI、调度都不用动。
这是"数据资产不被锁定"的兜底,不是可选优化。
原则三:批流分工,调度收口
- 批量:DataX 接入、Spark 加工、T+1 报表。
- 实时:Flink CDC 接入、Kafka 缓冲、Flink 入湖。
- 调度:DolphinScheduler 统一编排两条链路的依赖、重跑与补数。
不追求"一个引擎干所有事",而是让每条链路用最合适的引擎,再用调度器把边界接起来。
原则四:对外只留一个出口
内部组件一律不直接暴露公网。外部取数走受控网关,在这一层做认证、限流、脱敏、审计;临时分析走 Kyuubi,按需申请 Spark 资源,用完释放。
分层与数据流
数据源 接入 缓冲 加工 存储与组织 查询 应用
┌──────────┐ ┌───────────┐ ┌────────┐ ┌──────────┐ ┌────────────────┐ ┌──────────┐ ┌──────────┐
│ MySQL │─────►│ Flink CDC │──►│ Kafka │──►│ Flink │─────►│ Iceberg │──►│ Doris │────►│ BI 报表 │
│ PG │ └───────────┘ └────────┘ │ (流) │ │ on S3 (Ceph) │ │ (热点副本)│ └──────────┘
│ API/文件 │─────►┌───────────┐ └──────────┘ │ │ └──────────┘
└──────────┘ │ DataX │──────────────────────────────►│ Polaris + PG │──►┌──────────┐ ┌──────────┐
└───────────┘ ┌──────────┐ ┌──────────┐ │ (目录/元数据) │ │ Kyuubi │────►│ 临时分析 │
│ Spark │──►│ 批量加工 │ └────────────────┘ └──────────┘ └──────────┘
└──────────┘ └──────────┘ ▲
┌────┴─────┐
│ 受控网关 │────► 外部系统取数
└──────────┘对应到五层:
| 层 | 组件 | 数据流里的角色 |
|---|---|---|
| 基础资源 | K8s、Harbor、OpenBao、Envoy Gateway、cert-manager | 提供运行环境、镜像、密钥、入口、证书 |
| 数据存储与组织 | Ceph RGW、Iceberg、Polaris、PostgreSQL、Kafka | 持久化数据、组织成表、记录目录、缓冲变更 |
| 加工与接入 | Flink CDC、DataX、Flink、Spark、DolphinScheduler | 把数据搬进来、算出来、按依赖串起来 |
| 查询服务 | Doris、Kyuubi、受控网关 | 加速看板、临时分析、统一取数出口 |
| 治理与可观测 | OpenMetadata、OpenLineage、Prometheus、Grafana、Loki、Alloy、Alertmanager | 元数据与血缘、指标与日志、告警 |
组件清单
| 组件 | 命名空间(建议) | 有状态 | 关键依赖 | 说明 |
|---|---|---|---|---|
| k3s / Kubernetes | kube-system | 是 | — | 测试集群用 kubeadm(1 control-plane + 2 worker),生产用 kubeadm 或托管 K8s |
| Harbor | harbor | 是 | PostgreSQL / Redis / 对象存储 | POC 可先用公网镜像 + 加速,生产必装 |
| OpenBao | security | 是 | 存储后端(Raft / PG) | 密钥管理,替代 Vault |
| cert-manager | cert-manager | 是 | OpenBao(CA) | 证书签发与轮转 |
| Envoy Gateway | gateway | 是 | — | 南北向入口 |
| SeaweedFS / Rook+Ceph | storage | 是 | 数据盘 | POC 用 SeaweedFS,生产用 Ceph RGW |
| PostgreSQL | data | 是 | PVC | Polaris 元数据库、OpenMetadata 元数据库 |
| Polaris | catalog | 是 | PostgreSQL、S3 | Iceberg REST Catalog 实现 |
| Kafka | data | 是 | PVC | KRaft 模式,POC 单节点 |
| Doris | data | 是 | PVC | FE + BE,POC 单 FE 单 BE |
| Spark | compute | 否 | S3、Polaris | 用 Spark Operator 或 spark-submit 提交 |
| Flink | compute | 否 | Kafka、S3、Polaris | Kubernetes Operator 部署 |
| DolphinScheduler | schedule | 是 | PostgreSQL | API / Master / Worker / Alert |
| Kyuubi | query | 否 | Spark、Polaris | Spark SQL 多租户服务 |
| OpenMetadata | governance | 是 | PostgreSQL、Elasticsearch | 元数据、血缘、质量 |
| Elasticsearch | governance | 是 | PVC | 只做 OpenMetadata 的搜索索引 |
| Prometheus / Grafana / Loki / Alloy | monitoring | 是 | PVC | 指标、日志、看板、告警 |
端口与 Service 名称在部署页给出;这里只表达依赖关系,不作为最终清单。
许可与成本
| 组件 | 许可证 | 需要留意 |
|---|---|---|
| Kubernetes / Harbor / Envoy Gateway / cert-manager | Apache-2.0 | 无 |
| OpenBao | MPL-2.0 | 文件级 copyleft,未修改源码则无额外义务 |
| Rook | Apache-2.0 | 无 |
| Ceph | LGPL-2.1(少量 GPL) | 动态链接;未修改源码则无额外义务 |
| SeaweedFS / Iceberg / Polaris / Nessie | Apache-2.0 | 无 |
| PostgreSQL | PostgreSQL License | 类 BSD,宽松 |
| Kafka / Spark / Flink / DataX / DolphinScheduler / Kyuubi | Apache-2.0 | 无 |
| Doris / StarRocks | Apache-2.0 | StarRocks 部分企业特性为商业版 |
| MinIO(开源版) | AGPL-3.0 | 已归档停维护,且多节点部署需商业许可 |
| Elasticsearch | AGPL-3.0 / SSPL / Elastic License 2.0 三选一 | 内部使用无分发义务;对外交付产品需复核 |
| OpenSearch | Apache-2.0 | ES 的合规备选 |
| OpenMetadata / DataHub / Atlas | Apache-2.0 | 无 |
| Prometheus / Alertmanager | Apache-2.0 | 无 |
| Grafana / Loki / Alloy | AGPL-3.0 | 内部部署不触发分发义务;若随产品交付给客户,需要单独评估 |
结论:主推组件全部可私有化、无授权费。唯一需要法务看一眼的是 Grafana / Loki / Alloy / Elasticsearch 的 AGPL 条款——自用没问题,做成对外售卖的整机产品时要复核。
关键取舍
为什么不用 HDFS? HDFS 把存储节点和计算节点绑在一起,扩存储必须扩计算;而且它假设数据在本地盘、依赖 Hadoop 生态。对象存储 + Iceberg 把这两件事解开了,Spark、Flink、Doris 都能直接读。
既然有 Iceberg,为什么还要 Doris? Iceberg 解决"数据怎么放",不解决"看板秒开"。BI 要高并发、低延迟、点查和主键更新,这是 OLAP 引擎的活。Doris 里存的是热点副本,丢了可以从 Iceberg 重建。
为什么 Elasticsearch 只做索引? 一旦让 ES 承担业务检索或日志检索,它就从"可重建副本"变成了"第二事实源",删除或重建都会投鼠忌器。本栈里它只服务 OpenMetadata 的搜索框。
为什么 Kafka 不能省? 实时链路需要削峰、解耦、可重放。Flink CDC 直接写湖不是不行,但业务库高峰会把写入压力传导到湖上,且失败重放没有缓冲。Kafka 是这条链路的减震器。
3 节点测试集群能验证什么、不能验证什么? 能验证:K8s 调度、Pod 跨节点打散、etcd 选主、Kafka RF=3、Doris 3 BE 副本、PG 主备切换、Ceph 3 OSD 或 SeaweedFS 3 节点。 不能验证:跨机房/跨 AZ、真实磁盘故障、PB 级容量、大规模并发。测试集群验证的是机制能跑、配置能复用,不是性能与站点级容灾。