适合长期运行、补数、巡检、血缘、质量治理的数据产品服务。
判断规则:
如果服务的核心交付物是“稳定数据集”,而不是页面、接口或一次性脚本,就优先使用 Dataset First。
以 dataset 为边界,以 schema/data contract 为先,以 runtime/registry/config 为共享控制面,以 collect/backfill/repair/validate 为实现单元。
- 行情事实采集服务。
- 另类事件采集服务。
- 周期轮询快照服务。
- 原子事件流 + 时间桶聚合并存的数据服务。
- 需要长期运行、补数、巡检、血缘、质量治理的数据服务。
- 纯 API 网关。
- 纯 Web 应用。
- 纯交易执行服务。
- 一次性脚本工具。
- 不产出稳定 dataset 的临时任务。
- Dataset First:顶层先按 dataset 划分,而不是按
collector/parser/writer/task划分。 - Contract First:先定义目标落表、字段语义、主键、时间列、分区策略和刷新粒度。
- Layered Modeling:原子层、聚合层、事件流、时间桶、运行状态分开建模。
- Shared Control Plane:
config.py、registry.py、service_entry.py、runtime/*统一收口。 - Legacy Is Explicit:迁移期 legacy 壳只能兼容转发,新逻辑不得回流旧路径。
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/
<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 中显式标记为不支持。
registry.py 至少应定义:
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
推荐额外字段:
symbol_scope
refresh_granularity
retention_policy
partition_key
schema_version
sensitivity
Registry 的作用:
- 它是 dataset 清单的单一真相源。
- 文档、运行、血缘、权限、门禁都应从 registry 派生。
- 没有 registry,就会回到“数据集藏在脚本里”的旧问题。
推荐格式:
<market>_<instrument>_<topic>_<granularity?>_<layer?>
示例:
spot_tradesfutures_um_tradesfutures_um_book_tickerfutures_um_book_depthcandles_1mfutures_metrics_5mfutures_um_metrics_atomic
命名要求:
- 名字必须表达数据是什么,而不是代码怎么实现。
_reserved/只用于预留未来命名空间,不用于临时文件。- 事件流、快照、时间桶、派生结果要在命名或 contract 中显式表达。
service_entry.py 统一入口只做:
planstartstopstatusrestart
它不直接写业务逻辑,只负责读取 config、读取 registry、调用 runtime runner、输出运行真相。
runtime/ 负责:
- 进程编排。
- 模式分组。
- PID、日志、健康状态。
- cold-start、restart、stop 行为一致性。
业务代码不允许各自实现第二套守护逻辑。
推荐区分:
atomic # 原子事件/原子明细
snapshot # 单次轮询快照
bucketed # 时间桶聚合结果
derived # 从事实层再派生的结果
reserved # 预留但未启用
事件流模型适合 trades、orderbook updates、tick events、message stream,重点是顺序、幂等、去重、水位线。
时间桶 / 快照模型适合 candles、metrics、periodic snapshots、polling APIs,重点是覆盖、补齐、时间边界一致性。
- 先定 dataset 清单:哪些 active、哪些 backfill_only、哪些 reserved。
- 先写 contract:字段、主键、时间列、分区策略、资源 ID、schema version。
- 再建 registry、config、service_entry、runtime。
- 逐个实现 dataset:
contract -> writer -> collect -> backfill -> validate -> repair。 - 最后补 README、AGENTS、verify/CI、资源目录、血缘映射、smoke。
- 先盘点外部源码实际产出的数据对象,不先搬代码。
- 把原项目脚本反向映射为 dataset。
- 将 API client、auth、rate limiter、storage client、retry/backoff 抽到
common/、runtime/或writers/。 - 将 legacy 壳显式隔离,只允许兼容转发,不允许承载新逻辑。