跳到主要内容

容量规划

夜莺的资源消耗由规则数、序列数、事件量和数据库负载决定;量出四个数就知道该往哪个方向扩,这里不提供规格表。

这页不给「X 核 Y 内存能跑 Z 条规则」这样的表——最后一节说明为什么。 它给的是四个可以直接量出来的数,以及每个数逼近上限时该往哪个方向扩。 量完你自己的环境,比抄别人的规格准。

什么在消耗资源​

消耗什么主要由什么决定
CPU规则条数 × 判定频率,以及每次判定返回的序列数
内存内存里缓存的配置(规则、设备、用户)+ 判定返回的序列 + 队列里积压的样本和事件
元数据库事件写入、通知记录写入、各缓存每 9 秒一次的同步查询
磁盘内置时序库的数据块、判定记录、日志
出向网络每次判定对数据源的查询、每次转发给时序库的样本

注意判定的开销主要不在夜莺这一侧:一条规则每分钟对 Prometheus 发一次查询, 压力大头在 Prometheus。规则多了以后先扛不住的往往是数据源,不是夜莺。

先量这四个数​

都在 /metrics 上,curl --noproxy '*' http://n9e:17000/metrics 就能取。

1. 活跃序列数​

prometheus_tsdb_head_series

只有开着内置时序库的 Center 有这个指标,它是当前内存里活跃序列的真实条数。 用外部时序库时看外部库自己的对应指标。

上限参考:内置时序库适合 10 万活跃序列以内,再往上要换外部库。 这是产品自己给出的边界,写在 etc/config.toml 的 [EmbeddedTSDB] 注释里。

2. 判定耗时​

n9e_alert_rule_eval_total # 总判定次数,不带标签
n9e_alert_rule_eval_duration_ms{rule_id="..."} # 每条规则最近一次判定耗时

按 rule_id 排序看 rule_eval_duration_ms 的 top 10,那几条就是你的成本中心。 单条规则的判定耗时接近它的执行频率(默认 @every 60s)时,这条规则已经排不开了。

处理办法通常是改规则,不是加机器:降低执行频率、缩小查询范围、把返回上万条序列的 查询先做聚合。

3. 数据库连接​

n9e_db_pool_in_use_connections # 正在用的连接数
n9e_db_pool_wait_count_total # 等过连接的次数
n9e_db_pool_wait_duration_seconds_total

in_use 长期贴着 [DB] MaxOpenConns(默认 150)、并且 wait_count_total 在涨, 就是数据库这一层排队了。先看是不是有慢查询,再考虑调大连接池。

4. 写入量与队列​

n9e_pushgw_samples_received_total{channel="prometheus"} # 每秒进来多少样本
n9e_pushgw_sample_queue_size{queueid="..."} # 各队列积压
n9e_pushgw_push_queue_error_total{queueid="..."} # 被丢的样本

队列个数默认等于 CPU 核数,全局准入上限是 队列数 × QueueMaxSize × 0.1。 push_queue_error_total 一旦非 0,就是真的在掉数据了,详见 Pushgw 队列、写入器与双写。

磁盘要单独算​

三份数据都落在本地盘上,各有各的上限:

数据配置项默认上限
内置时序库[EmbeddedTSDB] RetentionDuration / MaxBytes15 天 / 10 GiB,哪个先到删哪个
判定记录[Alert.EvalLog] RetentionHours / MaxDiskGB / PerRuleDailyMB192 小时 / 20 GB / 单规则每天 1024 MB
日志[Log] KeepHours / RotateNum / RotateSize默认输出到 stdout,不占盘

MaxBytes 留空或写 0 表示不限制内置时序库的磁盘用量——那就变成磁盘写满为止, 生产上不要这么配。

元数据库这边随时间增长的是三张表,清理任务的默认行为不一样:

表配置项默认
历史告警事件[Center] CleanAlertHisEventDay永久保留(<= 0 表示不清理),每天凌晨 2 点执行
通知记录[Center] CleanNotifyRecordDay7 天,每天凌晨 1 点执行
工作流执行记录[Center] CleanPipelineExecutionDay7 天,每天早上 6 点执行

历史告警事件默认不清理,事件量大的环境上线前就该显式设一个保留天数, 否则这张表会一直长。

按什么维度扩​

先定位是哪个数到顶了,再决定扩什么。加机器不能解决所有问题。

到顶的是该做的
判定耗时(规则排不开)加 n9e 实例——规则会自动重新分派到新实例上
判定耗时(少数几条规则很慢)改那几条规则,加机器没用
活跃序列数换外部时序库,见内置时序库的单 Center 限制
写入量拆出 n9e-pushgw,或者加 n9e 实例并在前面做负载均衡
数据库排队先查慢查询,再调 [DB] MaxOpenConns,最后才是加数据库规格
磁盘调保留期,或者把内置时序库换掉
Web 卡但判定正常拆出 n9e-alert,让判定和 Web 不抢 CPU

还有一项容易忽略的成本:Pushgw 会为每一台被监控的机器在自己的 /metrics 上暴露 一条 n9e_pushgw_sample_received_by_ident{host_ident="..."}。机器数量上万时, 光这一个指标就是上万条序列,而且没有开关能关掉它——采集夜莺自身指标时要把这份成本算进去。

为什么这里没有规格表​

「N 核 M 内存支持 K 条规则」这种数字,只有在写清楚「规则查的是什么数据源、 每次返回多少条序列、执行频率多少」之后才有意义,而这三项在不同环境里能差两个数量级: 一条 up == 0 的规则和一条扫一万条序列再做 topk 的规则,成本不在一个量级上。

给一个没有前提条件的数字,读者照着买机器,出问题的时候这份文档要负责任。 所以这里给的是量法和扩的方向:先在你自己的规模上跑起来,量上面四个数,再按需要扩。

相关​