总体结论
推荐 1.3.0。架构更优、资源效率更高、可维护性更强。数据库增长更大是事实,但属于可调节的设计取舍,非架构缺陷。
一、依赖与二进制体积
| 维度 | 1.2.5-fix2 | 1.3.0 |
|---|---|---|
| gRPC | 直接依赖 google.golang.org/grpc | 已移除(仅 protobuf indirect) |
| OIDC | 直接依赖 coreos/go-oidc/v3 | 已移除 |
| 直接依赖数 | 19 | 17 |
移除 gRPC 对二进制体积影响显著(通常减少 5-10MB),同时缩小攻击面。
二、数据存储与 I/O
| 维度 | 1.2.5-fix2 | 1.3.0 |
|---|---|---|
| 监控数据 | 全部写入主库 komari.db(records + records_long_term + gpu_records 等 4 张表) | 独立 metrics.db,主库仅存配置/客户端 |
| 写入模式 | 同步逐条事务(每个客户端每次上报一次完整 transaction) | 异步批量(3s 窗口合并写入,低资源模式 30s 窗口) |
| 压缩策略 | 每分钟触发,内存中做 15 分钟百分位聚合 | 分层 rollup(raw 15min → 1min/48h → 5min/14d → 1h/14d),每 5 分钟 compact |
| SQLite 缓存 | 固定 64MB (cache_size=-65536) | 正常 64MB;低资源模式 8MB |
| mmap | 未配置(SQLite 默认) | 低资源模式显式 mmap_size=0 |
| temp_store | MEMORY | 低资源模式改为 FILE(节省 RAM) |
| 读连接池 | 无(单连接) | 正常模式 4 读连接;低资源模式 0 |
三、资源自适应
1.3.0 新增 resourceprobe 模块,首次启动自动探测:
- 内存 < 1.5GB → 低资源
- 磁盘 < 15GB → 低资源
- CPU / 随机写 IOPS 不达标 → 低资源
探测结果持久化后自动调整主库和 metrics 库的 SQLite PRAGMA,在低配 VPS 上显著降低内存和磁盘 I/O 占用。
四、架构质量
| 维度 | 1.2.5-fix2 | 1.3.0 |
|---|---|---|
| 启动流程 | cmd/server.go 单函数 238 行,log.Fatal 散落 | internal/server 显式生命周期,LIFO cleanup |
| 错误处理 | 半初始化状态仍可能对外服务 | 任一阶段失败即中止 + 资源回收 |
| 关闭 | 5s 超时 | 10s 超时 + 注册制 cleanup |
| 升级安全 | 无 | 版本升级自动备份 ./data |
| 额外功能 | Nezha 兼容 + Cloudflared 隧道 | 安装向导 + 旧版迁移 + Metric Store 恢复 + 备份/更新 |
五、1.3.0 数据库增长更大的原因
5.1 每次上报写入量:1 行 vs 15+ 行
- 1.2.5:每次客户端上报 →
records表写入 1 行(~20 列打包) 1.3.0:每次上报 → 拆成 15 个独立 metric point:
- cpu.usage, memory.used, swap.used, load.average, disk.used
- net.in.rate, net.out.rate, net.total.up, net.total.down
- traffic.up, traffic.down, process.count, connections.tcp, connections.udp, gpu.usage
- 如有 GPU 设备,每设备再加 4 个 point
5.2 Rollup 多层冗余保留
1.2.5 只有一种长期数据:15 分钟粒度,保留 30 天。
1.3.0 同时维护三层重叠 rollup:
| 层级 | 粒度 | 默认最大保留 | 每 metric 桶数 |
|---|---|---|---|
| Tier 1 | 1 分钟 | 48 小时 | 2,880 |
| Tier 2 | 5 分钟 | 14 天 | 4,032 |
| Tier 3 | 1 小时 | 14 天 | 336 |
三层是重叠的,不是互斥的。最近 48 小时内同一数据同时存在 1min + 5min 两个粒度。
5.3 每个 rollup 桶体积大
每个 rollup bucket 存储完整统计摘要:
- count / sum / sumSq(用于 avg 和 stddev)
- min / max
- first / last(值 + 时间戳)
- t-digest(用于任意百分位查询)
序列化后每桶约 200-400 字节。
5.4 定量对比(单客户端、无 GPU)
| 1.2.5 | 1.3.0 | |
|---|---|---|
| 长期存储行数 | 2,880 行(30 天) | 15 metrics × 7,248 桶 = 108,720 桶(14 天) |
| 每行/桶大小 | ~160 bytes(紧凑列) | ~250-350 bytes(含 t-digest) |
| 估算体积 | ~450 KB | ~30 MB |
注:1.2.5 默认保留 30 天,1.3.0 内部 tier 最长 14 天(可通过后台保留天数进一步缩短)。即使将 1.2.5 换算为 14 天(1,344 行 ≈ 210 KB),1.3.0 仍大约 100 倍以上。
5.5 设计取舍
| 1.2.5 思路 | 1.3.0 思路 |
|---|---|
| 空间优先:只存 P70 百分位单值 | 查询优先:保留完整统计,支持 avg/min/max/P50/P95/P99/stddev 任意聚合 |
| 固定 15min 粒度 | 多粒度适配不同时间范围查询 |
| 不可回溯原始分布 | 可回溯任意百分位 |
六、Tier 与后台"保留天数"的关系
后台的"保留天数"是每个 metric 的总保留上限,会截断所有内部 tier(见 5.2 节表格)。比如 cpu.usage 设 3 天,那么无论 tier 本身允许 14 天,cpu 数据最多只存 3 天。
实际保留 = min(tier 自身保留, 指标保留天数)
因此后台保留天数是控制数据库体积最直接的手段。
七、推荐保留天数配置
| 指标 | 推荐天数 | 理由 |
|---|---|---|
| cpu.usage | 3 | 排查性能问题核心指标 |
| memory.used | 3 | 同上 |
| load.average | 3 | 同上 |
| disk.used | 3 | 增长缓慢,3 天不占多少 |
| net.in.rate / net.out.rate | 1 | 实时性强,历史价值低 |
| net.total.up / net.total.down | 1 | counter 类型,只需看当前累计 |
| traffic.up / traffic.down | 1 | 流量统计靠 traffic report,不需长存 |
| connections.tcp / udp | 1 | 瞬态数据 |
| process.count | 1 | 瞬态数据 |
| swap.used | 1 | 辅助指标 |
| ping.latency_ms | 3 | 网络质量趋势有用 |
| ping.loss | 1 | 丢包看近期即可 |
| GPU 全部 | 0 | 无 GPU 则关闭 |
如需进一步压缩:把 cpu/memory/load/disk/ping 从 3 降到 2,总体积再减 ~30%。但 3 天是排查"前天出了什么问题"的最低实用窗口,不建议再低。
Tcping 或 Ping 的检测频率建议
对于“只是查看时间段延迟”这个需求来说,300秒(5分钟)是一个非常合适且常见的间隔,无论你用的是 Ping(ICMP协议)还是 Tcping(TCP协议)。这个频率在业界被广泛采用,主要基于以下几点考虑:
- 满足趋势分析需求:如果你是为了观察网络质量的变化趋势、判断是否存在“网络抖动”或“高峰拥堵”,5分钟一次的采样粒度已经完全足够。它能清晰描绘出延迟的波动曲线,又不会因为数据点太密而难以看清整体走向。
- 降低“噪音”干扰:网络延迟会受瞬间流量波动的影响而产生“毛刺”。5分钟的间隔天然过滤掉了这些瞬时抖动,让你看到的数据更能反映该时间段内的平均网络质量。
需要留意的是:Tcping 和 Ping 在实现原理上有所不同,这会影响你对数据的解读:
- 资源开销差异:Tcping 的成本比 Ping 高得多。Ping 是操作系统内核级处理,不经过用户态进程调度,开销极小;而 Tcping 需要发起 TCP 三次握手流程(通常在收到 SYN-ACK 后即发送 RST 主动断开,不会进入 ESTABLISHED 状态)。不过,300秒一次的频率对于任何现代服务器来说都是完全可以忽略不计的负载,非常安全。
- 数据含义差异:Tcping 测量的严格来说是传输层(TCP)握手延迟,而非应用层延迟,它受服务器 CPU 负载和连接队列状态的影响较大;而 Ping 测量的是纯网络层线路延迟。如果你关心的是业务端口可达性(如 80 或 443 端口),用 Tcping 更合适,因为它能穿透“禁 Ping 但开放业务端口”的防火墙策略;如果只是看网络线路质量,用 Ping 即可。
总结来说:300秒一次的频率,非常适合做日常的延迟趋势记录和故障回溯。如果你确实想捕捉瞬间的高延迟或丢包,那才需要把间隔缩短到30秒或60秒;否则,保持300秒就很好。
实战建议:两者结合使用效果最佳——用 Ping 监控底层网络基线(排查路由抖动、运营商丢包),用 Tcping 监控业务可用性(验证端口是否开放、服务响应是否正常),这样既能区分“网络问题”还是“服务问题”,又能在告警时快速定位故障边界。
八、1.2.5-fix2 唯一优势
- 代码更简单,少约 20 个源文件
- 正常模式下少一个 DB 连接(无独立 metrics.db)
- 无首次启动探测开销(约 9 秒一次性)
- 数据库体积更小
但这些不构成实质优势——1.3.0 的复杂度换来了可维护性和运行时资源节约。
九、最终建议
选 1.3.0。无论是高配还是低配环境,批量写入 + 分层 rollup + 低资源自适应都比 1.2.5 的逐条同步写 + 固定 64MB 缓存更省资源。移除 gRPC 让二进制更小、攻击面更窄。数据库增长可通过后台保留天数配置有效控制。
AI
评论已关闭