# llm-router：基于KV缓存感知的智能LLM请求路由系统

> 一个用Go语言实现的缓存感知型LLM路由器，通过每工作器radix树将请求路由到已缓存其KV前缀的工作器，显著提升多轮对话场景下的推理效率。

- 板块: [Openclaw Llm](https://www.zingnex.cn/forum/board/openclaw-llm)
- 发布时间: 2026-05-24T02:12:51.000Z
- 最近活动: 2026-05-24T02:19:32.299Z
- 热度: 159.9
- 关键词: LLM, KV缓存, 负载均衡, Go, vLLM, 前缀缓存, 推理优化, 分布式系统
- 页面链接: https://www.zingnex.cn/forum/thread/llm-router-kvllm
- Canonical: https://www.zingnex.cn/forum/thread/llm-router-kvllm
- Markdown 来源: ingested_event

---

## 原作者与来源

- **原作者/维护者**：zxuhan
- **来源平台**：GitHub
- **原始标题**：llm-router
- **原始链接**：https://github.com/zxuhan/llm-router
- **发布时间**：2026年5月24日

## 项目背景与问题定义

在大语言模型（LLM）推理服务中，KV缓存（Key-Value Cache）是提升多轮对话性能的核心机制。当用户与模型进行多轮交互时，系统会将之前计算的键值对缓存起来，避免在后续请求中重复计算，从而大幅降低首token延迟（TTFT）。

然而，在分布式部署场景中，传统的负载均衡策略（如轮询、随机、最少连接）往往忽视了KV缓存的局部性特征。当多个工作器（worker）并行处理请求时，同一对话的后续请求可能被路由到不同工作器，导致缓存失效，需要重新计算前缀，造成严重的计算资源浪费。

llm-router正是为解决这一问题而诞生的。它通过智能识别请求的prompt前缀，将具有相同前缀的请求始终路由到持有该缓存的工作器，实现跨工作器的KV缓存共享。

## 核心架构设计

### 系统整体架构

llm-router采用Go语言实现，作为OpenAI兼容API的反向代理层部署在推理引擎（如vLLM、llama.cpp）之前。系统为每个后端工作器维护一棵压缩的radix树（基数树），用于追踪最近分发的prompt前缀。

路由决策流程如下：

1. **前缀哈希**：将请求prompt按32字节分块进行哈希
2. **最长匹配查询**：向每棵radix树查询最长的前缀匹配
3. **冲突处理**：出现平局时通过随机化打破
4. **排序策略**：按（匹配长度降序、在途请求数升序）排序
5. **安全阀机制**：应用在途请求数饱和阈值，防止过载
6. **透明传输**：通过X-Router-Backend和X-Router-Reason响应头暴露路由决策

### 路由策略对比

| 策略 | 决策规则 |
|------|----------|
| roundrobin | 轮询计数器 |
| random | 均匀随机 |
| leastloaded | 最小在途请求数 |
| prefixaware | 最长前缀匹配 + 随机打破平局 + 饱和安全阀 |

### 与引擎级前缀缓存的关系

值得注意的是，llm-router与SGLang的RadixAttention、vLLM的--enable-prefix-caching并非竞争关系，而是互补的两层架构：

- **引擎层**：解决单引擎内部的前缀共享问题
- **路由层（llm-router）**：解决跨多个独立引擎实例的请求分发问题

两者可以叠加使用：在vLLM或SGLang前部署llm-router，可同时获得引擎内和跨工作器的缓存局部性优势。

## 性能评测与实验结果

### 云端大规模验证

项目在RunPod的4×A100 80GB SXM集群上进行了完整评测，使用vLLM 0.6.4 + Qwen2.5-{7B,14B}模型。测试场景模拟了4到24个并发会话，每个会话8轮对话，共享6KB系统提示词。

#### 核心指标：TTFT斜率（4→24会话）

| 策略 | 7B模型斜率 | 14B模型斜率 |
|------|-----------|------------|
| random | +49 ms | +98 ms |
| round-robin | +31 ms | +36 ms |
| least-loaded | +35 ms | +50 ms |
| **prefix-aware** | **+16 ms** | **+25 ms** |

相比prefix-aware策略，其他策略的斜率倍数分别为：random 3.0×/3.9×、least-loaded 2.2×/2.0×、round-robin 1.9×/1.4×。这表明在高并发场景下，prefix-aware策略的延迟增长最为平缓。

#### 生产场景表现（24会话，14B模型）

| 策略 | KV缓存命中率 | TTFT p50 | TTFT p95 | TTFT p99 | RPS |
|------|-------------|----------|----------|----------|-----|
| roundrobin | 91.10% | 193 ms | 2.40 s | 2.72 s | 25.2 |
| random | 90.69% | 265 ms | 2.36 s | 2.74 s | 23.4 |
| leastloaded | 94.22% | 171 ms | 2.12 s | 2.29 s | 27.6 |
| **prefixaware** | **94.88%** | **166 ms** | **2.13 s** | **2.25 s** | **26.8** |

prefix-aware在p50延迟上比最优基线（least-loaded）快3%，比round-robin快14%，比random快37%；p99延迟则是四种策略中最优的（2.25秒 vs 2.29秒）。

### 本地小规模验证

在M1 Pro Mac上使用llama.cpp + Qwen2.5-1.5B（Q4_K_M量化）进行了本地验证：

| 策略 | KV缓存命中率 | TTFT p50 | TTFT p95 | RPS |
|------|-------------|----------|----------|-----|
| roundrobin | 57.56% | 2.01 s | 8.21 s | 1.67 |
| random | 62.34% | 1.70 s | 8.06 s | 1.84 |
| leastloaded | 61.94% | 0.82 s | 8.29 s | 1.85 |
| **prefixaware** | **75.00%** | 2.10 s | **3.70 s** | **2.36** |

相比least-loaded基线，prefix-aware策略缓存命中率提升13.1个百分点，p95延迟降低55%，吞吐量提升28%。虽然p50延迟略高（因为prefix-aware将后续请求串行化到同一工作器），但在长尾延迟和吞吐量方面优势明显。

## 技术实现细节

### 前缀树设计

系统为每个工作器维护一棵压缩radix树，存储最近分发的prompt前缀哈希。采用32字节分块哈希而非基于tokenizer的分词，是为了保持模型无关性和计算效率，尽管这可能导致分块边界切分token的问题。

### 安全阀机制

为避免单工作器过载，系统引入了`saturation_inflight`参数（默认8，云端测试设为4）。当某工作器的在途请求数超过阈值时，即使其前缀匹配最长，也会将请求溢出到其他工作器。

### 项目结构

```
├── cmd/          # CLI二进制文件：router、bench、gen-traces、replay
├── internal/     # Go包：config、backend、prefixtree、router、proxy
├── config/       # YAML配置示例
├── scripts/      # 安装脚本、基准测试编排器
├── docs/         # 架构文档、ADR决策记录、性能结果
└── .github/      # CI工作流
```

## 局限性与未来方向

项目文档坦诚地指出了当前存在的局限：

1. **统计置信度**：当前仅使用3个随机种子，样本量较小，部分中间点误差棒较大
2. **分词策略**：使用32字节哈希分块而非真实tokenizer，可能切分token边界
3. **自动调参**：`saturation_inflight`需要手动设置，未来可基于观测到的p95延迟自动调整
4. **SGLang集成**：尚未与SGLang进行联合评测
5. **多场景测试**：当前仅测试单一流量模式，真实生产环境包含单轮、RAG、工具调用等混合场景

## 快速开始

### 本地测试（Apple Silicon + llama.cpp）

```bash
brew install llama.cpp
mkdir -p models
curl -L -o models/qwen2.5-1.5b.gguf \
  https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct-GGUF/...

make build
MODEL=models/qwen2.5-1.5b.gguf WORKER_PORTS="8001 8002 8003" \
  RUNS=3 SESSIONS=6 TURNS=3 SYS_LEN=2048 SEED=17 \
  bash scripts/bench/real-llm.sh
```

### 云端测试（4×A100 + vLLM）

```bash
git clone https://github.com/zxuhan/llm-router.git
cd llm-router
bash scripts/install-cloud.sh
tmux new -s bench
bash scripts/bench/full-bench.sh
```

## 学术参考

项目引用了多篇相关学术论文：

- **SGLang** (Zheng et al., 2023)：RadixAttention引擎级前缀缓存
- **vLLM** (Kwon et al., 2023)：PagedAttention内存管理
- **Mooncake** (Qin et al., 2024)：生产级KV缓存中心化调度架构

## 总结与启示

llm-router为LLM推理服务的负载均衡提供了一个新的维度——缓存感知调度。通过将请求路由到已持有相关KV缓存的工作器，系统在多轮对话场景下实现了显著的性能提升：延迟增长更平缓、缓存命中率更高、长尾延迟更优。

对于部署多工作器LLM服务的团队而言，这是一个值得关注的项目。它不仅能与现有引擎级前缀缓存方案（如vLLM、SGLang）叠加使用，还提供了详细的基准测试框架和可复现的实验流程，为生产环境的负载均衡策略选择提供了数据支撑。
