系統架構#

推薦系統不只是演算法,更是一個完整的工程系統。本章介紹推薦系統的架構設計。

三層架構#

Netflix 架構#

Netflix 的推薦系統架構是業界標杆,分為三層:

flowchart TB
    subgraph 在線層["🟢 在線層 Online"]
        direction LR
        O1[實時響應請求]
        O2[使用實時資料]
        O3[毫秒級延遲]
    end

    subgraph 近線層["🟡 近線層 Nearline"]
        direction LR
        N1[使用實時資料]
        N2[非同步處理]
        N3[特徵更新]
    end

    subgraph 離線層["🔵 離線層 Offline"]
        direction LR
        F1[批量處理]
        F2[全量資料]
        F3[模型訓練]
    end

    離線層 --> 近線層 --> 在線層

    style 在線層 fill:#e8f5e9
    style 近線層 fill:#fff3e0
    style 離線層 fill:#e3f2fd

各層特點#

階層資料服務典型任務
在線實時實時排序、過濾、業務規則
近線實時非同步特徵更新、模型增量更新
離線全量批量模型訓練、全量計算

在線層設計#

核心要求#

在線層必須保證:

  1. 低延遲(< 100ms)
  2. 高可用(99.99%)
  3. 可降級

服務流程#

flowchart LR
    A[用戶請求] --> B[召回服務]
    B --> C[排序服務]
    C --> D[重排服務]
    D --> E[返回結果]

    B -.-> B1[多路召回]
    C -.-> C1[CTR 預估]
    D -.-> D1[業務規則]

    style A fill:#e3f2fd
    style E fill:#e8f5e9

降級策略#

當上游服務異常時,需要有 Plan B:

異常情況降級策略
個性化召回失敗返回熱門排行榜
排序模型超時使用簡單規則排序
特徵服務異常使用預設特徵值

API 設計#

推薦 API 示例
GET /recommend
參數:
  - user_id: 用戶 ID(必需)
  - page_id: 頁面 ID
  - position_id: 推薦位 ID
  - size: 請求數量
  - offset: 偏移量(翻頁)

返回:
{
  "recommend_id": "xxx",  // 曝光 ID,用於追蹤
  "items": [
    {
      "id": "item_123",
      "title": "...",
      "score": 0.95
    }
  ],
  "size": 10
}

離線層設計#

典型任務#

資料清洗 → 特徵工程 → 模型訓練 → 離線評估 → 推送上線

資料管理#

組件作用工具
資料湖存儲原始日誌HDFS、S3
資料倉庫結構化存儲Hive、Spark SQL
特徵平台特徵計算和存儲自研或開源

模型訓練#

# 典型的離線訓練流程
def train_model():
    # 1. 讀取訓練資料
    df = spark.read.parquet("hdfs://data/training")

    # 2. 特徵工程
    features = feature_engineering(df)

    # 3. 模型訓練
    model = train(features)

    # 4. 離線評估
    metrics = evaluate(model, test_data)

    # 5. 模型推送
    if metrics['auc'] > threshold:
        push_to_online(model)

近線層設計#

流計算架構#

用戶行為 → Kafka → Flink/Storm → 特徵更新 → Redis/Cassandra
                               → 模型更新 →
                               → 推薦結果更新 →

Storm 程式設計模型#

概念說明類比
Spout資料源水龍頭
Bolt資料處理器水管連接處
Tuple資料單元
Topology資料流圖水管系統

實時更新示例#

以 Item-CF 為例,用戶產生新行為時:

  1. 取出用戶歷史行為物品列表
  2. 新物品與歷史物品構成「物品對」
  3. 更新這些物品對的共現次數
  4. 重新計算相似度

資訊流架構#

Feed 系統特點#

特點說明
海量內容每天新增百萬級內容
實時性要求高新聞時效性
多路召回興趣標籤、協同過濾、熱門等
混合排序多目標優化(時長、點擊、多樣性)

典型架構#

flowchart LR
    subgraph 內容處理
        A1[內容入庫] --> A2[內容分析] --> A3[建立索引]
    end

    subgraph 多路召回
        B1[標籤召回]
        B2[CF 召回]
        B3[熱門召回]
    end

    subgraph 排序展示
        C1[融合] --> C2[排序] --> C3[重排] --> C4[展示]
    end

    A3 --> B1
    A3 --> B2
    A3 --> B3
    U[用戶請求] --> B1
    U --> B2
    U --> B3
    B1 --> C1
    B2 --> C1
    B3 --> C1

    style U fill:#e3f2fd
    style C4 fill:#e8f5e9

搜尋、推薦、廣告的關係#

對比#

維度搜尋推薦廣告
用戶意圖明確模糊被動接收
目標相關性滿足興趣商業變現
資訊取得主動被動被動
個性化程度較低

統一架構的可能性#

三者都可以抽象為:過濾候選 → 排序候選 → 個性化輸出

                 ┌─────────────────────────────────────┐
                 │          統一架構                    │
                 │                                     │
Query/User ─────→│  召回層 ──→ 排序層 ──→ 重排層  │──→ 結果
                 │                                     │
                 └─────────────────────────────────────┘

一些公司已經在嘗試統一搜尋和推薦的架構,共享底層技術堆疊。

存儲選型#

不同資料的存儲方案#

資料類型特點推薦存儲
用戶/物品特徵批量讀寫Cassandra、HBase
模型參數鍵值對Redis
推薦結果列表形式Redis sorted set
隱向量稠密向量檔案 + MMAP
倒排索引高效檢索ElasticSearch

列式資料庫#

Cassandra vs HBase:

  • Cassandra:去中心化,可調一致性,讀寫性能更好
  • HBase:強一致性,與 Hadoop 生態集成好

模型存儲#

方式適用場景
PMML小規模模型,跨語言部署
Pickle/JoblibPython 生態內部使用
SavedModelTensorFlow 模型
ONNX跨框架通用格式

實踐建議#

從簡單開始#

不要一開始就追求完美架構:

  • 中小公司:先用單機,充分發揮單機性能
  • 先跑通流程,再優化性能
  • 根據實際瓶頸逐步升級

架構演進路線#

timeline
    title 推薦系統架構演進

    階段 1 單機版本
        : 協同過濾 + 熱門
        : MySQL/Redis
        : 定時批量更新

    階段 2 分離離線在線
        : 離線:Spark 計算
        : 在線:微服務架構

    階段 3 加入近線層
        : Kafka + Flink
        : 實時特徵更新

    階段 4 完整架構
        : 多路召回
        : 深度學習排序
        : 完善監控體系

總結#

要點說明
三層架構在線/近線/離線,各有分工
在線層低延遲、高可用、可降級
離線層批量計算、模型訓練
近線層流計算、實時更新
存儲選型根據資料特點選擇合適的存儲
演進路線從簡單開始,按需升級