作者: MoonCake TV 技术团队 (就我自己)
性能提升: 🚀 17 倍加速 (11.5 小时 → 40 分钟)
简单点,说人话,就是我以前的数据处理流程,没有规划,有什么用什么;核心还是太烂了;现在经过和 ai 的多轮对话,终于有了改进
在优化之前,我们的数据处理流程存在以下严重问题:
旧架构数据流:
Source APIs (数据源)
    ↓
Temporal Workers (数据抓取)
    ↓ HTTP POST /cf-workers/upsert-batch
Cloudflare Workers (中间层) ← 瓶颈 1: 网络延迟
    ↓ 写入 D1 数据库
Cloudflare D1 (SQLite) ← 瓶颈 2: D1 性能限制
    ↓ GET /cf-workers/search-todos-*
meilisearch-sync Worker ← 瓶颈 3: 额外的同步层
    ↓ POST to meili-search-service
meili-search-service Meilisearch
    ↓
Cloudflare Workers
    ↓
用户查询
关键瓶颈:
m3u8_urls 字段需要多次 stringify/parse我们采用了单向数据流的设计理念,彻底简化了数据处理架构:
新架构数据流:
Source APIs (数据源)
    ↓
Temporal Workers (数据抓取 + 解析)
    ↓ HTTP POST /v1/upsert-batch (JWT 认证)
meili-search-service PostgreSQL ---> Meilisearch Server (同一个服务器内部)
    ↓
Cloudflare Workers
    ↓
用户查询 (通过 m3u8-s1 代理)
之前:
现在:
收益:
之前:
is_indexed 标志位现在:
收益:
之前 (Cloudflare D1):
// m3u8_urls 存储为 TEXT
m3u8_urls: JSON.stringify(item.m3u8_urls); // 需要序列化
现在 (PostgreSQL):
// m3u8_urls 存储为 JSONB
m3u8_urls: item.m3u8_urls; // 直接传递对象,无需序列化
收益:
新的 PostgreSQL Upsert 逻辑:
INSERT INTO table_name (
  id, field1, field2, field3, ...
) VALUES ($1, $2, $3, $4, ...)
ON CONFLICT (unique_key1, unique_key2)
DO UPDATE SET
  m3u8_urls = EXCLUDED.m3u8_urls,
  updated_at = EXCLUDED.updated_at
关键优化点:
ON CONFLICT 实现 upsert (插入或更新)| 指标 | 旧架构 | 新架构 | 提升比例 | 
|---|---|---|---|
| 总处理时间 | 11.5 小时 | 40 分钟 | 17.25x | 
| 网络往返次数 | 4+ 次 | 1 次 | 4x 减少 | 
| 服务层级 | 4 层 | 2 层 | 2x 简化 | 
| 数据库数量 | 3 个 | 1 个 | 3x 精简 | 
| 维度 | 旧架构 | 新架构 | 
|---|---|---|
| 数据源 | Cloudflare D1 + PostgreSQL | PostgreSQL 单一数据源 | 
| 中间服务 | Cloudflare Workers + meilisearch-sync | 无 | 
| 数据流向 | 循环依赖 | 单向流动 | 
| 维护成本 | 高(多个服务) | 低(精简架构) | 
** 表结构:**
CREATE TABLE IF NOT EXISTS dazahui (
  id SERIAL PRIMARY KEY,
  mc_id VARCHAR(50) UNIQUE NOT NULL,
  title TEXT NOT NULL,
  m3u8_urls JSONB,  -- 关键:使用 JSONB 类型
  .......
  CONSTRAINT unique_xxx UNIQUE(xxx, xxxx)
);
旧代码 (写入 Cloudflare Workers):
await fetch("https://cf-workers/upsert-batch", {
  method: "POST",
  body: JSON.stringify({
    items: items.map((item) => ({
      ...item,
      m3u8_urls: JSON.stringify(item.m3u8_urls), // 需要序列化
    })),
  }),
});
新代码 (直接写入 meili-search-service):
await fetch(`/v1/upsert-batch`, {
  method: "POST",
  body: JSON.stringify({
    items, // m3u8_urls 保持对象格式,无需序列化
  }),
});
关键改进:
数据写入 API (JWT 保护):
POST /v1/upsert-batch
Authorization: Bearer <MEILI_INTERNAL_JWT_SECRET>
Request:
{
  "items": [
    {
      "title": "电影标题",
      "m3u8_urls": {"第 1 集": "url1", "第 2 集": "url2"},
      "language": "zh",
      ...
    }
  ]
}
Response:
{
  "code": 200,
  "message": "Batch upsert completed",
  "data": {
    "processed": 150,
    "failed": 0
  }
}
ON CONFLICT 实现 upsert 批量操作虽然数据写入性能已大幅提升,但仍有进一步优化空间:
添加查询 API 到 meili-search-service
GET /v1/search-sql?keyword=xxx (SQL LIKE 搜索)GET /v1/random?limit=20 (随机内容)GET /v1/mc_item/:mc_id (获取单个内容)更新 m3u8-s1 为纯代理层
/boss/* 路由/v1/* 端点改为代理到 meili-search-serviceMeilisearch 自动索引
核心技术:
优化技术:
通过彻底重新设计数据处理架构,我们实现了:
这次优化充分证明了: 正确的架构设计比单纯的代码优化更能带来质的飞跃。