4.2 KiB
DHT 元数据搜索服务开发约定
项目目标
本项目用于持续或间歇地从 BitTorrent DHT 网络发现 infohash 获取元数据并提供本地全文搜索和高性能过滤能力
基础 DHT 协议和抓取能力保留在 dht-crawler 中
面向最终用户运行的服务代码统一放在 dht-search 中
技术方案
- Tokio 负责异步任务调度网络任务和有界队列
- RocksDB 负责权威数据持久化精确去重抓取状态和索引状态
- Tantivy 负责可重建的全文搜索过滤排序和结果聚合
- Axum 负责 HTTP 搜索接口详情接口和运行状态接口
- BLAKE3 负责计算规范化内容结构指纹
- Serde 负责配置领域对象和接口数据的序列化
- Tracing 负责结构化日志和故障定位
RocksDB 是唯一权威数据源
Tantivy 索引必须能够从 RocksDB 完整重建
数据处理流程
- DHT 采集器发现 infohash
- 内存近期缓存过滤高频重复
- RocksDB 精确判断 infohash 是否已处理
- 未处理的 infohash 进入有界 Metadata 下载队列
- Metadata 完成校验和规范化后计算内容指纹
- 使用 RocksDB WriteBatch 原子保存元数据去重映射和待索引状态
- 后台索引任务批量写入 Tantivy
- Tantivy 提交成功后将记录状态更新为已索引
- Axum 只通过搜索和存储抽象读取数据
所有任务队列必须有明确容量并在队列满时产生背压
禁止通过无限队列维持表面吞吐
去重规则
第一层以 infohash 做精确去重并阻止相同 Metadata 被重复下载
第二层根据规范化文件路径和文件大小计算 content key 将不同 infohash 的相同内容聚合展示
模糊名称相似度只用于搜索结果聚合不得直接删除数据
Bloom Filter 只能作为前置加速结构不得作为最终去重依据
再次发现已有 infohash 时只更新最后发现时间和发现次数
持久化和恢复
程序必须支持间歇运行和跨重启恢复
正常关闭时先停止接收新任务再排空或持久化队列最后提交搜索索引
异常退出后依靠 RocksDB WAL 恢复已提交数据
每条搜索文档必须具有待索引和已索引状态以便启动后补建索引
内存队列不得成为任何权威状态的唯一保存位置
数据目录必须通过配置指定且不得依赖当前工作目录
代码边界
crawler只负责协调 DHT 事件和 Metadata 下载domain只定义领域模型规范化规则和内容指纹storage只负责 RocksDB 数据布局原子写入查询和恢复search只负责 Tantivy schema 文档转换索引和查询api只负责 HTTP 协议参数校验和响应转换config只负责读取校验和暴露配置telemetry只负责日志指标和运行观测shutdown只负责关闭信号和优雅退出协调
模块之间通过明确的数据结构和 trait 通信不得跨层直接访问内部实现
资源约束
- Metadata 下载并发必须可配置
- 单个 Metadata 大小文件数量和路径长度必须有限制
- RocksDB 写入使用批处理并明确控制 block cache
- Tantivy 写入使用批量提交并明确控制 IndexWriter 内存预算
- 日志不得输出完整 Metadata 或大文件列表
- 长期运行的集合必须有容量上限过期规则或磁盘持久化方案
开发规则
新业务代码写入 dht-search
项目阶段任务完成状态和验收标准统一维护在根目录 TODOS.md
需求实现或技术决策发生变化时必须同步更新 TODOS.md
dht-crawler 只接受可复用的 DHT 基础能力不得包含数据库搜索接口或部署逻辑
每个 Rust 文件顶部必须使用中文行注释描述该文件的功能边界且注释行尾不添加标点
新增行为必须包含与风险相称的测试
修改持久化 key 或编码格式时必须提供兼容或迁移方案
不得把 opencodes 下的参考项目纳入 workspace 或修改其内容
构建准备
应用骨架默认不启用 RocksDB 原生构建
实现存储层时通过 rocksdb-storage feature 启用 RocksDB
Windows 构建 RocksDB 前需要安装 LLVM 并确保 LIBCLANG_PATH 指向包含 libclang.dll 的目录
启用后的检查命令为 cargo check -p dht-search --features rocksdb-storage