komari 的节点如果很多的话建议数据库换为 PostgreSQL,提升明显

大鲨鱼 2026-07-13 18:51 1

已经迁移到了 PostgreSQL,你可以让 ai 帮你迁移,很快很方便



deepseek v4 pro 分析结果,ai 含量 100%


komari 源码中 SQLite 的局限


1、单连接写入

// metricstore.go:141-145
// SQLite 串行化写入:固定单写连接以避免 "database is locked" 竞争
opts = append(opts,
metric.WithMaxOpenConns(1), // ← 只有一个写连接
metric.WithMaxIdleConns(1),
metric.WithSQLiteReadPool(4), // 额外读池缓解读阻塞
)

所有写入——包括多个 agent 同时上报、compaction、数据清理——都必须排队经过这一个连接。


2、聚合查询回退

func sqlAggValueExpr(driver Driver, agg Aggregation) (string, bool) {
switch agg {
case AggStdDev:
switch driver {
case DriverMySQL, DriverPostgreSQL:
return "STDDEV_POP(value)", true // ← MySQL/PG 可下推 SQL
default:
return "", false // ← SQLite 不支持,回退到内存计算!
}
default:
if frac, ok := percentileFractionString(agg); ok {
if driver == DriverPostgreSQL {
// ← 仅 PostgreSQL 支持百分位下推!
return fmt.Sprintf("percentile_cont(%s) WITHIN GROUP (ORDER BY value)", frac), true
}
return "", false // ← SQLite/MySQL 都不支持,回退内存!
}
}
}


  • SQLite:必须把所有原始数据点从磁盘读到内存,在 Go 中完成计算

  • PostgreSQL:只需一个 SQL 查询,数据库引擎原生完成计算,只返回最终结果


对于保留 90 天、每分钟一个采样点的场景,单个指标就有 ~130,000 行。如果有 10 个 agent、20 个指标,那就是 2600 万行。SQLite 做一次 P95 查询可能要拉几十万行数据到内存,而 PostgreSQL 只返回一个数字。


3、写入锁竞争

// dbcore.go:386-402
// SQLite 同一时刻只允许一个写者;限制连接数可避免连接池层面的写写竞争。
// 负载历史每分钟会执行包含读和写的事务,若连接池允许多个连接,容易与
// ping 结果等短写入撞锁并导致整批负载记录回滚。
sqlDB.SetMaxOpenConns(1)

多个 agent 同时上报数据时,SQLite 下它们只能串行写入。busy_timeout=5000(5秒) 是一个缓冲区,但高频写入下仍可能触发 SQLITE_BUSY


4、Compaction 阻塞写入

// dialect_rollup.go:59
func (sqliteDialect) compactTxOptions() *sql.TxOptions { return nil }

SQLite compaction 事务使用默认隔离级别,由于只有单连接,compaction 期间所有 metric 写入都被阻塞


而 PostgreSQL 用 SERIALIZABLE 隔离级别 + 重试机制:


// dialect_rollup.go:81-83
func (postgresDialect) compactTxOptions() *sql.TxOptions {
return &sql.TxOptions{Isolation: sql.LevelSerializable}
}

写入不会被阻塞,只在真正冲突时才触发重试。




SQLite 的优化措施(源码中做了什么来缓解)


Komari 对 SQLite 做了大量优化,说明开发者清楚其局限:




















































优化 源码位置 效果
WAL 模式 dbcore.go:407-408 读写并发(读不阻塞写)
独立读连接池 (4个) metricstore.go:144 SELECT 走读池,减轻主连接压力
64MB 页缓存 dbcore.go:413 cache_size=-65536
256MB mmap config.go:168 大文件读取性能
_txlock=immediate dbcore.go:271 事务开始即获取写锁,避免锁升级死锁
busy_timeout=5000 dbcore.go:271 写锁等待最多 5 秒
temp_store=MEMORY dbcore.go:414 临时表放内存
synchronous=NORMAL dbcore.go:412 性能优先于持久性

这些优化让 SQLite 在中小规模下表现可接受,但不能改变其单写者架构本质。




PostgreSQL 在 Metric 场景下的具体优势




















































能力 SQLite PostgreSQL
并发写入 1 个连接串行 25 个连接并发
STDDEV 查询 内存计算(拉全量) SQL 下推
P50/P95/P99 查询 内存计算(拉全量) SQL 下推
Compaction 与写入并发 互相阻塞 不阻塞(SERIALIZABLE)
JSON 字段类型 TEXT JSONB(原生索引)
空间回收 VACUUM VACUUM FULL
连接池 无(单连接) 完整连接池
部署复杂度 零依赖 需要额外服务



PostgreSQL 显著优于 SQLite 的核心原因:




  1. 聚合查询性能可能差 10-100 倍:当查询涉及百分位或标准差时,SQLite 必须把所有原始点拉到应用层内存计算,而 PostgreSQL 只需要一个 SQL 查询。这是源码中最明确的性能分水岭 (dialect.go:399-444)。




  2. 高并发写入不会互相阻塞:SQLite 的 MaxOpenConns=1 在 agent 数量增长时会成为瓶颈。




  3. Compaction 不阻塞写入:SQLite 的 compaction 事务(清理过期数据+构建 rollup)会占用唯一的写连接,期间新数据无法写入。




一句话总结:对于小规模部署,Komari 对 SQLite 的优化已经足够好;但当 agent 数量和查询复杂度增长时,PostgreSQL 的 SQL 聚合下推能力(尤其是百分位查询)和真正的并发写入支持,使其在 metric 场景下确实比 SQLite 好很多——这个差异是架构性的,不是微调参数能弥补的

最新回复 (17)
  • solaireh3 07-13 18:52
    1

    就几台🐔,不想折腾了

  • happyfool 07-13 18:56
    2

    都上postgres了,不如再咬咬牙,全部切换Prometheus ^-^

    有点好奇,多少节点适合迁移数据库啊 ^-^

  • diead 07-13 18:57
    3

    PostgreSQL真的是越用越好用,现在我们公司的小项目以及基本全迁移过去了

  • wzdq 07-13 18:58
    4

    开发者用sqlite是为了方便,轻量使用

  • taong 07-13 18:59
    5

    新版我不会看延时和丢包了。

  • HelloWorldx 07-13 19:02
    6

    难道是这个问题,我一直显示丢包,但是点进去根本就没丢包,这个版本有点折腾了。 ^-^

  • heiyu 07-13 19:04
    7

    6个机需要吗

  • astom 07-13 19:09
    8

    浏览器卡怎么破

  • 東方不败 07-13 19:30
    9

    @HelloWorldx #6 我也有这个问题,不知道是不是网络问题,主控在国内,走的cf隧道,但是我在国内的机器是直接连面板,但是很多情况都是同一时刻丢包

  • HelloWorldx 07-13 19:35
    10

    @東方不败 #9 对都是同一刻丢包,但实际上没有丢包。我感觉是数据处理的问题了,等作者修复了。我今天把旧数据删除+重装探针都无法解决 ^-^

  • 東方不败 07-13 19:36
    11

    @HelloWorldx #10 感觉你的探针流畅丝滑啊 ^-^

  • HelloWorldx 07-13 19:37
    12

    @東方不败 #11 刚重装好 ^-^

  • 東方不败 07-13 19:38
    13

    @HelloWorldx #12 域名好长,直奔主题了 ^-^

  • HelloWorldx 07-14 02:53
    14

    @東方不败 #13 应该是主题的问题,刚刚主题作者更新完以后恢复正常了。我都没有显示任何丢包了,佬可以参考一下。 ^-^

  • corenuclear 07-14 08:12
    15

    节点少就不折腾了

  • 東方不败 07-14 08:25
    16

    @HelloWorldx #14 我刚刚看你的探针,在同一时间还是有丢包

  • HelloWorldx 07-14 11:18
    17

    @東方不败 #16 还真是,等作者修复了 ^-^

* 帖子来源NodeSeek
返回