mirror of
https://github.com/tradecatlabs/vibe-coding-cn.git
synced 2026-07-28 11:17:46 +00:00
227 lines
7.1 KiB
Markdown
227 lines
7.1 KiB
Markdown
|
|
<a id="reference-engineering-practice-7-dataset-first-数据服务结构"></a>
|
|||
|
|
# Dataset First 数据服务结构
|
|||
|
|
|
|||
|
|
适合长期运行、补数、巡检、血缘、质量治理的数据产品服务。
|
|||
|
|
|
|||
|
|
判断规则:
|
|||
|
|
|
|||
|
|
> 如果服务的核心交付物是“稳定数据集”,而不是页面、接口或一次性脚本,就优先使用 Dataset First。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-一句话"></a>
|
|||
|
|
##### 一句话
|
|||
|
|
|
|||
|
|
以 dataset 为边界,以 schema/data contract 为先,以 runtime/registry/config 为共享控制面,以 collect/backfill/repair/validate 为实现单元。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-适合"></a>
|
|||
|
|
##### 适合
|
|||
|
|
|
|||
|
|
- 行情事实采集服务。
|
|||
|
|
- 另类事件采集服务。
|
|||
|
|
- 周期轮询快照服务。
|
|||
|
|
- 原子事件流 + 时间桶聚合并存的数据服务。
|
|||
|
|
- 需要长期运行、补数、巡检、血缘、质量治理的数据服务。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-不适合直接照抄"></a>
|
|||
|
|
##### 不适合直接照抄
|
|||
|
|
|
|||
|
|
- 纯 API 网关。
|
|||
|
|
- 纯 Web 应用。
|
|||
|
|
- 纯交易执行服务。
|
|||
|
|
- 一次性脚本工具。
|
|||
|
|
- 不产出稳定 dataset 的临时任务。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-核心原则"></a>
|
|||
|
|
##### 核心原则
|
|||
|
|
|
|||
|
|
1. Dataset First:顶层先按 dataset 划分,而不是按 `collector/parser/writer/task` 划分。
|
|||
|
|
2. Contract First:先定义目标落表、字段语义、主键、时间列、分区策略和刷新粒度。
|
|||
|
|
3. Layered Modeling:原子层、聚合层、事件流、时间桶、运行状态分开建模。
|
|||
|
|
4. Shared Control Plane:`config.py`、`registry.py`、`service_entry.py`、`runtime/*` 统一收口。
|
|||
|
|
5. Legacy Is Explicit:迁移期 legacy 壳只能兼容转发,新逻辑不得回流旧路径。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-标准目录"></a>
|
|||
|
|
##### 标准目录
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
service-root/
|
|||
|
|
├── README.md
|
|||
|
|
├── AGENTS.md
|
|||
|
|
├── pyproject.toml
|
|||
|
|
├── scripts/
|
|||
|
|
│ ├── start.sh
|
|||
|
|
│ ├── verify.sh
|
|||
|
|
│ └── check_legacy_shells.sh
|
|||
|
|
├── src/<service_name>/
|
|||
|
|
│ ├── __init__.py
|
|||
|
|
│ ├── config.py
|
|||
|
|
│ ├── registry.py
|
|||
|
|
│ ├── service_entry.py
|
|||
|
|
│ ├── common/
|
|||
|
|
│ ├── runtime/
|
|||
|
|
│ │ ├── stack_runner.py
|
|||
|
|
│ │ ├── process_utils.py
|
|||
|
|
│ │ ├── <group>_runner.py
|
|||
|
|
│ │ └── <group>_worker.py
|
|||
|
|
│ ├── writers/
|
|||
|
|
│ ├── validators/
|
|||
|
|
│ └── datasets/
|
|||
|
|
│ ├── <dataset_a>/
|
|||
|
|
│ │ ├── contract.py
|
|||
|
|
│ │ ├── collect.py
|
|||
|
|
│ │ ├── backfill.py
|
|||
|
|
│ │ ├── repair.py
|
|||
|
|
│ │ ├── writer.py
|
|||
|
|
│ │ ├── validate.py
|
|||
|
|
│ │ └── README.md
|
|||
|
|
│ ├── <dataset_b>/
|
|||
|
|
│ └── _reserved/
|
|||
|
|
├── tests/
|
|||
|
|
│ ├── unit/
|
|||
|
|
│ ├── integration/
|
|||
|
|
│ └── fixtures/
|
|||
|
|
└── legacy/ or old-shells/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-dataset-最小结构"></a>
|
|||
|
|
##### Dataset 最小结构
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
<dataset>/
|
|||
|
|
├── contract.py
|
|||
|
|
├── collect.py
|
|||
|
|
├── backfill.py
|
|||
|
|
├── repair.py
|
|||
|
|
├── writer.py
|
|||
|
|
├── validate.py
|
|||
|
|
└── README.md
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
职责边界:
|
|||
|
|
|
|||
|
|
- `contract.py`:定义 dataset key、resource_id、物理表、主键、幂等键、时间语义、字段语义。
|
|||
|
|
- `collect.py`:实时采集或轮询采集主逻辑。
|
|||
|
|
- `backfill.py`:历史补数、文件回填、分页补齐。
|
|||
|
|
- `repair.py`:缺口修复、异常恢复、局部重算。
|
|||
|
|
- `writer.py`:统一落库、批量写入、去重、冲突处理。
|
|||
|
|
- `validate.py`:数据质量检查、行数、字段、时间连续性校验。
|
|||
|
|
- `README.md`:说明该 dataset 的输入、输出、约束与边界。
|
|||
|
|
|
|||
|
|
如果某个 dataset 没有 `repair` 或 `backfill`,必须在 registry 中显式标记为不支持。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-registry-真相矩阵"></a>
|
|||
|
|
##### Registry 真相矩阵
|
|||
|
|
|
|||
|
|
`registry.py` 至少应定义:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
dataset_key
|
|||
|
|
resource_id
|
|||
|
|
runtime_status # active | backfill_only | reserved | disabled
|
|||
|
|
physical_table
|
|||
|
|
group # lf | hf | events | snapshots
|
|||
|
|
source_kind # ws | rest | zip | scrape | file | api
|
|||
|
|
collect_supported
|
|||
|
|
backfill_supported
|
|||
|
|
repair_supported
|
|||
|
|
default_enabled
|
|||
|
|
owner
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
推荐额外字段:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
symbol_scope
|
|||
|
|
refresh_granularity
|
|||
|
|
retention_policy
|
|||
|
|
partition_key
|
|||
|
|
schema_version
|
|||
|
|
sensitivity
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Registry 的作用:
|
|||
|
|
|
|||
|
|
- 它是 dataset 清单的单一真相源。
|
|||
|
|
- 文档、运行、血缘、权限、门禁都应从 registry 派生。
|
|||
|
|
- 没有 registry,就会回到“数据集藏在脚本里”的旧问题。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-dataset-命名"></a>
|
|||
|
|
##### Dataset 命名
|
|||
|
|
|
|||
|
|
推荐格式:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
<market>_<instrument>_<topic>_<granularity?>_<layer?>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
示例:
|
|||
|
|
|
|||
|
|
- `spot_trades`
|
|||
|
|
- `futures_um_trades`
|
|||
|
|
- `futures_um_book_ticker`
|
|||
|
|
- `futures_um_book_depth`
|
|||
|
|
- `candles_1m`
|
|||
|
|
- `futures_metrics_5m`
|
|||
|
|
- `futures_um_metrics_atomic`
|
|||
|
|
|
|||
|
|
命名要求:
|
|||
|
|
|
|||
|
|
- 名字必须表达数据是什么,而不是代码怎么实现。
|
|||
|
|
- `_reserved/` 只用于预留未来命名空间,不用于临时文件。
|
|||
|
|
- 事件流、快照、时间桶、派生结果要在命名或 contract 中显式表达。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-service-entry-与-runtime"></a>
|
|||
|
|
##### Service Entry 与 Runtime
|
|||
|
|
|
|||
|
|
`service_entry.py` 统一入口只做:
|
|||
|
|
|
|||
|
|
- `plan`
|
|||
|
|
- `start`
|
|||
|
|
- `stop`
|
|||
|
|
- `status`
|
|||
|
|
- `restart`
|
|||
|
|
|
|||
|
|
它不直接写业务逻辑,只负责读取 config、读取 registry、调用 runtime runner、输出运行真相。
|
|||
|
|
|
|||
|
|
`runtime/` 负责:
|
|||
|
|
|
|||
|
|
- 进程编排。
|
|||
|
|
- 模式分组。
|
|||
|
|
- PID、日志、健康状态。
|
|||
|
|
- cold-start、restart、stop 行为一致性。
|
|||
|
|
|
|||
|
|
业务代码不允许各自实现第二套守护逻辑。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-数据模型分层"></a>
|
|||
|
|
##### 数据模型分层
|
|||
|
|
|
|||
|
|
推荐区分:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
atomic # 原子事件/原子明细
|
|||
|
|
snapshot # 单次轮询快照
|
|||
|
|
bucketed # 时间桶聚合结果
|
|||
|
|
derived # 从事实层再派生的结果
|
|||
|
|
reserved # 预留但未启用
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
事件流模型适合 trades、orderbook updates、tick events、message stream,重点是顺序、幂等、去重、水位线。
|
|||
|
|
|
|||
|
|
时间桶 / 快照模型适合 candles、metrics、periodic snapshots、polling APIs,重点是覆盖、补齐、时间边界一致性。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-新建数据服务流程"></a>
|
|||
|
|
##### 新建数据服务流程
|
|||
|
|
|
|||
|
|
1. 先定 dataset 清单:哪些 active、哪些 backfill_only、哪些 reserved。
|
|||
|
|
2. 先写 contract:字段、主键、时间列、分区策略、资源 ID、schema version。
|
|||
|
|
3. 再建 registry、config、service_entry、runtime。
|
|||
|
|
4. 逐个实现 dataset:`contract -> writer -> collect -> backfill -> validate -> repair`。
|
|||
|
|
5. 最后补 README、AGENTS、verify/CI、资源目录、血缘映射、smoke。
|
|||
|
|
|
|||
|
|
<a id="reference-engineering-practice-外部源码接入流程"></a>
|
|||
|
|
##### 外部源码接入流程
|
|||
|
|
|
|||
|
|
1. 先盘点外部源码实际产出的数据对象,不先搬代码。
|
|||
|
|
2. 把原项目脚本反向映射为 dataset。
|
|||
|
|
3. 将 API client、auth、rate limiter、storage client、retry/backoff 抽到 `common/`、`runtime/` 或 `writers/`。
|
|||
|
|
4. 将 legacy 壳显式隔离,只允许兼容转发,不允许承载新逻辑。
|