当你把大模型集成进产品时,会很快撞上提供商的速率限制。单个 OpenAI 密钥给你 1M TPM 和 10K RPM。如果你有几个重度用户在处理大文档,这点配额几秒钟就没了。
解决办法是池化。你为同一个模型准备多个 API 密钥,在它们之间负载均衡流量。五个密钥就给你 5M TPM。你也可以混合后端:把 OpenAI 和 Azure OpenAI 放在同一个 gpt-5.2 别名下,这样对 gpt-5.2 的请求会打到有容量的那个后端。这是人们选择 LiteLLM 这种网关的主要原因。
但池化带来了共享状态的问题。如果你在负载均衡器后面运行多个网关节点,每个节点都需要知道每个密钥还剩多少配额。如果节点 A 把一个密钥用完了,节点 B 必须立刻知道。纯本地内存追踪在这里行不通。你会冲破提供商的限制,拿到 429 错误。
LiteLLM 用 Python 写成。这带来了该语言众所周知的开销,但它的架构是为分布式状态而设计的。通过把持久数据放在 Postgres 里,把热运行时计数器放在 Redis 里,LiteLLM 通过了其他系统失败的多节点测试。
实际配置密钥池化
在 LiteLLM 里配置密钥池化很直接。你定义一个 router 配置,把多个部署归到同一个模型名下,并给它们分配限额。
同一提供商,多个密钥:
model_list:
- model_name: gpt-5.2
litellm_params:
model: openai/gpt-5.2
api_key: sk-key-1
tpm: 1000000
rpm: 10000
- model_name: gpt-5.2
litellm_params:
model: openai/gpt-5.2
api_key: sk-key-2
tpm: 1000000
rpm: 10000
router_settings:
routing_strategy: usage-based-routing-v2
redis_host: os.environ/REDIS_HOST
redis_port: os.environ/REDIS_PORT
redis_password: os.environ/REDIS_PASSWORD
enable_pre_call_check: true不同后端,同一个模型 ID。当你为同一个模型有 OpenAI、Azure、OpenRouter 以及区域性 Azure 部署,又想把它们当作一个池来处理时,这很有用:
model_list:
- model_name: gpt-5.2
litellm_params:
model: openai/gpt-5.2
api_key: sk-openai-key
tpm: 1000000
rpm: 10000
- model_name: gpt-5.2
litellm_params:
model: azure/gpt-5.2
api_base: https://my-deployment.openai.azure.com
api_key: os.environ/AZURE_API_KEY
tpm: 1000000
rpm: 10000
- model_name: gpt-5.2
litellm_params:
model: openrouter/openai/gpt-5.2
api_key: os.environ/OPENROUTER_API_KEY
tpm: 1000000
rpm: 10000
- model_name: gpt-5.2
litellm_params:
model: azure/gpt-5.2
api_base: https://my-eu-deployment.openai.azure.com
api_key: os.environ/AZURE_EU_API_KEY
tpm: 1000000
rpm: 10000
router_settings:
routing_strategy: usage-based-routing-v2
redis_host: os.environ/REDIS_HOST
redis_port: os.environ/REDIS_PORT
redis_password: os.environ/REDIS_PASSWORD
enable_pre_call_check: true在这两种配置里,LiteLLM 充当一个智能负载均衡器。通过把路由器配置为 usage-based-routing-v2,并让 router_settings 访问 Redis,它用一个异步 Redis 实现来跟踪全局使用量(redis.mget 和 redis.incr)。它评估所有实例的剩余容量,把流量路由到当前这一分钟使用量最低的 API 密钥,过滤掉那些已经超过 TPM/RPM 限额的密钥。
为什么池化在多节点之间会失效
如果你把 5 个 OpenAI API 密钥池化在一个别名(比如 gpt-5.2)下,这些密钥就有一个组合的容量约束。如果节点 A 用完了一个密钥的配额,节点 B 必须立刻知道。
LiteLLM 通过直接连接 Redis 来创建集中的令牌桶和请求计数器来实现这一点。当一个请求进来:
- 节点 A 计算需要的 token 数,请求预留。
- Redis 原子地递增全局计数器。
- 如果节点 B 一毫秒之后处理一个请求,它在发送 payload 之前会从 Redis 读取更新后的计数器。
这解决了请求重叠的问题。虽然仍然有一点点竞态条件的余地(LiteLLM 把它承认作有界漂移),但这种 Redis 支撑的方法避免了纯本地内存追踪时发生的那种大规模预算超支。
LiteLLM 的架构哲学
LiteLLM 不试图成为一个把所有真相都放在本地内存里的智能、孤立的节点。相反,它充当一个"分布式执行器"。
它把状态管理卸载给专门为这个工作而构建的专用系统:
- Redis: 处理快速、临时状态(速率限制、冷却、实时开支计数器)。
- Postgres: 处理持久、关系型状态(虚拟密钥、预算、用户、团队和永久的开支日志)。
这种哲学意味着你可以在负载均衡器后面部署 10 个 LiteLLM 实例,它们会作为一个单一、全局协调的代理集群工作,开箱即用,在开源层级上。要启用这个功能,你的 config.yaml 把持久状态指向 Postgres,把路由器状态指向 Redis:
general_settings:
master_key: sk-master-123
database_url: "postgresql://user:pass@db:5432/litellm"
router_settings:
redis_host: "redis-cluster.internal"
redis_port: 6379
redis_password: "redis-password"
enable_pre_call_check: true安全地共享虚拟密钥
除了提供商密钥,LiteLLM 允许你为用户、团队或内部服务生成虚拟密钥。
与OSS Bifrost 中的多节点 Postgres 陷阱不同,多个 LiteLLM 节点可以安全地连接到完全相同的 Postgres 数据库。当一个带虚拟密钥的请求到达时,LiteLLM 在数据库里对该密钥进行认证,检查用户的预算,并把开支追踪作为共享的持久状态来更新。
因为真相存放在外部,你可以通过 API 程序化地创建一个虚拟密钥,你集群里的每一个 LiteLLM 节点都会立刻识别它。下面是一个为特定团队创建带硬性月度预算的动态范围密钥的例子:
curl -X POST 'http://litellm-cluster:4000/key/generate' \
-H 'Authorization: Bearer sk-master-123' \
-H 'Content-Type: application/json' \
-d '{
"key_name": "marketing-team-prod",
"models": ["gpt-5.2", "claude-3.5-sonnet"],
"max_budget": 500.0,
"budget_duration": "30d",
"rpm_limit": 100,
"metadata": {
"team": "marketing",
"environment": "production"
}
}'一旦生成,这个密钥立即在所有节点上有效。API 用 Postgres 的持久账本来执行 max_budget,用 Redis 的热计数器来执行 rpm_limit。
为什么这对你的架构很重要
选择 LiteLLM 不是因为它有虚拟密钥功能;很多网关都有。选择它是因为它的状态模型在开源多节点部署中原生支持虚拟密钥作为全局协调的预算主体。
当你的应用的财务可行性取决于永远不超过提供商的速率限制、永远不让用户超过分配的预算时,你需要一个尊重共享状态的系统。LiteLLM 提供的正是这个。
下一篇我们会把 LiteLLM 和 Bifrost 拉到一起对比,帮你决定哪种架构哲学最适合你的基础设施需求。
