上一篇完成了 Kibana 平台内部机制的全貌,覆盖了 bundle 加载序列和异步搜索会话。这一篇转向外部对比,核心问题是:单一后端深度集成(Kibana)与多数据源统一抽象(Grafana)各自解决什么问题,DataSource 模型的差异在哪里,告警模型如何不同。

架构起点的分叉

Kibana 和 Grafana 都是可视化平台,都有 Dashboard、Panel、告警,但它们的架构起点完全不同,导致几乎所有设计决策都走向了不同方向。

Kibana 的起点是"Elasticsearch 的前端"。即使经过多次重构,它的状态(Saved Objects)存在 ES 里,它的查询模型围绕 ES 的 aggregation 体系构建,它的 Data View 是对 ES 索引模式的映射。ES 是 Kibana 唯一的数据后端,也是它的持久化存储。这种深度绑定让 Kibana 能充分利用 ES 的全文检索、嵌套 aggregation、异步搜索、PIT 等特性,但代价是:换掉 ES,Kibana 就什么都不是了。

Grafana 的起点是"不同数据源的统一可视化层"。它自己用 SQLite(或 PostgreSQL/MySQL)存状态,不依赖任何特定的数据后端。它的 Datasource 是一个插件接口,任何能实现这个接口的系统都可以成为 Grafana 的数据源。Prometheus、Loki、InfluxDB、Elasticsearch、PostgreSQL、甚至 Google Sheets,都是 Grafana 的一等公民数据源。

1
2
3
4
5
6
7
8
9
Kibana 架构
Browser → Kibana Node.js → Elasticsearch (数据 + 状态)

Grafana 架构
Browser → Grafana Server → SQLite/PG (状态)
→ Datasource Plugin A → Prometheus
→ Datasource Plugin B → Loki
→ Datasource Plugin C → Elasticsearch
→ ...

这个起点差异决定了后续所有取舍。

状态存储模型

Kibana 把所有状态(Dashboard 定义、可视化配置、Data View、告警规则、报表计划)存在 Elasticsearch 的 .kibana 系统索引里,以 Saved Object 格式组织,带引用关系和迁移框架。这意味着备份 Kibana 状态就是备份 ES 快照,迁移 Kibana 配置就是导出/导入 ES 文档。

Grafana 把状态存在独立的关系数据库里(默认 SQLite,生产环境推荐 PostgreSQL 或 MySQL)。Dashboard JSON、用户、org、datasource 配置都在这里。Grafana 的状态和数据源是完全分离的两套存储。这使得 Grafana 的备份和迁移更接近传统 Web 应用的运维模式:备份 DB,而不是备份数据后端。

Grafana 8 引入了 Grafana as Code(GaC)支持,Dashboard 可以用 JSON 文件存在 Git 里,通过 provisioning 机制在启动时加载。Kibana 8.7 也引入了 Kibana Fleet(配置即代码机制),但成熟度低于 Grafana 的 provisioning。

DataSource 模型差异

这是两个平台最核心的结构差异。

Kibana 的数据模型围绕 Data View(旧称 Index Pattern)构建。一个 Data View 对应一个或多个 ES 索引(通过 wildcard 模式),声明哪些字段是时间字段、哪些是关键字字段。Kibana 的所有可视化(Discover、Lens、TSVB、Vega)都从一个 Data View 出发,发送 ES 查询,拿回 ES 的聚合结果。Data View 是 Kibana 可视化的唯一入口。

1
2
3
4
5
Kibana Data View
└── index pattern: logs-*
├── time field: @timestamp
├── fields: [message, level, host, ...]
└── → 所有 Kibana 可视化从这里取数据

Grafana 的数据模型围绕 Datasource 插件构建。每个 Datasource 是一个插件,实现标准接口(query()testDatasource()annotationQuery() 等)。一个 Grafana Dashboard 里的不同 Panel 可以分别指向不同的 Datasource。Panel A 查 Prometheus,Panel B 查 Loki,Panel C 查 Elasticsearch,它们共存在同一个 Dashboard 里。

1
2
3
4
Grafana Panel
├── Panel A → Datasource: Prometheus → query: rate(http_requests[5m])
├── Panel B → Datasource: Loki → query: {job="nginx"} |= "error"
└── Panel C → Datasource: MySQL → query: SELECT count(*) FROM orders

这个差异的实际影响:在 Kibana 里,把一张 Dashboard 的数据源从 logs-prod-* 切换到 logs-staging-*,只需改 Data View;在 Grafana 里,切换 Datasource 需要逐个 Panel 操作(或者用 Dashboard Variables 统一管理)。但 Grafana 天然支持同一张 Dashboard 混合多个后端的数据,Kibana 在 8.x 之前做不到(8.x 的 Lens 开始实验性支持跨 Data View 的拼接,但仍在 ES 生态内)。

查询语言与可视化模型

Kibana 的查询层建立在 ES DSL 之上。Discover 用 KQL(Kibana Query Language,一个语法糖层),底层翻译成 ES Query DSL。Lens 和 TSVB 的图形化构建器最终也生成 ES aggregation DSL。Vega 和 Vega-Lite 允许用户直接写 ES 查询。可视化类型以聚合为中心:terms aggregation → 饼图/柱状图,date histogram → 时序图,percentile aggregation → 折线图。

Grafana 没有统一查询语言,每个 Datasource 插件提供自己的查询编辑器。Prometheus 数据源用 PromQL,Loki 数据源用 LogQL,CloudWatch 数据源用 AWS Metrics Insights,ES 数据源有自己的查询构建器(也可以直接写 Lucene/ES DSL)。可视化类型以时序为中心,但通过 Transformations 层可以对查询结果做 join、pivot、filter 等后处理,弥补不同数据源之间的模型差距。

告警模型对比

两个平台的告警架构在 2022-2023 年都经历了大幅重构,当前状态(Kibana 8.x、Grafana 9.x+)如下。

Kibana 的告警由 Task Manager 驱动。告警规则是一个 Saved Object,Task Manager 按规则的检查间隔定期触发任务,任务执行 ES 查询,把结果与阈值比较,把告警事件写入专用的 .kibana-alert-history-*.alerts-* 索引。告警状态持久化在 ES 里,这意味着告警历史可以被 Discover 查询,可以被 Dashboard 可视化。

1
2
3
4
5
6
Kibana 告警流
Rule (Saved Object)
→ Task Manager 按 interval 调度
→ 执行 ES 查询
→ 写 alert event 到 .alerts-* 索引
→ 触发 Connector(email / Slack / webhook)

Grafana 的告警(Grafana Alerting,前身是 Grafana 8 统一告警模型)有独立的告警数据存储。告警规则定义在 Grafana DB 里,由 Alert Engine 执行,支持多数据源(一条规则可以同时查 Prometheus 和 Loki)。告警状态存在 Grafana 的关系 DB 里(或外部 Alertmanager),而不是数据后端。Grafana 直接对接 Prometheus Alertmanager 协议,与现有 Prometheus 告警生态兼容。

两者的关键区别:Kibana 告警状态和历史可以被 ES 查询,与日志/指标数据在同一个索引里检索,关联分析方便;Grafana 告警与 Prometheus Alertmanager 生态对接更直接,在已有 Prometheus 监控体系的环境里集成成本更低。

实验:同一份日志数据在两个平台里的查询差异

准备条件:运行一个 Elasticsearch 集群,里面有 logs-* 索引,同时运行 Kibana 和 Grafana(Grafana 配置 ES Datasource 指向同一集群)。

在 Kibana 里:

1
2
3
1. 创建 Data View: logs-* (time field: @timestamp)
2. 在 Discover 里搜索: level: "error" AND host: "web-01"
3. 在 Lens 里构建:X 轴 @timestamp (date histogram), Y 轴 Count, 分组 level.keyword

在 Grafana 里(ES Datasource):

1
2
3
1. 添加 Elasticsearch Datasource,Index: logs-*,Time field: @timestamp
2. 新建 Panel,Query: Lucene query "level:error AND host:web-01"
3. 同样构建时序图:使用 Date Histogram aggregation + Terms on level.keyword

导出两个平台的 Dashboard JSON,对比结构。Kibana 的 Dashboard JSON 包含 Saved Object 格式,references 数组指向 Data View;Grafana 的 Dashboard JSON 是自包含的,Panel 直接内嵌查询配置和 datasource uid。Grafana 的 JSON 更容易在 Git 里版本管理和 diff,Kibana 的 JSON 需要带着所有 references 一起导出才有意义。

模式提炼

单一后端深度集成(Kibana)在功能深度和查询能力上占优:ES 的 aggregation 嵌套层级、异步搜索、runtime fields 这些高级特性都能直接用。多后端抽象(Grafana)在覆盖面和灵活性上占优:不受数据源技术栈限制,一张 Dashboard 可以聚合来自不同系统的信号。

状态存储的选择影响运维模型:ES 存状态(Kibana)意味着 Kibana 和 ES 的运维不可分离;独立 DB 存状态(Grafana)意味着可视化平台和数据后端可以独立扩展和备份。

告警模型与持久化位置的选择影响可观测性:告警历史在 ES 里(Kibana)意味着告警事件可以和业务日志、指标在同一个搜索界面里关联查询;告警历史在关系 DB 里(Grafana)意味着与 Alertmanager 生态对接更自然。

工程迁移表

维度 Kibana Grafana 选择依据
数据后端 ES only 100+ datasource plugins 是否有多数据源需求
状态存储 Elasticsearch SQLite / PG / MySQL 现有运维体系
查询语言 KQL / ES DSL 每个 datasource 独立 团队熟悉度
可视化模型 aggregation-centric time-series + transforms 数据形态
告警集成 ES-native, Task Manager Alertmanager-compatible 现有告警栈
Dashboard as Code 成熟度中等(8.7+) 成熟(provisioning, GaC) GitOps 要求
安全/SIEM 内置(Enterprise) 无原生支持 安全场景

常见误解

Grafana 连上 ES 就和 Kibana 一样了。不对。Grafana 的 ES Datasource 支持 ES 的基础查询和常用 aggregation,但不支持 ES 的全部高级特性(如 EQL、异步搜索的 Search Session 集成、Kibana 专有的 runtime field UI)。Kibana 对 ES 的深度集成是 Grafana 的 ES 插件无法复制的。

Kibana 只适合日志分析。不对。Kibana 的 Metrics(基于 APM Indices 和 Metricbeat 数据)、Uptime/Synthetics、Security(SIEM)、Maps 都是正式产品,适用范围已覆盖指标、链路追踪、安全分析、地理可视化。

两个平台不能共存。可以共存。在已有 ELK 栈的环境里加入 Grafana 连接 Prometheus 和 Loki,Kibana 继续处理 ES 数据,是完全合理的架构。两个平台各自处理最擅长的数据源,不必二选一。

练习

  1. 用 Grafana 的 ES Datasource 创建一张 Dashboard,在同一张 Dashboard 里放两个 Panel:一个查 ES 的错误日志计数(Lucene query),另一个查 Prometheus 的 CPU 使用率(PromQL)。观察这在 Kibana 里是否可以实现。

  2. 从 Kibana 导出一张包含 3 个 panel 的 Dashboard JSON,再在 Grafana 里手工重建同样的 Dashboard,对比两个 JSON 文件的结构差异,特别是 references 的处理方式。

  3. 在 Kibana 里创建一条告警规则,用 Dev Tools 查询 .alerts-* 索引,找到这条规则的告警历史记录;再在 Grafana 里创建等价规则,查看 Grafana DB 里的告警记录。对比两者的数据模型。

系列导航

  • 上一篇:深入 Kibana 15 - 性能模型:bundle、bootstrap 与异步搜索会话
  • 下一篇:深入 Kibana 17 - 演进:从纯前端到 New Platform 再到 Serverless

参考资料