Appearance
数据模型与落盘规范
数据库持久化模型
系统使用 MySQL 作为持久化后端,通过 SQLAlchemy ORM 管理 6 张核心表。表名可通过 RuntimeSettings.db_tables 配置映射(默认与 ORM __tablename__ 一致,生产环境常使用 dt_ 前缀)。
表 1:runs(运行记录)
存储每次仿真运行的元信息与生命周期状态。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
id | VARCHAR(128) | PK | 运行唯一标识,如 acceptance-e2e-20260211090035 |
scenario_id | VARCHAR(128) | NOT NULL | 关联场景标识 |
strategy_id | VARCHAR(64) | NOT NULL | 调度策略标识(如 round_robin、adaptive) |
mode | VARCHAR(32) | NOT NULL, DEFAULT 'mock' | 运行模式:mock / gateway |
status | VARCHAR(32) | NOT NULL, DEFAULT 'created' | 当前状态(见状态转换图) |
steps | INTEGER | NULLABLE | 总步数 K |
dt_seconds | FLOAT | NULLABLE | 步长 ΔT(秒) |
seed | INTEGER | NULLABLE | 随机种子 |
created_at | DATETIME | NOT NULL | 创建时间 |
started_at | DATETIME | NULLABLE | 启动时间 |
finished_at | DATETIME | NULLABLE | 结束时间 |
output_dir | VARCHAR(512) | NULLABLE | 文件落盘目录路径 |
current_step | INTEGER | NULLABLE, DEFAULT 0 | 当前执行到的步数 |
error_message | TEXT | NULLABLE | 失败时的错误信息 |
Run 状态转换图:
created ──→ running ──→ stopping ──→ stopped
│ │ │
│ ├──→ finished│
│ │ │
└──→ failed ←┘←───────────┘
↑
(任何非终态均可转入 failed)合法的状态转换矩阵(源自 repo.py:_ALLOWED_TRANSITIONS):
| 当前状态 | 可转向 |
|---|---|
created | running, stopped, failed |
running | stopping, stopped, finished, failed |
stopping | stopped, finished, failed |
stopped | (终态) |
finished | (终态) |
failed | (终态) |
表 2:run_summary(运行摘要统计)
每次 run 完成后写入的聚合摘要,与 runs 为 1:1 关系。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
run_id | VARCHAR(128) | PK, FK → runs.id (CASCADE) | 关联运行 ID |
avg_throughput_bps | FLOAT | NULLABLE | 平均吞吐(bps) |
avg_loss_rate | FLOAT | NULLABLE | 平均丢包率 |
p95_delay_ms | FLOAT | NULLABLE | P95 时延(ms) |
trace_count | INTEGER | NULLABLE | 总 trace 条数 |
received_count | INTEGER | NULLABLE | 成功接收条数 |
updated_at | DATETIME | NOT NULL | 最后更新时间 |
表 3:run_events(运行事件流)
记录 run 执行过程中的关键事件,与 runs 为 1:N 关系。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
id | INTEGER | PK, AUTO_INCREMENT | 事件序号 |
run_id | VARCHAR(128) | FK → runs.id (CASCADE), NOT NULL | 关联运行 ID |
event_type | VARCHAR(64) | NOT NULL | 事件类型(如 step_start、step_end、schedule、error) |
step_id | INTEGER | NULLABLE | 关联步骤号 |
payload_json | TEXT | NULLABLE | 事件详情(JSON 格式) |
created_at | DATETIME | NOT NULL | 事件产生时间 |
表 4:scenarios(场景配置)
存储通过 API CRUD 管理的场景定义,支持 YAML 文件导入。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
id | VARCHAR(128) | PK | 场景唯一标识 |
name | VARCHAR(256) | NOT NULL | 场景名称 |
nodes_json | TEXT | NOT NULL, DEFAULT '[]' | 节点配置(JSON 数组) |
traffic_json | TEXT | NOT NULL, DEFAULT '[]' | 业务流配置(JSON 数组) |
run_config_json | TEXT | NOT NULL, DEFAULT '{}' | 运行参数配置(JSON 对象) |
unet_config_json | TEXT | NULLABLE | UNET 特有配置(JSON 对象) |
created_at | DATETIME | NOT NULL | 创建时间 |
updated_at | DATETIME | NOT NULL | 最后更新时间 |
表 5:run_traces(Trace 原始事件)
存储每条消息的发送/接收事件,按 run 粒度批量写入。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
id | INTEGER | PK, AUTO_INCREMENT | 记录序号 |
run_id | VARCHAR(128) | FK → runs.id (CASCADE), NOT NULL, INDEX | 关联运行 ID |
step_id | INTEGER | NOT NULL | 步骤号 |
seq | INTEGER | NOT NULL | 序列号 |
tx_time_ms | INTEGER | NOT NULL | 发送时间戳(ms) |
rx_time_ms | INTEGER | NULLABLE | 接收时间戳(ms),未收到时为 NULL |
src | INTEGER | NOT NULL | 源节点 ID |
dst | INTEGER | NOT NULL | 目标节点 ID |
payload_bytes | INTEGER | NOT NULL, DEFAULT 0 | 用户数据长度(不含 header) |
received | BOOLEAN | NOT NULL, DEFAULT false | 是否成功接收 |
source | VARCHAR(32) | NOT NULL, DEFAULT 'unknown' | 数据来源(gateway / logonly / mock) |
索引: ix_run_traces_run_step_seq ON (run_id, step_id, seq)
表 6:run_metrics(聚合指标)
按 step 聚合的统计指标,运行过程中逐步写入。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
id | INTEGER | PK, AUTO_INCREMENT | 记录序号 |
run_id | VARCHAR(128) | FK → runs.id (CASCADE), NOT NULL, INDEX | 关联运行 ID |
step_id | INTEGER | NOT NULL | 步骤号 |
t_window_start_ms | INTEGER | NOT NULL, DEFAULT 0 | 窗口起始时间(ms) |
t_window_end_ms | INTEGER | NOT NULL, DEFAULT 0 | 窗口结束时间(ms) |
throughput_bps | FLOAT | NOT NULL, DEFAULT 0.0 | 吞吐量(bps) |
loss_rate | FLOAT | NOT NULL, DEFAULT 0.0 | 丢包率(0~1) |
delay_p50_ms | FLOAT | NOT NULL, DEFAULT 0.0 | P50 时延(ms) |
delay_p95_ms | FLOAT | NOT NULL, DEFAULT 0.0 | P95 时延(ms) |
sent_count | INTEGER | NOT NULL, DEFAULT 0 | 当步发送总数 |
recv_count | INTEGER | NOT NULL, DEFAULT 0 | 当步接收总数 |
sync_error_ms | FLOAT | NOT NULL, DEFAULT 0.0 | 同步误差(ms) |
overhead_ms | FLOAT | NOT NULL, DEFAULT 0.0 | 调度开销(ms) |
索引: ix_run_metrics_run_step ON (run_id, step_id)
ER 关系图
┌─────────────┐
│ scenarios │
└─────────────┘
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ run_summary │────→│ runs │←────│ run_events │
│ (1:1) │ FK │ │ FK │ (1:N) │
└─────────────┘ └──────┬──────┘ └─────────────┘
│
┌────────────┼────────────┐
│ FK │ FK
v v
┌─────────────┐ ┌─────────────┐
│ run_traces │ │ run_metrics │
│ (1:N) │ │ (1:N) │
└─────────────┘ └─────────────┘runs是核心主表,其余 4 张表通过run_id外键关联(ON DELETE CASCADE)scenarios表独立存储,通过runs.scenario_id逻辑关联(非外键约束)
文件落盘规范
Run 目录结构(必须)
每次运行输出一个目录(作为数据库持久化的补充备份):
runs/<run_id>/
scenario.yaml
strategy.json
versions.json
schedule_decisions.csv
traces.csv
metrics.csv
report.md其中:
scenario.yaml:本次运行使用的场景快照strategy.json:策略 id 与参数快照versions.json:可复现所需的版本与环境信息schedule_decisions.csv:每步的调度决策与调度开销traces.csv:包级别原始事件(发送/接收)metrics.csv:聚合指标(按 step 或窗口)report.md:本次 run 的关键统计与图表
versions.json(最小字段)
git_commit:代码提交版本python_version:Python 版本deps:关键依赖版本(可用 pip freeze 的子集)unet_cmd:UNET 启动命令(如适用)unet_host/unet_portscenario_id/strategy_id/seed/K/delta_t_s
Payload Header 协议(24 bytes,little-endian)
为保证跨 UNET 版本/事件字段差异时仍能稳定计算指标,发送 payload 前增加固定头部:
run_id:uint32step_id:uint32seq:uint32tx_time_ms:uint64src:uint16dst:uint16
编码:
struct.pack('<IIIQHH', run_id, step_id, seq, tx_time_ms, src, dst)payload = header + user_data
traces 字段说明(数据库 + CSV 对照)
| 数据库字段 (run_traces) | CSV 旧字段名 | 说明 |
|---|---|---|
tx_time_ms | t_tx_ms | 发送时间(来自 header.tx_time_ms) |
rx_time_ms | t_rx_ms | 接收时间(来自系统采集或 wall-clock) |
run_id | run_id | 运行标识 |
step_id | step_id | 步骤号 |
seq | seq | 序列号 |
src | src | 源节点 |
dst | dst | 目标节点 |
payload_bytes | payload_len | 用户数据长度 |
received | ok | 是否成功接收 |
source | meta_json.source | 数据来源标识 |
metrics 字段说明(数据库 + CSV 对照)
| 数据库字段 (run_metrics) | CSV 旧字段名 | 说明 |
|---|---|---|
step_id | step_id | 步骤号 |
throughput_bps | throughput_bps | 吞吐量 |
loss_rate | loss_rate | 丢包率 |
delay_p50_ms | delay_p50_ms | P50 时延 |
delay_p95_ms | delay_p95_ms | P95 时延 |
sync_error_ms | sync_error_ms | 同步误差 |
overhead_ms | schedule_overhead_ms | 调度开销 |
t_window_start_ms | (新增) | 窗口起始时间 |
t_window_end_ms | (新增) | 窗口结束时间 |
sent_count | (新增) | 当步发送总数 |
recv_count | (新增) | 当步接收总数 |