Files

227 lines
7.1 KiB
Markdown
Raw Permalink Normal View History

2026-06-01 00:48:27 +08:00
<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 壳显式隔离,只允许兼容转发,不允许承载新逻辑。