Align architecture, protocol, API, storage, security and deployment documentation with default mutual measurements and the Agent link board.
5.4 KiB
Backend 存储
实现位于 MoShiro.Backend.Storage.Sqlite,负责实现 Backend.Application 中定义的端口接口,只做读写,不含业务逻辑。降采样和分析由 Application 调用 Analysis 完成。
1. 目录布局
data/
├─ moshiro.db # SQLite:配置、身份、原始块索引、指标、测试结果
├─ backups/ # Backend 更新前的数据库备份
└─ raw/
└─ 2026-09-27/ # 按 UTC 日期分目录,保留期满整目录删除
├─ agt_01J…/ # 每个 Agent 一个目录
│ ├─ udp_echo.seg # 段文件:同一天、同一 Kind 的块依次追加
│ ├─ tcp_echo.seg
│ └─ tsk_…_icmp_echo.seg # 目标任务
└─ tests/tst_01J…/phase0.seg …
- 段文件:把收到的 RawChunk 原样追加写入(块本身已经带 crc,并且自描述),SQLite 只记录
(segment, offset, length)。每 10 秒一块也不会产生海量小文件。 - 写入顺序:追加写入 →
fsync(每批合并执行一次)→ 插入索引 → 由收件箱确认(Fleet 回复fleet.outbox.ack)。启动时截断没有索引记录的段文件尾部。 - 去重:
chunk_id已存在时,直接回复 ACK。
2. SQLite 配置
journal_mode=WAL、synchronous=NORMAL、foreign_keys=ON、busy_timeout=5000。- 单写入者:所有写操作经过一个有界
Channel,由一个后台循环执行;读操作使用独立的只读连接池。 - 时间统一存储为 Unix 毫秒
INTEGER(UTC);表结构版本记录在PRAGMA user_version,迁移脚本为内置 SQL。
3. 表结构
完整定义以 Schema.cs 为准(当前版本 16,迁移为按版本号追加的内置 SQL)。agents、join_tokens 及公钥、状态版本字段同时作为 Fleet 的 IFleetStore 实现,与其他数据放在同一个 moshiro.db,由同一个单写入者写入。CI 签名的发布清单存在 settings 表中(release.<组件>.manifest、release.<组件>.signature),面板原样保存和转发。
| 类别 | 表 | 说明 |
|---|---|---|
| 身份与注册 | agents、join_tokens、node_meta |
节点公钥、状态、地址(含手填标记)、IPv6 诊断、task_version / applied_task_version、row_version(ETag);node_meta 保存系统、构建信息与国家 / 运营商;agents.name 仅在非 pending 节点间唯一 |
| 账户与信任 | users、sessions、api_tokens、passkeys、operator_sets、audit_log、settings |
会话与 CSRF、能力化 API 令牌、passkey、操作员集合链、审计日志、键值设置 |
| 任务 | tasks、tests、test_results |
tasks.scope 为 line 或 target,agent_id 为空表示全局模板,base_task_id 指向被覆盖的模板;tests 记录按需测试及其阶段、地址族、线路;test_results 保存指标与曲线 |
| 原始数据索引 | raw_segments、raw_chunks |
raw_chunks 记录 (segment, offset, length)、series(line:<dialer_id>[:ipv6] 或 target:<task_id>)、Kind、任务、测试、起止时间 |
| 指标 | metric_10s、metric_1m、metric_5m、metric_1h、metric_versions |
每个桶一行,metrics 为 AccumulatorCodec 编码的 {metric_id: 累加器状态};主键 (agent_id, series, window_start);metric_versions 保存指标指纹与重算进度 |
| 分析调度 | analysis_queue、rollup_dirty |
待计算窗口(seq 递增,完成时只删除序号未变的项,处理期间到达的迟到块不丢更新);待降采样的桶(先低层 5 分钟,再高层 1 小时) |
| 观测 | events、host_samples |
节点事件;每个节点每分钟一行的主机资源汇总 |
新增 Kind 或指标不需要改表结构:指标是 metric_*.metrics 中的一个键,Kind 只是 raw_chunks.kind 的一个取值。1 秒精度的热层在内存中,不落盘,见 query.md 第 3 节。
4. 保留
| 数据 | 默认保留 |
|---|---|
| 持续任务的原始段文件 | 30 天 |
| 按需测试的原始段文件 | 90 天 |
| 热层(1s,内存) | 最近 1 小时 |
metric_10s |
48 小时 |
metric_1m |
30 天 |
metric_5m |
365 天 |
metric_1h、tests、test_results |
永久 |
events |
365 天 |
保留期在管理端设置中修改,键为 retention.raw_days、retention.test_raw_days、retention.metric_10s_hours、retention.metric_1m_days、retention.metric_5m_days、retention.events_days、retention.host_days(主机样本,默认 7 天)。
降采样由 Application 的 AnalysisScheduler 驱动:读取下一级的累加器状态,合并后写回上一层,待处理的桶记录在 rollup_dirty。
5. 容量估算
以 15 个 Agent、默认模板(udp_echo 10 Hz + tcp_echo 20 Hz)为例:
| 数据 | 估算 |
|---|---|
| 原始数据 | 每条线路约 7 MB/天(udp_echo)+ 14 MB/天(tcp_echo 及内核采样)≈ 21 MB/天;15 条线路约 0.3 GB/天,30 天约 9.5 GB |
| 按需测试 | 一次 hy2_ladder 约 1.5 MB;每条线路每天 4 次,90 天约 8 GB |
| SQLite | 指标窗口和降采样约 1~2 GB/年 |
写入量约每秒 3 块,单写入者可以承载。以上为估算值。
6. 查询
时间段、自动步长、数据源选择、现场合并和降级规则见 query.md。