数据底座架构设计:分层架构与技术选型

聊到数据底座,我第一个想说的就是分层。为什么?因为不分层,你后期根本没法维护。我在好几个项目里都见过那种「大泥球」架构——所有逻辑揉在一起,改一个数据源,整个管道都得重跑。说白了,分层不是为了好看,是为了让每一层都能独立演进。

今天我们就从四个核心层展开:数据源层、存储层、计算层、服务层。再加上技术选型原则和高可用设计,这些都是我踩过坑之后总结出来的。

数据源层:接入的「第一公里」

数据源层是整个底座的入口。你想想看,数据从哪里来?业务数据库、日志文件、消息队列、第三方API……每个源的格式、频率、一致性要求都不一样。

我个人习惯把数据源分成三类:

  • 结构化数据:MySQL、PostgreSQL、Oracle 这类关系库。变更捕获用 Debezium 或 Canal。
  • 半结构化数据:JSON 日志、CSV 文件、Avro/Parquet。通常走 Flume 或 Filebeat。
  • 流式数据:Kafka、Pulsar、AWS Kinesis。实时性要求高,延迟容忍度低。
我的经验: 数据源层最容易忽略的是「元数据管理」。我曾经接手过一个项目,50 多个 Kafka Topic,没人知道每个 Topic 的 schema 是什么。后来我们强制要求所有数据源注册到 Schema Registry,才把混乱控制住。

存储层:选对引擎,事半功倍

存储层是数据底座的心脏。选错了,后面所有计算层都得跟着遭殃。我见过有人用 HDFS 存实时查询数据,结果查询延迟高到没法用。也见过有人用 Elasticsearch 存全量历史数据,集群规模膨胀到失控。

我的建议是:按场景选存储,不要一把抓。

场景 推荐引擎 核心考量
离线批处理 HDFS / MinIO / S3 吞吐量、扩展性、成本
实时查询 ClickHouse / Druid 查询延迟、列式存储
全文检索 Elasticsearch 分词、倒排索引
消息缓冲 Kafka / Pulsar 吞吐量、持久化、回溯
元数据管理 Hive Metastore / Glue Schema 一致性、血缘

这里有个坑:不要把 Kafka 当数据库用。Kafka 的消息默认有保留期限,过期就删了。我曾经有个同事把 Kafka 当长期存储,结果数据回溯时发现历史消息已经被清理了……嗯,从那以后我们给每个 Topic 都设了明确的保留策略。

计算层:批流一体是趋势

计算层负责把原始数据变成有价值的信息。以前大家喜欢把批处理和流处理分开——Spark 做批,Flink 做流。但现在趋势是批流一体,一套代码跑两种模式。

我个人比较推荐的分层方式:

  • 批处理:Spark SQL + Airflow 调度。适合 T+1 报表、历史数据重跑。
  • 流处理:Flink + Kafka。适合实时指标、异常检测。
  • 即席查询:Presto / Trino。适合分析师临时跑 SQL。
注意: 计算层的资源隔离很重要。我曾经见过一个集群,流任务和批任务混跑,结果批任务把 CPU 吃满,导致实时指标延迟飙升。后来我们用了 YARN 队列或 K8s Namespace 做资源隔离,才解决问题。

服务层:让数据「用起来」

服务层是数据底座和业务应用之间的桥梁。数据存好了、算完了,怎么让业务方方便地拿到?这就是服务层要干的事。

常见的服务层组件包括:

  • API 网关:统一数据查询入口,鉴权、限流、路由。
  • 数据服务:RESTful API 或 gRPC,封装复杂查询逻辑。
  • 可视化:Superset、Grafana、Metabase。
  • 数据订阅:通过 Kafka 或 Webhook 推送数据变更。

这里我想强调一点:服务层一定要做缓存。我做过一个实时大屏项目,前端每 5 秒请求一次聚合数据,如果每次都去查 ClickHouse,集群压力非常大。后来我们在服务层加了 Redis 缓存,命中率 80% 以上,查询延迟从 200ms 降到了 5ms。

技术选型原则:别追新,要追稳

技术选型这件事,我踩过的坑比谁都多。总结下来就三条原则:

  1. 社区活跃度:选 GitHub Star 多、Release 频繁的项目。冷门技术再牛也别碰,出了问题没人帮你。
  2. 团队熟悉度:再好的技术,团队没人会用也是白搭。我见过有人硬上 Flink,结果团队只会写 Spark,最后项目延期两个月。
  3. 生态兼容性:选能和现有系统无缝集成的组件。比如你已经在用 Kafka,就别硬上 Pulsar,除非有非换不可的理由。

我的避坑指南: 我曾经在一个项目里选了当时最火的「新一代计算引擎」,结果半年后项目停止维护,我们不得不花两个月迁移代码。从那以后,我选技术只看两点:有没有大厂在用、有没有商业支持。

高可用设计:别让单点毁了你的底座

数据底座一旦上线,就是 7×24 小时跑。任何一个单点故障,都可能导致整个管道瘫痪。高可用设计不是可选项,是必选项。

我总结了几条关键策略:

  • 多副本:HDFS 默认 3 副本,Kafka 分区至少 2 副本。数据不丢是第一优先级。
  • 主备切换:NameNode、ResourceManager 这些核心组件必须配 HA。我用过 ZKFC + Quorum Journal Manager,切换时间控制在 30 秒以内。
  • 跨机房容灾:如果预算允许,做异地多活。我参与过一个金融项目,两地三中心,数据实时同步,机房级故障不影响业务。
  • 限流与降级:服务层必须做限流,防止突发流量打垮后端。我习惯用 Sentinel 或 Hystrix,配合熔断机制。
别忘了演练: 高可用设计不是写个文档就完事了。我每季度都会做一次故障演练——手动 Kill 一个节点,看看系统能不能自动恢复。第一次演练时,我们发现 ZK 会话超时配置不合理,导致切换延迟过高。演练救了我们一命。

整体架构图

下面这张图展示了数据底座的四层架构,以及各层之间的数据流向。你可以把它当作一个参考模板,实际落地时根据业务场景调整。

MLOps 数据底座分层架构 数据源层 MySQL Kafka 日志文件 第三方 API IoT 设备 存储层 HDFS / S3 ClickHouse Elasticsearch Kafka Hive Metastore 计算层 Spark (批处理) Flink (流处理) Presto (即席查询) Airflow (调度) 服务层 API 网关 数据服务 可视化 数据订阅 缓存 (Redis) 数据流自下而上:采集 → 存储 → 计算 → 服务。每层独立扩展,互不耦合。

总结一下

数据底座的分层架构,说白了就是「各司其职」。数据源层负责接入,存储层负责持久化,计算层负责加工,服务层负责输出。每一层都有自己的职责边界,不要越界。

技术选型时,别被新框架迷了眼。社区活跃、团队熟悉、生态兼容,这三点比什么都重要。高可用设计也不是一蹴而就的,需要持续演练和优化。