自版本 4.3 起,Grafana 可以使用 MySQL 作为原生数据源。直接数据库连接的想法是 Grafana-Zabbix 插件可以使用此数据源直接从 Zabbix 数据库查询数据。
对于 Zabbix API 而言,最占用资源的查询之一是历史记录查询。对于长时间间隔,history.get
返回大量数据。为了显示这些数据,插件应使用 consolidateBy 函数调整时间序列分辨率。最终,Grafana 显示的是经过缩减的时间序列,但这些数据首先需要在客户端加载和处理。直接数据库连接通过将聚合移动到服务器端来解决这两个问题。因此,客户端获得一个“即用型”数据集,该数据集小得多。这使得数据加载更快,并且客户端无需花费时间处理数据。
此外,许多用户发现直接数据库查询比 API 调用具有更好的性能。这可能是由于多种原因造成的,例如额外的 PHP 层和额外的 SQL 查询(用户权限检查)。
直接数据库连接功能允许透明地使用数据库查询历史数据。现在 Grafana-Zabbix 插件支持用于历史查询的少数数据库:MySQL、PostgreSQL 和 InfluxDB。无论数据库类型如何,其理念和数据流保持不变。
数据流
此图表说明了插件如何同时使用 Zabbix API 和 MySQL 数据源从 Zabbix 查询不同类型的数据。MySQL 数据源仅用于拉取历史和趋势数据,而不是使用 history.get
和 trend.get
API 调用。
查询结构
以下是在 Grafana-Zabbix 插件中获取历史记录的查询示例
MySQL:
SELECT itemid AS metric, clock AS time_sec, {aggFunc}(value) as value
FROM {historyTable}
WHERE itemid IN ({itemids})
AND clock > {timeFrom} AND clock < {timeTill}
GROUP BY time_sec DIV {intervalSec}, metric
ORDER BY time_sec ASC
PostgreSQL:
SELECT to_char(itemid, 'FM99999999999999999999') AS metric,
clock / {intervalSec} * {intervalSec} AS time,
{aggFunc}(value) AS value
FROM {historyTable}
WHERE itemid IN ({itemids})
AND clock > {timeFrom} AND clock < {timeTill}
GROUP BY 1, 2
ORDER BY time ASC
其中 {aggFunc}
是 [AVG, MIN, MAX, SUM, COUNT]
聚合函数之一,{historyTable}
是历史记录表,{intervalSec}
是以秒为单位的聚合间隔。
获取趋势时,插件还会额外查询特定的值列(value_avg
、value_min
或 value_max
),这取决于 consolidateBy
函数的值
MySQL:
SELECT itemid AS metric, clock AS time_sec, {aggFunc}({valueColumn}) as value
FROM {trendsTable}
WHERE itemid IN ({itemids})
AND clock > {timeFrom} AND clock < {timeTill}
GROUP BY time_sec DIV {intervalSec}, metric
ORDER BY time_sec ASC
PostgreSQL:
SELECT to_char(itemid, 'FM99999999999999999999') AS metric,
clock / {intervalSec} * {intervalSec} AS time,
{aggFunc}({valueColumn}) AS value
FROM {trendsTable}
WHERE itemid IN ({itemids})
AND clock > {timeFrom} AND clock < {timeTill}
GROUP BY 1, 2
ORDER BY time ASC
注意:这些查询将来可能会更改,因此请查阅源码以获取实际查询结构。
如您所见,Grafana-Zabbix 插件使用给定时间间隔进行聚合。此间隔由 Grafana 提供,并取决于面板的像素宽度。因此,Grafana 以适当的分辨率显示数据。
InfluxDB
Zabbix 支持可加载模块,这使得将历史数据写入外部数据库成为可能。有一个由 Gleb Ivanovsky 编写的 InfluxDB 模块,可以将历史记录实时导出到 InfluxDB。
InfluxDB 保留策略
为了控制数据库大小,您应该使用 InfluxDB 保留策略机制。可以为长期数据创建保留策略,并以与 Zabbix 相同的方式(趋势)写入聚合数据。然后可以在插件中使用此保留策略来获取特定周期后的数据(数据源配置中的 保留策略 选项)。有关如何配置保留策略以与 effluence 模块一起使用的更多信息,请参阅 文档。
InfluxDB 查询
最终,插件会生成类似于此的 InfluxDB 查询
SELECT MEAN("value")
FROM "history"
WHERE ("itemid" = '10073' OR "itemid" = '10074')
AND "time" >= 1540000000000s AND "time" <= 1540000000060s
GROUP BY time(10s), "itemid" fill(none)
直接数据库连接的函数用法
只有一个函数直接影响后端数据。此函数是 consolidateBy
。其他函数在客户端工作,并转换来自后端的数据。因此,您应该清楚地了解这是预聚合数据(通过 AVG、MAX、MIN 等)。
例如,假设您想按 1 小时间隔和 max
函数对值进行分组。如果您只应用 groupBy(10m, max)
函数,您的结果将是错误的,因为您会转换由默认 AVG
函数聚合的数据。您应该将 consolidateBy(max)
与 groupBy(10m, max)
结合使用才能获得精确的结果。