跳到主要内容

ClickHouse / Doris / IoTDB

ClickHouse、Doris、IoTDB 同属 SQL 类数据源:查询结果的数值列成为序列值,其余列成为标签,直接用于告警判定。

这三个存的东西不一样——ClickHouse 和 Doris 通常放海量日志和明细, IoTDB 放设备时序——但在夜莺里它们是同一类:用 SQL 查,查出来的表被当成序列去判定告警。 这页讲怎么接、SQL 要写成什么形态、以及结果的哪一列变成数值、哪一列变成标签。

三者在开源版里能做什么​

它们的能力边界不一样,动手之前先看清楚,免得接完发现在探索器里选不到:

注册数据源告警规则即时查询仪表盘
ClickHouse✓✓——
Doris✓✓——
IoTDB✓✓✓✓

也就是说,ClickHouse 和 Doris 在开源版里的唯一落点是告警规则。 它们不会出现在数据查询的数据源下拉框里,也选不进仪表盘面板。 IoTDB 没有这个限制。

三者都能配告警规则,但前提是先注册出至少一个该类型的数据源—— 告警规则表单里的「数据源类型」只列出你已经注册过的类型,一个 Doris 数据源都没有的话, 这个类型的卡片根本不出现。

ClickHouse​

集成中心 → 数据源 → 新增 → ClickHouse。

字段填什么
名称必填
协议Native 或 HTTP,默认 Native
Nodeshost:port,不能带 http:// 前缀,带了会被直接挡下来。Native 默认端口 9000,HTTP 默认端口 8123(表单里的占位符写的是 9200,那是笔误,别照抄)
安全连接(SSL/TLS)开启后会多出一个「跳过 SSL 验证」开关
用户名 / 密码按需

Nodes 是个可以加行的列表,但当前实现只用第一个节点,多填的暂时不会参与轮询。

「高级设置」里是连接池和限流:超时时间(毫秒,默认 100000)、 单次请求允许检索的最大行数(默认 500,必填)、最大空闲连接数(10)、 最大打开连接数(100)、连接最大生存时间(秒,14400)。

ClickHouse 数据源表单ClickHouse 数据源表单

点 测试连通性并保存 时,夜莺会真的建连接并执行一次 SHOW DATABASES, 过不了就不入库。地址格式写错(带了 http://)属于配置错误,用「不测试连通性直接保存」 也存不进去。

Doris​

集成中心 → 数据源 → 新增 → Doris。

字段填什么
名称必填
URLFE 的 MySQL 协议地址,localhost:9030 这种写法,不带 scheme
用户名 / 密码按需
超时时间(单位: 毫秒)默认 100000
单次请求允许检索的最大行数默认 500
最大空闲 / 打开连接数、连接最大生存时间同 ClickHouse

Doris 的查询编辑器里有数据库和数据表两个下拉框,选完之后可以用「快捷查询」 按模板生成 SQL,也可以切「自定义查询」自己写。

它还有一个时间宏:$__timeFilter(\timestamp`)`。SQL 里写了它, 页面上选的时间区间才会作用到查询上;没写的话编辑器会弹一条警告 ——「查询条件中未包含时间宏,所选的时间区间将不会生效」, 意思是这条 SQL 可能在扫全表。

IoTDB​

集成中心 → 数据源 → 新增 → IoTDB。

字段填什么
名称必填
URLREST 接口地址,表单里已经预填了 http://localhost:18080
超时(单位:ms)默认 10000
用户名 / 密码按需

保存时的连通性测试是往 <URL>/rest/table/v1/query 发一条 show databases。

IoTDB 的查询编辑器多两个东西:查询模板(一组现成的 SQL,把里面的 $变量 换成实际值就能用)和时间字段 / 时间格式——因为 IoTDB 的时间列名字不固定, 要显式告诉夜莺哪一列是时间轴、按什么格式解析。

查询结果怎么变成序列​

这是 SQL 类数据源和 PromQL 类数据源最大的差别,也是最容易卡住的地方。

PromQL 返回的本来就是时序;SQL 返回的是一张表。夜莺靠两个「辅助配置」把表翻译成序列:

  • 值字段:结果里哪些列是数值,参与阈值判定、画成曲线。必填;
  • 标签字段:结果里哪些列作为序列的标签,通常就是 GROUP BY 的那几列。可选。

举个最简单的:

SELECT count(*) AS err_count
FROM logs.app_log
WHERE level = 'ERROR'
AND event_time > now() - INTERVAL 5 MINUTE

值字段选 err_count,告警条件写 $A.err_count > 1000。

想让每个服务单独告警,就 GROUP BY 之后把分组列设成标签字段:

SELECT service, count(*) AS err_count
FROM logs.app_log
WHERE level = 'ERROR'
AND event_time > now() - INTERVAL 5 MINUTE
GROUP BY service

值字段 err_count,标签字段 service。SQL 返回几行,就有几条独立序列, 告警引擎逐行判定——十行就最多十条事件,每条事件的标签里带着自己那个 service。 这也意味着一条没有 GROUP BY 又返回几千行的 SQL,会一次性烧出几千条事件。

写完 SQL 一定先点 数据预览,确认返回的列名和行数符合预期,再去配阈值。

别让告警查询扫全表​

告警规则里的 SQL 是周期性执行的,执行频率填 60 秒就是每分钟扫一次。三条纪律:

  1. WHERE 里一定要限定时间范围,并且用分区列或主键列, 比如 event_time > now() - INTERVAL 5 MINUTE。Doris 用 $__timeFilter() 时间宏;
  2. 执行频率和查询代价匹配。一条要扫十秒的 SQL 别配成 15 秒一次;
  3. 限制返回行数。数据源表单里那个「单次请求允许检索的最大行数」就是最后一道闸, 默认 500,不要为了图省事调到几万。

下一步​