2. Databricks平台架构与可观测性数据源
要建立一套真正可用的可观测性体系,第一步不是选工具,而是搞清楚“信号从哪里来”。Databricks 是一个由多个子系统拼装而成的平台,每个子系统在运行过程中都会产生不同形态、不同粒度、不同时效性的可观测性信号。如果把这些信号混在一起看,很容易出现“指标很多但定位不了问题”的困境。因此,本节按照平台架构的层次,逐一梳理各组件的信号产生点,并说明这些信号在排障与容量规划中的实际用途。
控制平面与数据平面:两类信号的根本差异
Databricks 的架构可以粗略划分为控制平面(Control Plane)与数据平面(Data Plane)。控制平面由 Databricks 托管,承载账户管理、工作区配置、作业调度、集群管理 API、Unity Catalog 元数据服务、Notebook 与 Git 集成等。数据平面则运行在客户自己的云账号中,承载实际的计算资源(VM、容器)、Spark 驱动与执行器、Delta 表数据文件、以及部分网络出口配置。
这个划分直接决定了信号的可获取方式。控制平面的信号通常通过 REST API、审计日志(Audit Logs)、系统表(system tables)以及账户控制台暴露,例如作业运行状态、集群创建事件、用户登录行为、权限变更记录。数据平面的信号则更多依赖集群内部的 Spark UI、日志投递(如到 S3/ADLS 的日志路径)、云厂商监控(CloudWatch、Azure Monitor)以及 Delta 表的事务日志。理解这一点,才能判断某个指标应该从哪个入口采集,以及它的延迟和保留策略是否满足需求。
Spark 与 Photon:计算引擎的信号密度最高
Spark 是 Databricks 上绝大多数批处理与流处理作业的执行引擎,也是信号最密集的组件。一个 Spark 作业从提交到结束,会产生以下几类关键信号:
- Driver 日志:包含作业提交、DAG 划分、Stage 调度、Task 失败重试、异常堆栈。这是排障的第一入口,尤其是
OutOfMemoryError、FetchFailedException、TaskKilled等典型错误。 - Executor 日志:记录每个执行器的 GC 行为、Shuffle 读写、磁盘溢写、心跳丢失。当出现数据倾斜时,个别 Executor 的日志会明显比其他执行器“厚”。
- Spark UI / Event Log:提供 Stage 级别的输入输出字节数、Shuffle Read/Write、Task 耗时分布、GC 时间占比。Event Log 可以持久化到对象存储,供事后回放分析。
- Metrics Sink:Spark 内置的指标系统可以按需推送到 Prometheus、Graphite 或自定义 Sink,适合做实时监控看板。
Photon 是 Databricks 自研的向量化执行引擎,在兼容 Spark API 的前提下,用 C++ 重写了部分算子,显著提升 CPU 利用率。Photon 的信号与 Spark 共享同一套日志和 UI 框架,但有几个专属观察点:查询是否被 Photon 接管(在 Spark UI 的 SQL 页面会标注 Photon 执行计划)、Photon 算子耗时、以及因不支持某算子而回退到 JVM 执行的比例。如果发现某类查询 Photon 启用率很低,往往意味着写法或数据类型触发了回退,需要针对性优化。
Delta Lake:事务日志是数据层的“黑匣子”
Delta Lake 的可观测性核心在于 _delta_log 目录下的事务日志。每一次写入、更新、删除、合并(MERGE)都会生成一个 JSON 提交文件,记录本次操作新增/删除的文件列表、统计信息(min/max、null count)、以及 schema 变更。这些日志本身就是最可靠的数据层信号源:
- 版本增长速率:短时间内版本号快速增长,通常意味着高频小批量写入,会带来小文件问题。
- 文件数量与平均大小:通过日志中的
add记录可以统计当前表的小文件比例,判断是否需要OPTIMIZE。 - 提交耗时:日志中记录的提交时间戳差值,可以反映并发写入冲突或元数据操作压力。
- Time Travel 与 Vacuum 状态:保留的历史版本数量、上次 Vacuum 时间,直接影响存储成本与查询性能。
在实际操作中,可以用一条 SQL 快速观察 Delta 表的健康状况:
DESCRIBE DETAIL my_catalog.my_schema.orders;
-- 关注字段:numFiles、sizeInBytes、partitionColumns、lastModified
-- 若 numFiles 远大于 sizeInBytes / 128MB,说明小文件偏多
这条命令返回的 numFiles 与 sizeInBytes 是判断小文件问题的直接依据。假设一张表 sizeInBytes 为 10GB,numFiles 为 5000,则平均文件大小约 2MB,远低于推荐的 128MB~256MB,此时应安排 OPTIMIZE 并考虑调整写入批次。
Unity Catalog:元数据与权限的审计信号
Unity Catalog 统一管理数据资产(表、视图、函数、模型)的元数据与访问权限。它的可观测性信号主要体现在审计日志与系统表中:谁在什么时候访问了哪张表、执行了什么操作、权限是否被修改、跨工作区共享是否生效。这些信号对于安全合规和故障溯源至关重要。例如,当某个作业突然报“表不存在”时,通过审计日志可以快速确认是表被重命名、权限被回收,还是工作区绑定关系发生了变化。
Unity Catalog 还提供 information_schema 和 system.access.audit 等系统表,可以直接用 SQL 查询访问历史与权限变更,无需额外搭建采集管道。这是控制平面信号中时效性较好、结构化程度较高的一类。
MLflow 与 Model Serving:机器学习链路的专属信号
MLflow 覆盖了实验跟踪、模型注册、模型部署三个阶段,每个阶段都有独立的信号产生点。实验跟踪阶段,每次 mlflow.log_param、log_metric、log_artifact 都会写入 Run 记录,包含参数、指标曲线、代码版本、环境依赖。模型注册阶段,模型版本状态(Staging、Production、Archived)的流转会留下事件记录。Model Serving 阶段,每个服务端点会暴露请求量、延迟分布(P50/P95/P99)、错误率、以及底层资源利用率。
这些信号的价值在于把“模型效果”与“系统表现”关联起来。例如,当某个端点的 P99 延迟从 80ms 上升到 400ms 时,可以回溯到对应模型版本的输入特征分布是否发生漂移,或者 Serving 集群的 CPU 是否被其他端点挤占。MLflow 的 Run 记录与 Serving 的指标如果能在同一时间轴上对齐,就能形成从训练到推理的完整可观测链路。
信号采集的优先级建议
面对如此多的信号源,实际落地时不必一次性全部接入。可以按照“先保命、再优化、后精细”的顺序推进:第一优先级是作业失败率、集群启动失败、Serving 错误率这类直接反映可用性的信号;第二优先级是 Executor OOM、Shuffle 溢出、Delta 小文件数这类影响性能与成本的信号;第三优先级是 Photon 启用率、MLflow 指标漂移、权限变更明细这类用于持续优化的信号。每个信号都应明确它的采集入口、保留周期和告警阈值,避免“采了不用”或“用时找不到”。