feat: 抓取任务队列 + 媒体机直传 + 向量回填

crawl(品牌抓取任务队列)
- /admin/internal/crawl/tasks 领取 / :id/result 回报,spider 可常驻拉任务
- 后台品牌列表支持「加入抓取队列」,队列页可看状态与重试
- 租约超时的 running 自动回收为 queued,避免 worker 崩溃后任务卡死

media(媒体机直传)
- ingest 载荷新增 main_key/detail_keys/main_size/detail_sizes:
  有 key 就直接落库,跳过下载与上传;与 URL 形态可逐图混用
- 细节图按 Details/DetailKeys 两者较长者遍历(只给 key 时不再丢图)
- 媒体机上传的 key 不进失败回滚清单(内容寻址、可能与他人共享)
- /admin/internal/upload-url 签发 S4 PUT 预签名(spider 不持有 AK/SK)

embeddings(向量回填)
- GET /admin/internal/embeddings/pending 派发缺向量的图(含可直接下载的 url)
- POST /admin/internal/embeddings 回写向量并重算近邻;失败项计入
  image_embedding_failures,连续失败到上限后退出队列(坏图不占位)
- 近邻重算改为异步串行:同步会让 100 张的批次 POST 超时(实测 >60s)
- 新增 key 分支单测:混用 key/url、细节图只给 key、字节数、回滚清单、向量占位
This commit is contained in:
toom1996
2026-10-25 00:37:13 +08:00
parent e18c5a0815
commit 151e09ab30
22 changed files with 1535 additions and 28 deletions

View File

@ -0,0 +1,23 @@
-- 品牌抓取任务表:后台表达「要爬哪些品牌」,spider 服务来领取执行。
-- 与 ingest_jobs 分层:crawl_tasks 对外(跨机器),ingest_jobs 对内(后端 worker)。
CREATE TABLE IF NOT EXISTS crawl_tasks (
id bigserial PRIMARY KEY,
brand_id bigint NOT NULL,
status varchar(16) NOT NULL DEFAULT 'queued',
priority smallint NOT NULL DEFAULT 0,
max_shows smallint NOT NULL DEFAULT 0,
worker varchar(64) NOT NULL DEFAULT '',
locked_at bigint NOT NULL DEFAULT 0,
attempts smallint NOT NULL DEFAULT 0,
shows_submitted integer NOT NULL DEFAULT 0,
last_error text NOT NULL DEFAULT '',
created_at bigint NOT NULL DEFAULT 0,
updated_at bigint NOT NULL DEFAULT 0
);
-- 一个品牌同时只允许一条任务:后台反复点「加入队列」不会产生重复任务,
-- 而是把已完成/失败的记录重置为 queued。
CREATE UNIQUE INDEX IF NOT EXISTS uq_crawl_tasks_brand ON crawl_tasks (brand_id);
-- 领取用索引:按优先级 + 入队顺序。
CREATE INDEX IF NOT EXISTS idx_crawl_tasks_pick ON crawl_tasks (status, priority DESC, id);