13 KiB
DHT 元数据搜索服务计划
本文档记录项目当前规划实施顺序和完成状态
它是随需求实现结果性能数据和部署条件持续调整的活文档
维护规则
- 已经通过验收的任务使用
[x]标记 - 正在规划但尚未完成的任务使用
[ ]标记 - 需求变化时允许新增删除拆分合并或调整阶段顺序
- 调整计划时同步修改任务说明依赖关系和验收标准
- 不因代码已经存在就标记完成必须满足对应验收标准
- 发现原方案不合适时记录新决策并更新后续阶段
- 每次完成一个可交付功能时同步更新本文档
当前技术方向
dht-crawler负责可复用的 DHT 协议节点发现 Peer 查找和 Metadata 下载dht-search负责持久化去重索引搜索接口配置和运行生命周期- RocksDB 保存权威数据去重信息和任务状态
- Tantivy 保存可以从 RocksDB 重建的搜索索引
- Axum 提供搜索详情统计和健康检查接口
- 所有长期任务通过有界队列和背压控制资源占用
如果实际运行证明 RocksDB 的构建部署或资源成本不合适可以重新评估 redb SQLite 或其他存储方案
阶段零 项目基础
目标
建立清晰的 workspace 边界开发规则和可持续验证的基础库
任务
- 将 workspace 扁平化为
dht-crawler和dht-search - 使用当前 Git 配置统一作者仓库许可证和 edition 元数据
- 编写
AGENTS.md记录架构边界和开发约定 - 将最终应用与可复用 DHT 基础库分离
- 删除被内容组索引替代的旧状态和无效兼容代码
- 收紧仅供测试或存储内部使用的接口和依赖
- 实现 BEP-51
sample_infohashes主动发现 - 实现主动 Peer 查找和 Metadata 获取
- 验证远程公网设备能够持续获取 Metadata
- 确认 Xray 全局代理会影响 Metadata TCP 连接并完成旁路验证
- 保持基础库测试通过
验收标准
cargo check --workspace --all-targets通过dht-crawler单元测试通过opencodes参考项目不参与 workspace 构建
阶段一 本地持久化基础
目标
建立跨重启保留的权威数据源并完成精确去重和内容聚合基础
任务
- 定义二十字节
InfoHash类型和十六进制转换 - 定义
TorrentRecordTorrentFile和内容组索引状态 - 校验名称文件列表文件总大小和 infohash
- 使用 BLAKE3 计算规范化内容指纹
- 规范化 Unicode 路径分隔符大小写和文件顺序
- 保留真实子目录避免内容指纹碰撞
- 定义 RocksDB 二进制键空间
- 实现数据库格式检查
- 实现 infohash 精确查询和存在性判断
- 实现新记录 WriteBatch 原子写入
- 实现重复 infohash 的
last_seenseen_count和 Peer 更新 - 实现相同内容不同 infohash 的聚合映射
- 实现待索引记录查询和索引完成标记
- 配置 Bloom Filter LZ4 压缩和有限 block cache
- 准备 Windows 本地 RocksDB 构建所需的 libclang
- 将本地构建工具目录排除出 Git
验收标准
- 数据库关闭并重新打开后记录仍可读取
- 重复写入不会创建第二条 torrent 记录
- 重复写入会正确增加发现次数
- 相同内容的不同 infohash 可以独立保存并聚合查询
- Metadata 主体内容映射和待索引标记原子写入
- RocksDB 功能测试通过
dht-searchClippy-D warnings通过
阶段二 采集持久化闭环
目标
让 DHT 获取的真实 Metadata 自动进入有界持久化管线并支持安全停止和重新启动
任务
- 定义应用配置结构和默认配置文件
- 支持通过配置指定固定数据目录
- 支持配置 DHT 端口并发队列容量和 Metadata 限制
- 初始化 RocksDB repository 并处理启动错误
- 将
TorrentInfocallback 转换为TorrentRecord - 建立有界持久化队列并实现背压
- 使用专用阻塞任务执行 RocksDB 操作避免阻塞 Tokio worker
- 在 Metadata 下载前查询持久化 infohash 状态减少重复下载
- 在 BEP-51 Peer Lookup 前批量查询 RocksDB 并更新已有 infohash 发现状态
- 将已存在记录更新为再次发现而不是重复创建
- 增加接收写入重复拒绝失败和队列深度指标
- 实现
Ctrl+CSIGINT和SIGTERM优雅退出 - 退出时停止接收新任务并排空或持久化剩余任务
- 支持重新启动后继续使用原数据库
- 将 example 运行方式替换为正式
dht-search二进制 - 支持通过运行时长参数进行间歇运行
验收标准
- 本地运行可以持续向 RocksDB 写入真实 Metadata
- 停止并重启后旧 infohash 不会作为新记录重复写入
- 队列达到容量时内存不继续无界增长
- 正常退出后已接受的任务不会静默丢失
- 远程设备运行一小时没有持续内存增长
- 记录采集速度重复率数据库增长和写入延迟
阶段三 Tantivy 搜索索引
目标
让持久化 Metadata 支持快速全文搜索过滤排序和索引恢复
任务
- 定义 Tantivy schema 和索引版本
- 索引名称文件路径扩展名 infohash 和内容指纹
- 将大小文件数时间和发现次数定义为 fast fields
- 设计中英文数字和文件名子串 tokenizer
- 实现待索引任务批量消费
- 实现按数量和时间间隔批量 commit
- commit 成功后原子更新 RocksDB 索引状态
- 实现关键词短语和精确 infohash 查询
- 实现大小时间扩展名文件数热度和可用性过滤
- 实现大小范围和扩展名过滤
- 实现相关性时间热度大小和发现次数排序
- 建立带时间衰减的 DHT 活跃度分数和用户可读等级
- 实现分页并限制最大翻页成本
- 实现相同
content_key结果精确折叠和变体分页 - 实现从 RocksDB 全量重建 Tantivy 索引
- 支持索引结构不兼容时直接重建
验收标准
- 新写入记录在目标延迟内可搜索
- 搜索索引删除后可以从 RocksDB 完整重建
- 索引过程中异常退出不会永久丢失文档
- 百万级测试数据常用查询延迟达到约定目标
阶段四 HTTP 搜索服务
目标
提供稳定可验证并且资源受限的搜索和详情接口
任务
- 使用 Axum 建立 HTTP 服务
- 实现
/health和/ready接口 - 实现
/stats运行状态接口 - 实现
/search搜索过滤和分页接口 - 实现
/torrents/{infohash}详情接口 - 实现
/contents/{content_key}内容变体接口 - 使用 Bun Vue TypeScript Vite Tailwind CSS 和 shadcn-vue 建立 Web 基础环境
- 实现简单现代并适配移动端的单页搜索界面
- 接入搜索过滤排序分页详情内容变体和磁力链接复制
- 接入采集索引持久化和验证运行状态展示
- 实现运行状态定时刷新和浏览器持久化明暗主题
- 为加载空结果接口错误和失败重试提供明确界面状态
- 将生产静态资源交给 Axum 提供并支持单页回退
- 提供 Windows 一键启动后端和 Web 开发服务的脚本
- 定义统一错误响应
- 限制查询长度分页大小和最大 offset
- 增加请求延迟错误率和并发指标
- 增加搜索详情字段和按需验证入队 API 端到端测试
- 增加搜索过滤折叠精确哈希和变体接口测试
验收标准
- API 能搜索真实采集数据
- 非法参数返回稳定的客户端错误
- 搜索查询在独立阻塞任务执行不会阻塞异步 worker
- 健康检查能区分进程存活和服务可用
阶段五 质量过滤和重复内容控制
目标
减少垃圾数据和重复展示同时避免不可恢复的误删
任务
-
将种子可用性定义为最近通过 DHT 找到并完成 BitTorrent 握手
-
区分 Metadata 结构有效和 swarm 当前可用性
-
实现未验证活跃和可能失效三态模型
-
实现详情高优先级和搜索普通优先级的仅按需验证
-
使用持久化有界验证队列租约恢复去重和失败退避
-
Metadata 与验证握手共享 TCP 建连总预算
-
开发阶段清理测试数据库并以当前数据结构重新采集
-
搜索和详情接口返回热度与可用性数据
-
/stats返回验证队列发现握手成功失败和拒绝指标 -
统计真实数据的 infohash 重复率和内容重复率
-
定义可配置的名称路径扩展名和大小过滤规则
-
定义 Metadata 最大大小文件数和路径长度限制
-
识别空名称异常路径大小溢出和文件数量攻击
-
设计可解释的名称标准化规则
-
为模糊相似结果生成聚合候选但不自动删除
-
支持黑名单规则版本和命中原因
-
保留被过滤记录的计数指标但避免保存大内容
-
增加误判测试和边界数据集
验收标准
-
搜索和详情响应不等待 DHT 或 Peer 网络验证
-
进程重启后已接受的验证任务能够通过租约恢复
-
一次验证失败不会删除记录或标记为绝对失效
-
数据清空后能够建立新的内容组搜索文档
-
精确重复不会重复下载和重复展示
-
内容重复可以折叠并保留全部 infohash
-
过滤规则可以配置更新和回滚
-
模糊去重不会直接造成数据丢失
阶段六 性能资源和长期运行
目标
以真实数据验证持续运行时的吞吐延迟磁盘放大和资源上限
任务
- 增加
find_nodePeer Lookup 新目标和 Metadata 建连的显式配置 - 为主动
find_nodeget_peers和sample_infohashes增加共享 UDP 查询总预算 - 为 Metadata TCP 建连增加独立每秒速率限制
- 将桌面默认配置调整为保守网络预算
- 根据本机首次验证将主动 UDP 从
40/s下调至10/s并将 Metadata 建连从5/s下调至2/s - 验证极保守配置运行三分钟不影响同机代理网络并安全退出
- 将 BEP-51 采样准入压力反向传递到采样查询调度
- 实现样本来源节点单点
get_peers优先和失败后有限递归降级 - 完成首轮三分钟对比并验证 Peer Lookup UDP 从
278降至254且网络稳定 - 通过多轮或更长时间运行评估随机 DHT 样本下的 Metadata 成功率
- 统计按需验证的 Peer 发现率握手成功率和平均验证耗时
- 完成首轮真实按需验证并确认旧记录两次握手均成功更新为活跃
- 验证新 Metadata 记录直接继承成功来源 Peer 的活跃状态
- 验证启用按需可用性功能后保守预算运行三分钟并安全停止
- 根据真实验证数据校准热度权重等级边界和失败退避时间
- 根据公网设备长期实测设计超时率自动降速
- 建立采集存储索引和查询基准测试
- 记录每条元数据和每个索引文档的平均磁盘占用
- 记录 RocksDB block cache memtable 和 compaction 指标
- 记录 Tantivy IndexWriter 内存和 commit 延迟
- 根据实测调整批量大小队列容量和并发
- 增加磁盘剩余空间保护和只读降级策略
- 增加数据库备份检查点和恢复验证
- 增加日志轮转和保留策略
- 验证间歇运行和正常退出恢复
- 验证二十四小时和七天连续运行
- 根据规模决定是否继续使用 RocksDB
验收标准
- 内存使用在目标上限内稳定
- 队列和缓存不会随运行时间无限增长
- 磁盘不足时能够安全停止写入
- 备份可以在独立目录恢复并搜索
- 连续运行期间没有数据格式损坏和不可恢复任务
阶段七 部署和运维
目标
让应用可以在公网 Linux 设备上重复构建部署监控停止和恢复
任务
- 固化 Linux 目标构建方式和 RocksDB 构建依赖
- 生成 release 二进制并使用 SHA-256 校验部署
- 定义配置数据日志和索引目录布局
- 编写 systemd service
- 编写 systemd timer 支持间歇运行
- 使用专用低权限 UID 运行验证
- 固化 Xray 环境下的最小范围网络旁路
- 验证高并发运行需要
LimitNOFILE=65536 - 实现启动前数据目录权限检查
- 实现优雅升级和回滚流程
- 编写备份恢复和故障排查文档
验收标准
- 新设备可以按文档完成部署
- 服务重启不会丢失已提交数据
- Xray 旁路只影响爬虫进程
- 更新失败时可以恢复上一版本二进制和数据
当前下一步
使用真实采集数据进行 Web 浏览器人工验收并根据使用反馈调整交互细节
随后进行百万级查询基准和更长时间的资源稳定性测试